[yast-commit] r57826 - in /branches/tmp/mvidner/core-dbus-values: dbus/SCR_service/ dbus/namespace_service/src/ dbus/namespace_service/testsuite/ libscr/src/ liby2dbus/src/

Author: mvidner Date: Wed Jul 1 16:37:56 2009 New Revision: 57826 URL: http://svn.opensuse.org/viewcvs/yast?rev=57826&view=rev Log: Enhanced DBus -> YCP value conversion by considering also the expected YCP type. Otherwise it is impossible to tell whether an empty array should become an empty map or an empty list (bnc#516492). Not finished yet: - many test cases are missing - errors are only logged but not sent over DBus Modified: branches/tmp/mvidner/core-dbus-values/dbus/SCR_service/DBusServer.cc branches/tmp/mvidner/core-dbus-values/dbus/namespace_service/src/DBusModulesServer.cc branches/tmp/mvidner/core-dbus-values/dbus/namespace_service/src/DBusModulesServer.h branches/tmp/mvidner/core-dbus-values/dbus/namespace_service/testsuite/t2 branches/tmp/mvidner/core-dbus-values/dbus/namespace_service/testsuite/test_all branches/tmp/mvidner/core-dbus-values/libscr/src/SCR.cc branches/tmp/mvidner/core-dbus-values/liby2dbus/src/DBusMsg.cc branches/tmp/mvidner/core-dbus-values/liby2dbus/src/DBusMsg.h branches/tmp/mvidner/core-dbus-values/liby2dbus/src/DBusServerBase.h Modified: branches/tmp/mvidner/core-dbus-values/dbus/SCR_service/DBusServer.cc URL: http://svn.opensuse.org/viewcvs/yast/branches/tmp/mvidner/core-dbus-values/d... ============================================================================== --- branches/tmp/mvidner/core-dbus-values/dbus/SCR_service/DBusServer.cc (original) +++ branches/tmp/mvidner/core-dbus-values/dbus/SCR_service/DBusServer.cc Wed Jul 1 16:37:56 2009 @@ -118,7 +118,7 @@ } else { - arg0 = request.getYCPValue(0); + arg0 = request.getYCPValue(0, Type::Path); if (arg0.isNull() || !arg0->isPath()) { @@ -141,8 +141,8 @@ if (check_ok) { - YCPValue arg = request.getYCPValue(1); - YCPValue opt = request.getYCPValue(2); + YCPValue arg = request.getYCPValue(1, Type::Unspec); + YCPValue opt = request.getYCPValue(2, Type::Unspec); std::string caller(request.sender()); @@ -205,9 +205,9 @@ ret.push_back(action_id); - YCPValue path = msg.getYCPValue(0); - YCPValue arg = msg.getYCPValue(1); - YCPValue opt = msg.getYCPValue(2); + YCPValue path = msg.getYCPValue(0, Type::Path); + YCPValue arg = msg.getYCPValue(1, Type::Unspec); + YCPValue opt = msg.getYCPValue(2, Type::Unspec); std::string path_str, arg_str, opt_str; Modified: branches/tmp/mvidner/core-dbus-values/dbus/namespace_service/src/DBusModulesServer.cc URL: http://svn.opensuse.org/viewcvs/yast/branches/tmp/mvidner/core-dbus-values/d... ============================================================================== --- branches/tmp/mvidner/core-dbus-values/dbus/namespace_service/src/DBusModulesServer.cc (original) +++ branches/tmp/mvidner/core-dbus-values/dbus/namespace_service/src/DBusModulesServer.cc Wed Jul 1 16:37:56 2009 @@ -433,7 +433,8 @@ while(index < reqarg) { - YCPValue arg = request.getYCPValue(index); + constTypePtr argtype(fptr->parameterType(index)); + YCPValue arg = request.getYCPValue(index, argtype); if (arg.isNull()) { @@ -443,8 +444,6 @@ } // check the data type compatibility - constTypePtr argtype(fptr->parameterType(index)); - if (argtype->matchvalue(arg) < 0) { if (interface == YAST_DBUS_RAW_INTERFACE) @@ -490,6 +489,7 @@ } else { + // FIXME should be a dbus error y2error("Wrong parameters to function %s::%s", object.c_str(), method.c_str()); } } @@ -504,13 +504,14 @@ if (!found) { +// see also DBusServerBase::unknownRequest y2internal("Function %s::%s was not found although it was registered", object.c_str(), method.c_str()); string msg = "Method '"+ interface + "." + method + "' " "on object '" + object + "' doesn't exist"; // anyway, why didnt dbus itself cry? reply.createError(request, // in reply to msg, - "org.freedesktop.DBus.Error.UnknownMethod"); + DBUS_ERROR_UNKNOWN_METHOD); return reply; } @@ -564,7 +565,7 @@ { if (request.arguments() == 1) { - YCPValue arg = request.getYCPValue(0); + YCPValue arg = request.getYCPValue(0, Type::String); if (arg.isNull()) { Modified: branches/tmp/mvidner/core-dbus-values/dbus/namespace_service/src/DBusModulesServer.h URL: http://svn.opensuse.org/viewcvs/yast/branches/tmp/mvidner/core-dbus-values/d... ============================================================================== --- branches/tmp/mvidner/core-dbus-values/dbus/namespace_service/src/DBusModulesServer.h (original) +++ branches/tmp/mvidner/core-dbus-values/dbus/namespace_service/src/DBusModulesServer.h Wed Jul 1 16:37:56 2009 @@ -35,6 +35,7 @@ virtual actionList createActionId(const DBusMsg &msg); // handle unknown requests + // Tries to autoimport and retry virtual DBusMsg unknownRequest(const DBusMsg &request); private: Modified: branches/tmp/mvidner/core-dbus-values/dbus/namespace_service/testsuite/t2 URL: http://svn.opensuse.org/viewcvs/yast/branches/tmp/mvidner/core-dbus-values/d... ============================================================================== --- branches/tmp/mvidner/core-dbus-values/dbus/namespace_service/testsuite/t2 (original) +++ branches/tmp/mvidner/core-dbus-values/dbus/namespace_service/testsuite/t2 Wed Jul 1 16:37:56 2009 @@ -8,7 +8,7 @@ YT = dbus.Interface(T_o, 'org.opensuse.YaST.YCPValues') yp = (False, "map", dbus.Dictionary(signature="sv", variant_level=1)) yrp = YT.ParamMap(yp) -print yrp +print "Explicit returned:", yrp assert yrp[0] == False assert yrp[1] == "map" rp = yrp[2] @@ -20,8 +20,6 @@ # p = {} # ValueError: Unable to guess signature from an empty dict p = dbus.Dictionary(signature="sv") rp = T.ParamMap(p) -print rp +print "Implicit returned:", rp assert isinstance(rp, dict) assert len(rp.values()) == 0 - -# T.NoSuchMethod() # TODO it does not throw! Modified: branches/tmp/mvidner/core-dbus-values/dbus/namespace_service/testsuite/test_all URL: http://svn.opensuse.org/viewcvs/yast/branches/tmp/mvidner/core-dbus-values/d... ============================================================================== --- branches/tmp/mvidner/core-dbus-values/dbus/namespace_service/testsuite/test_all (original) +++ branches/tmp/mvidner/core-dbus-values/dbus/namespace_service/testsuite/test_all Wed Jul 1 16:37:56 2009 @@ -1,14 +1,21 @@ #! /bin/sh # run all applicable test cases with proper setup -# $0 +# $0 [-a: all, even failing] # $0 ./a_single_testcase -: ${CASES:=$@} -# : ${CASES:=./t?} # t2 fails. also, it requires python - : ${CASES:=./t1} - +if [ "$1" = "" ]; then + # some(most) of them require python + #: ${CASES:=./t1} + : ${CASES:=./t[1235]*} +elif [ "$1" = "-a" ]; then + : ${CASES:=./t? ./t*-*} +else + : ${CASES:=$@} +fi +CASES_A=($CASES) # make array +CASES_A=(${CASES_A[@]/*~/}) # exclude backup files # load the modules from the current directory export Y2DIR=. ./test_server \ ../src/yast_modules_dbus_server --disable-timer --test TEST \ -- \ - $CASES + ${CASES_A[@]} Modified: branches/tmp/mvidner/core-dbus-values/libscr/src/SCR.cc URL: http://svn.opensuse.org/viewcvs/yast/branches/tmp/mvidner/core-dbus-values/l... ============================================================================== --- branches/tmp/mvidner/core-dbus-values/libscr/src/SCR.cc (original) +++ branches/tmp/mvidner/core-dbus-values/libscr/src/SCR.cc Wed Jul 1 16:37:56 2009 @@ -83,7 +83,7 @@ y2debug("Received reply type: %d", reply.type()); // return the first argument from the reply - YCPValue ret = reply.getYCPValue(0); + YCPValue ret = reply.getYCPValue(0, Type::Unspec); // validate the reply (check for exceptions) if (reply.type() != DBUS_MESSAGE_TYPE_METHOD_RETURN) Modified: branches/tmp/mvidner/core-dbus-values/liby2dbus/src/DBusMsg.cc URL: http://svn.opensuse.org/viewcvs/yast/branches/tmp/mvidner/core-dbus-values/l... ============================================================================== --- branches/tmp/mvidner/core-dbus-values/liby2dbus/src/DBusMsg.cc (original) +++ branches/tmp/mvidner/core-dbus-values/liby2dbus/src/DBusMsg.cc Wed Jul 1 16:37:56 2009 @@ -1,4 +1,3 @@ - /* DBusMsg @@ -662,265 +661,356 @@ } -YCPValue DBusMsg::getYCPValueRaw(DBusMessageIter *it, const std::string &ycp_type) const +// returns NULL if "it" does not point to a string +const char * DBusMsg::getString(DBusMessageIter *it) const { - YCPValue ret; + const char *s = NULL; + if (dbus_message_iter_get_arg_type (it) == DBUS_TYPE_STRING) + { + dbus_message_iter_get_basic(it, &s); + } + return s; +} - int type = dbus_message_iter_get_arg_type(it); +// "it" is the inside iterator +YCPList DBusMsg::getYCPValueList(DBusMessageIter *it, constTypePtr valuetype) const +{ + YCPList lst; - // TODO support more types - if (type == DBUS_TYPE_BOOLEAN) + while (dbus_message_iter_get_arg_type (it) != DBUS_TYPE_INVALID) { - bool b; - dbus_message_iter_get_basic(it, &b); - ret = YCPBoolean(b); + // FIXME this can fail + YCPValue list_val = getYCPValue(it, valuetype); + lst->add(list_val); + + dbus_message_iter_next(it); } - else if (type == DBUS_TYPE_STRING) - { - const char *s; - dbus_message_iter_get_basic(it, &s); + return lst; +} - static const char* block_prefix = "block "; - static const int block_prefix_len = ::strlen(block_prefix); +// "it" is the inside iterator +YCPMap DBusMsg::getYCPValueMap(DBusMessageIter *it, constTypePtr keytype, constTypePtr valuetype) const +{ + YCPMap map; - // use ycp_type to return the correct type - if (ycp_type.empty() || ycp_type == "string") - ret = YCPString(s); - else if (ycp_type == "symbol") - ret = YCPSymbol(s); - else if (ycp_type == "path") - ret = YCPPath(s); - else if (std::string(ycp_type, 0, block_prefix_len) == block_prefix) + while (dbus_message_iter_get_arg_type (it) != DBUS_TYPE_INVALID) + { + // is it a map or a list? + if (dbus_message_iter_get_arg_type(it) == DBUS_TYPE_DICT_ENTRY) { - y2debug("Found YCP block"); + DBusMessageIter mapit; + dbus_message_iter_recurse(it, &mapit); - if (s == NULL || *s == '\0') - { - y2warning("The code block is empty"); - ret = YCPVoid(); - } - else - { - // parse the string, recreate the YCPBlock again - Parser parser(s); - parser.setBuffered(); - YCodePtr p = parser.parse(); - YCPValue contents = YCPNull (); - - if (!p) - { - y2error("Parse error in YCP code: %s", s); - } - else - { - if (p->isBlock ()) - { - contents = YCPCode (p); - } - else - { - contents = p->evaluate (true); - } - } + // DICT keys cannot be structs, skip Bsv + YCPValue key = getYCPValueRawType(&mapit, keytype); - ret = !contents.isNull() ? contents : YCPVoid(); - } + dbus_message_iter_next(&mapit); + + // read the value + YCPValue val = getYCPValue(&mapit, valuetype); + + map->add(key, val); } - else + // else FIXME how to signal error + + dbus_message_iter_next(it); + } + return map; +} + +// returns YCPNull without an error if "it" does not point to an integer/byte +YCPValue DBusMsg::getYCPValueInteger(DBusMessageIter *it) const +{ + int type = dbus_message_iter_get_arg_type(it); + YCPValue ret; + + switch (type) { + case DBUS_TYPE_INT64: { - y2warning("Unknown STRING data, returning as YCPString"); - // default is YCPString - ret = YCPString(s); + dbus_int64_t i; + dbus_message_iter_get_basic(it, &i); + ret = YCPInteger(i); + break; + } + case DBUS_TYPE_UINT64: + { + // warning: YCPInteger is signed! + dbus_uint64_t i; + dbus_message_iter_get_basic(it, &i); + ret = YCPInteger(i); + break; + } + case DBUS_TYPE_INT32: + { + dbus_int32_t i; + dbus_message_iter_get_basic(it, &i); + ret = YCPInteger(i); + break; + } + case DBUS_TYPE_UINT32: + { + dbus_uint32_t i; + dbus_message_iter_get_basic(it, &i); + ret = YCPInteger(i); + break; + } + case DBUS_TYPE_INT16: + { + dbus_int16_t i; + dbus_message_iter_get_basic(it, &i); + ret = YCPInteger(i); + break; + } + case DBUS_TYPE_UINT16: + { + dbus_uint16_t i; + dbus_message_iter_get_basic(it, &i); + ret = YCPInteger(i); + break; + } + case DBUS_TYPE_BYTE: + { + unsigned char i; + dbus_message_iter_get_basic(it, &i); + ret = YCPInteger(i); + break; } } - else if (type == DBUS_TYPE_ARRAY) - { - DBusMessageIter sub; - dbus_message_iter_recurse(it, &sub); + return ret; +} - // DBUS_TYPE_ARRAY is used for YCPList and YCPMap - if (ycp_type == "list") - { - y2debug("Found an YCPList container"); - YCPList lst; +// here ycptype is NOT Type::Unspec +YCPValue DBusMsg::getYCPValueRawType(DBusMessageIter *it, constTypePtr ycptype) const +{ + if (ycptype->isAny()) + return getYCPValueRawAny(it); - while (dbus_message_iter_get_arg_type (&sub) != DBUS_TYPE_INVALID) - { - YCPValue list_val = getYCPValue(&sub); - lst->add(list_val); + YCPValue ret; - dbus_message_iter_next(&sub); - } + int type = dbus_message_iter_get_arg_type(it); + bool mismatch = true; - ret = lst; + if (ycptype->isBoolean()) + { + if (type == DBUS_TYPE_BOOLEAN) + { + bool b; + dbus_message_iter_get_basic(it, &b); + ret = YCPBoolean(b); + mismatch = false; } - else if (ycp_type == "map") + } + else if (ycptype->isInteger()) + { + ret = getYCPValueInteger(it); + mismatch = ret.isNull(); + } + else if (ycptype->isFloat()) + { + if (type == DBUS_TYPE_DOUBLE) { - y2debug("Found an YCPMap container"); - YCPMap map; - - while (dbus_message_iter_get_arg_type (&sub) != DBUS_TYPE_INVALID) - { - // is it a map or a list? - if (dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_DICT_ENTRY) - { - DBusMessageIter mapit; - dbus_message_iter_recurse(&sub, &mapit); - - // read the key without the header - YCPValue key = getYCPValueRaw(&mapit); + double d; + dbus_message_iter_get_basic(it, &d); + ret = YCPFloat(d); + mismatch = false; + } + } + else if (ycptype->isList()) + { + // DBUS_TYPE_ARRAY is used for YCPList and YCPMap + // TODO sending a dict where a list is expected will confusingly complain about value type mismatch + if (type == DBUS_TYPE_ARRAY) + { + DBusMessageIter sub; + dbus_message_iter_recurse(it, &sub); - dbus_message_iter_next(&mapit); + constListTypePtr list_type = (constListTypePtr) ycptype; + constTypePtr valuetype = list_type->type(); - // read the value - YCPValue val = getYCPValue(&mapit); + // FIXME this can fail + ret = getYCPValueList(&sub, valuetype); + mismatch = false; + } + } + else if (ycptype->isMap()) + { + if (type == DBUS_TYPE_ARRAY) + { + DBusMessageIter sub; + dbus_message_iter_recurse(it, &sub); - map->add(key, val); - } + constMapTypePtr map_type = (constMapTypePtr) ycptype; + constTypePtr keytype = map_type->keytype(); + constTypePtr valuetype = map_type->valuetype(); - dbus_message_iter_next(&sub); - } - - ret = map; + ret = getYCPValueMap(&sub, keytype, valuetype); + mismatch = false; } - else if (ycp_type == "term") + } + else if (ycptype->isTerm()) + { + // array with first item being the name + if (type == DBUS_TYPE_ARRAY) { - y2debug("Found an YCPTerm container"); + DBusMessageIter sub; + dbus_message_iter_recurse(it, &sub); - YCPList term_list; std::string term_name; + YCPList term_list; - int index = 0; - while (dbus_message_iter_get_arg_type (&sub) != DBUS_TYPE_INVALID) + if (dbus_message_iter_get_arg_type (&sub) != DBUS_TYPE_INVALID) { - YCPValue list_val = getYCPValue(&sub); - - if (index == 0) + YCPValue ytn = getYCPValue(&sub, Type::String); + if (!ytn.isNull() && ytn->isString()) { - if (!list_val.isNull() && list_val->isString()) - { - term_name = list_val->asString()->value(); - } - else - { - y2error("Expecting string (term name) in the list"); - return YCPVoid(); - } + term_name = ytn->asString()->value(); + dbus_message_iter_next(&sub); + + term_list = getYCPValueList(&sub, Type::Unspec); + + y2debug("Received TERM: name: %s, list: %s", term_name.c_str(), term_list->toString().c_str()); + + ret = YCPTerm(term_name, term_list); + mismatch = false; } else { - term_list->add(list_val); + y2error("Expecting string (term name) in the list"); + return YCPVoid(); // FIXME } - - dbus_message_iter_next(&sub); - index++; } - - y2debug("Received TERM: name: %s, list: %s", term_name.c_str(), term_list->toString().c_str()); - - YCPTerm term(term_name, term_list); - ret = term; } - else if (ycp_type.empty()) + } + else if (ycptype->isString()) + { + const char *s = getString(it); + if (s != NULL) { - y2debug("Reading RAW DBus array"); - - // is the container a map or a list? - if (dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_DICT_ENTRY) + ret = YCPString(s); + mismatch = false; + } + } + else if (ycptype->isSymbol()) + { + const char *s = getString(it); + if (s != NULL) + { + ret = YCPSymbol(s); + mismatch = false; + } + } + else if (ycptype->isPath()) + { + const char *s = getString(it); + if (s != NULL) + { + ret = YCPPath(s); + mismatch = false; + } + } + // parsed YCP code, wow. + //FIXME does the execution precede auth checks?! + else if (ycptype->isBlock()) + { + const char *s = getString(it); + if (s != NULL) + { + if (*s == '\0') { - y2debug("Found a map"); - - YCPMap map; - - while (dbus_message_iter_get_arg_type (&sub) != DBUS_TYPE_INVALID) - { - // is it a map or a list? - if (dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_DICT_ENTRY) - { - DBusMessageIter mapit; - dbus_message_iter_recurse(&sub, &mapit); - - // read the key without the header - YCPValue key = getYCPValueRaw(&mapit); - - dbus_message_iter_next(&mapit); - - // read the value - YCPValue val = getYCPValueRaw(&mapit); - - map->add(key, val); - } - - dbus_message_iter_next(&sub); - } - - ret = map; + y2warning("The code block is empty"); + ret = YCPVoid(); } else { - y2debug("Found a list"); - - YCPList lst; + // parse the string, recreate the YCPBlock again + Parser parser(s); + parser.setBuffered(); + YCodePtr p = parser.parse(); - while (dbus_message_iter_get_arg_type (&sub) != DBUS_TYPE_INVALID) + if (!p) { - YCPValue list_val = getYCPValue(&sub); - lst->add(list_val); - - dbus_message_iter_next(&sub); + y2error("Parse error in YCP code: %s", s); + ret = YCPVoid(); + } + else + { + ret = p->isBlock ()? YCPCode (p): p->evaluate (true); } - - ret = lst; } - } - else - { - y2error("Unknown container type for DBUS_TYPE_ARRAY: %s", ycp_type.c_str()); - ret = YCPVoid(); + mismatch = false; } } - else if (type == DBUS_TYPE_DOUBLE) - { - double d; - dbus_message_iter_get_basic(it, &d); - ret = YCPFloat(d); - } - else if (type == DBUS_TYPE_INT64) + else { - dbus_int64_t i; - dbus_message_iter_get_basic(it, &i); - ret = YCPInteger(i); + y2error ("Missing code to convert DBus data to YCP type %s", + ycptype->toString().c_str()); } - else if (type == DBUS_TYPE_UINT64) + + if (mismatch) { - // warning: YCPInteger is signed! - dbus_uint64_t i; - dbus_message_iter_get_basic(it, &i); - ret = YCPInteger(i); + y2error ("Data mismatch, expecting YCP type %s, got DBus type %c", + ycptype->toString().c_str(), (char)type); } - else if (type == DBUS_TYPE_INT32) + + return ret; +} + +YCPValue DBusMsg::getYCPValueRawAny(DBusMessageIter *it) const +{ + YCPValue ret; + + int type = dbus_message_iter_get_arg_type(it); + // TODO support more types + if (type == DBUS_TYPE_BOOLEAN) { - dbus_int32_t i; - dbus_message_iter_get_basic(it, &i); - ret = YCPInteger(i); + bool b; + dbus_message_iter_get_basic(it, &b); + ret = YCPBoolean(b); } - else if (type == DBUS_TYPE_UINT32) + else if (type == DBUS_TYPE_STRING) { - dbus_uint32_t i; - dbus_message_iter_get_basic(it, &i); - ret = YCPInteger(i); + const char *s; + dbus_message_iter_get_basic(it, &s); + ret = YCPString(s); + } - else if (type == DBUS_TYPE_INT16) + else if (type == DBUS_TYPE_ARRAY) { - dbus_int16_t i; - dbus_message_iter_get_basic(it, &i); - ret = YCPInteger(i); + DBusMessageIter sub; + dbus_message_iter_recurse(it, &sub); + + // DBUS_TYPE_ARRAY is used for YCPList and YCPMap + y2debug("Reading RAW DBus array"); + + // is the container a map or a list? + // An empty map is indistinguishable from a list! + if (dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_DICT_ENTRY) + { + y2debug("Found a map"); + ret = getYCPValueMap(&sub, Type::Any, Type::Unspec); + } + else + { + y2debug("Found a list"); + + YCPList lst; + + while (dbus_message_iter_get_arg_type (&sub) != DBUS_TYPE_INVALID) + { + YCPValue list_val = getYCPValue(&sub, Type::Unspec); + lst->add(list_val); + + dbus_message_iter_next(&sub); + } + + ret = lst; + } } - else if (type == DBUS_TYPE_UINT16) + else if (type == DBUS_TYPE_DOUBLE) { - dbus_uint16_t i; - dbus_message_iter_get_basic(it, &i); - ret = YCPInteger(i); + double d; + dbus_message_iter_get_basic(it, &d); + ret = YCPFloat(d); } else if (type == DBUS_TYPE_VARIANT) { @@ -933,42 +1023,57 @@ // there should be just one value inside the container if (dbus_message_iter_get_arg_type (&sub) != DBUS_TYPE_INVALID) { - val = getYCPValueRaw(&sub); + val = getYCPValueRawAny(&sub); } - + // FIXME YCPNull possible ret = val; } else { - y2error("Unsupported DBus type: %d (%c)", type, (char)type); - ret = YCPVoid(); + ret = getYCPValueInteger(it); + if (ret.isNull()) + { + y2error("Unsupported DBus type: %d (%c)", type, (char)type); + ret = YCPVoid(); + } } return ret; } -YCPValue DBusMsg::getYCPValue(DBusMessageIter *it) const +// main getter dispatcher +YCPValue DBusMsg::getYCPValue(DBusMessageIter *it, constTypePtr ycptype) const { int type = dbus_message_iter_get_arg_type(it); y2debug("Found DBus type: %d (%c)", type, (char)type); + YCPValue ret; if (type != DBUS_TYPE_STRUCT) { - YCPValue ret = getYCPValueRaw(it, ""); - if (ret.isNull()) - { - ret = YCPVoid(); - } + if (ycptype->isUnspec()) + ret = getYCPValueRawAny(it); + else + ret = getYCPValueRawType(it, ycptype); - y2milestone("Using RAW dbus value '%s' instead of (bsv) YCPValue structure", ret->toString().c_str()); +// y2milestone("Using RAW dbus value '%s' instead of (bsv) YCPValue structure", ret->toString().c_str()); + } + else + ret = getYCPValueBsv(it, ycptype); - return ret; + if (ret.isNull()) // TODO unify + { + ret = YCPVoid(); } + return ret; +} +// "it" must point to a struct +YCPValue DBusMsg::getYCPValueBsv(DBusMessageIter *it, constTypePtr ycptype) const +{ DBusMessageIter struct_iter; dbus_message_iter_recurse(it, &struct_iter); - type = dbus_message_iter_get_arg_type(&struct_iter); + int type = dbus_message_iter_get_arg_type(&struct_iter); bool received_nil = false; // read the nil flag at the beginning @@ -987,6 +1092,8 @@ } else { + // FIXME "response" is wrong, can go both ways. + // for params, should throw param dbus error y2error("Missing nil flag in the response"); return YCPVoid(); } @@ -994,14 +1101,29 @@ // read the data type in the header dbus_message_iter_next(&struct_iter); - std::string ycp_type; + constTypePtr vycptype = Type::Unspec; type = dbus_message_iter_get_arg_type(&struct_iter); if (type == DBUS_TYPE_STRING) { const char *str; dbus_message_iter_get_basic(&struct_iter, &str); y2debug("HEADER: type: %s", str); - ycp_type = str; + + std::string ycp_type = str; + if (ycp_type == "string") + vycptype = Type::String; + else if (ycp_type == "symbol") + vycptype = Type::Symbol; + else if (ycp_type == "path") + vycptype = Type::Path; + else if (ycp_type == "list") + vycptype = Type::List; + else if (ycp_type == "map") + vycptype = Type::Map; + else if (ycp_type == "block") + vycptype = Type::Block; + else + y2error("Dunno how to translate BSV type %s to YCP type", str); } else { @@ -1023,12 +1145,13 @@ DBusMessageIter variant_iter; dbus_message_iter_recurse(&struct_iter, &variant_iter); - YCPValue ret = getYCPValueRaw(&variant_iter, ycp_type); + YCPValue ret = getYCPValueRawType(&variant_iter, vycptype); return (received_nil) ? YCPVoid() : ret; } -YCPValue DBusMsg::getYCPValue(int index) const +// the public getter: idx +YCPValue DBusMsg::getYCPValue(int index, constTypePtr ycptype) const { YCPValue ret = YCPNull(); @@ -1046,6 +1169,7 @@ int i = 0; // iterate over the other arguments +//wasteful API? while (i < index && dbus_message_iter_next(&it)) { i++; @@ -1053,7 +1177,7 @@ if (i == index) { - ret = getYCPValue(&it); + ret = getYCPValue(&it, ycptype); } else { Modified: branches/tmp/mvidner/core-dbus-values/liby2dbus/src/DBusMsg.h URL: http://svn.opensuse.org/viewcvs/yast/branches/tmp/mvidner/core-dbus-values/l... ============================================================================== --- branches/tmp/mvidner/core-dbus-values/liby2dbus/src/DBusMsg.h (original) +++ branches/tmp/mvidner/core-dbus-values/liby2dbus/src/DBusMsg.h Wed Jul 1 16:37:56 2009 @@ -1,4 +1,3 @@ - /* DBusMsg */ @@ -12,6 +11,8 @@ #include <ycp/TypePtr.h> class YCPValue; +class YCPList; +class YCPMap; // DBusMessage wrapper class DBusMsg @@ -47,7 +48,8 @@ bool addYCPValue(const YCPValue &val); bool addValueAs(const YCPValue &val, constTypePtr rettype = NULL); - YCPValue getYCPValue(int index) const; + // ycptype may be Type::Any + YCPValue getYCPValue(int index, constTypePtr ycptype) const; bool isMethodCall(const std::string &interface, const std::string &method) const; int arguments() const; @@ -78,8 +80,27 @@ int typeInt(const YCPValue &val) const; std::string typeStr(const YCPValue &val, bool bsv_enc = true) const; - YCPValue getYCPValue(DBusMessageIter *it) const; - YCPValue getYCPValueRaw(DBusMessageIter *it, const std::string &ycp_type = std::string()) const; + YCPValue getYCPValue(DBusMessageIter *it, constTypePtr ycptype) const; + YCPValue getYCPValueRawType(DBusMessageIter *it, constTypePtr ycptype) const; + YCPValue getYCPValueRawAny(DBusMessageIter *it) const; + YCPValue getYCPValueBsv(DBusMessageIter *it, constTypePtr ycptype) const; + + const char * getString(DBusMessageIter *it) const; + YCPList getYCPValueList(DBusMessageIter *it, constTypePtr valuetype) const; + YCPMap getYCPValueMap(DBusMessageIter *it, constTypePtr keytype, constTypePtr valuetype) const; + YCPValue getYCPValueInteger(DBusMessageIter *it) const; + +}; + +class DBusException +{ + std::string m_name; + std::string m_message; +public: + DBusException(const std::string& name, const std::string& message) + :m_name(name), m_message(message) {} + std::string name() const { return m_name; } + std::string message() const { return m_message; } }; class SignatureException : std::exception @@ -89,4 +110,3 @@ }; #endif - Modified: branches/tmp/mvidner/core-dbus-values/liby2dbus/src/DBusServerBase.h URL: http://svn.opensuse.org/viewcvs/yast/branches/tmp/mvidner/core-dbus-values/l... ============================================================================== --- branches/tmp/mvidner/core-dbus-values/liby2dbus/src/DBusServerBase.h (original) +++ branches/tmp/mvidner/core-dbus-values/liby2dbus/src/DBusServerBase.h Wed Jul 1 16:37:56 2009 @@ -56,6 +56,7 @@ virtual actionList createActionId(const DBusMsg &msg); // handle unknown requests + // Some servers will try to autoload and retry virtual DBusMsg unknownRequest(const DBusMsg &request); std::string service_name; -- To unsubscribe, e-mail: yast-commit+unsubscribe@opensuse.org For additional commands, e-mail: yast-commit+help@opensuse.org
participants (1)
-
mvidner@svn.opensuse.org