/**
 * @ingroup DBusSignatureInternals
 * Unit test for DBusSignature.
 *
 * @returns #TRUE on success.
 */
dbus_bool_t
_dbus_signature_test (void)
{
  DBusSignatureIter iter;
  DBusSignatureIter subiter;
  DBusSignatureIter subsubiter;
  DBusSignatureIter subsubsubiter;
  const char *sig;
  dbus_bool_t boolres;

  _dbus_assert (sizeof (DBusSignatureIter) >= sizeof (DBusSignatureRealIter));

  sig = "";
  _dbus_assert (dbus_signature_validate (sig, NULL));
  _dbus_assert (!dbus_signature_validate_single (sig, NULL));
  dbus_signature_iter_init (&iter, sig);
  _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_INVALID);

  sig = DBUS_TYPE_STRING_AS_STRING;
  _dbus_assert (dbus_signature_validate (sig, NULL));
  _dbus_assert (dbus_signature_validate_single (sig, NULL));
  dbus_signature_iter_init (&iter, sig);
  _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_STRING);

  sig = DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_BYTE_AS_STRING;
  _dbus_assert (dbus_signature_validate (sig, NULL));
  dbus_signature_iter_init (&iter, sig);
  _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_STRING);
  boolres = dbus_signature_iter_next (&iter);
  _dbus_assert (boolres);
  _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_BYTE);

  sig = DBUS_TYPE_UINT16_AS_STRING
    DBUS_STRUCT_BEGIN_CHAR_AS_STRING
    DBUS_TYPE_STRING_AS_STRING
    DBUS_TYPE_UINT32_AS_STRING
    DBUS_TYPE_VARIANT_AS_STRING
    DBUS_TYPE_DOUBLE_AS_STRING
    DBUS_STRUCT_END_CHAR_AS_STRING;
  _dbus_assert (dbus_signature_validate (sig, NULL));
  dbus_signature_iter_init (&iter, sig);
  _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_UINT16);
  boolres = dbus_signature_iter_next (&iter);
  _dbus_assert (boolres);
  _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_STRUCT);
  dbus_signature_iter_recurse (&iter, &subiter);
  _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_STRING);
  boolres = dbus_signature_iter_next (&subiter);
  _dbus_assert (boolres);
  _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_UINT32);
  boolres = dbus_signature_iter_next (&subiter);
  _dbus_assert (boolres);
  _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_VARIANT);
  boolres = dbus_signature_iter_next (&subiter);
  _dbus_assert (boolres);
  _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_DOUBLE);

  sig = DBUS_TYPE_UINT16_AS_STRING
    DBUS_STRUCT_BEGIN_CHAR_AS_STRING
    DBUS_TYPE_UINT32_AS_STRING
    DBUS_TYPE_BYTE_AS_STRING
    DBUS_TYPE_ARRAY_AS_STRING
    DBUS_TYPE_ARRAY_AS_STRING
    DBUS_TYPE_DOUBLE_AS_STRING
    DBUS_STRUCT_BEGIN_CHAR_AS_STRING
    DBUS_TYPE_BYTE_AS_STRING
    DBUS_STRUCT_END_CHAR_AS_STRING
    DBUS_STRUCT_END_CHAR_AS_STRING;
  _dbus_assert (dbus_signature_validate (sig, NULL));
  dbus_signature_iter_init (&iter, sig);
  _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_UINT16);
  boolres = dbus_signature_iter_next (&iter);
  _dbus_assert (boolres);
  _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_STRUCT);
  dbus_signature_iter_recurse (&iter, &subiter);
  _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_UINT32);
  boolres = dbus_signature_iter_next (&subiter);
  _dbus_assert (boolres);
  _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_BYTE);
  boolres = dbus_signature_iter_next (&subiter);
  _dbus_assert (boolres);
  _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_ARRAY);
  _dbus_assert (dbus_signature_iter_get_element_type (&subiter) == DBUS_TYPE_ARRAY);

  dbus_signature_iter_recurse (&subiter, &subsubiter);
  _dbus_assert (dbus_signature_iter_get_current_type (&subsubiter) == DBUS_TYPE_ARRAY);
  _dbus_assert (dbus_signature_iter_get_element_type (&subsubiter) == DBUS_TYPE_DOUBLE);

  dbus_signature_iter_recurse (&subsubiter, &subsubsubiter);
  _dbus_assert (dbus_signature_iter_get_current_type (&subsubsubiter) == DBUS_TYPE_DOUBLE);
  boolres = dbus_signature_iter_next (&subiter);
  _dbus_assert (boolres);
  _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_STRUCT);
  dbus_signature_iter_recurse (&subiter, &subsubiter);
  _dbus_assert (dbus_signature_iter_get_current_type (&subsubiter) == DBUS_TYPE_BYTE);

  sig = DBUS_TYPE_ARRAY_AS_STRING
    DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
    DBUS_TYPE_INT16_AS_STRING
    DBUS_TYPE_STRING_AS_STRING
    DBUS_DICT_ENTRY_END_CHAR_AS_STRING
    DBUS_TYPE_VARIANT_AS_STRING;
  _dbus_assert (dbus_signature_validate (sig, NULL));
  _dbus_assert (!dbus_signature_validate_single (sig, NULL));
  dbus_signature_iter_init (&iter, sig);
  _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_ARRAY);
  _dbus_assert (dbus_signature_iter_get_element_type (&iter) == DBUS_TYPE_DICT_ENTRY);

  dbus_signature_iter_recurse (&iter, &subiter);
  dbus_signature_iter_recurse (&subiter, &subsubiter);
  _dbus_assert (dbus_signature_iter_get_current_type (&subsubiter) == DBUS_TYPE_INT16);
  boolres = dbus_signature_iter_next (&subsubiter);
  _dbus_assert (boolres);
  _dbus_assert (dbus_signature_iter_get_current_type (&subsubiter) == DBUS_TYPE_STRING);
  boolres = dbus_signature_iter_next (&subsubiter);
  _dbus_assert (!boolres);

  boolres = dbus_signature_iter_next (&iter);
  _dbus_assert (boolres);
  _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_VARIANT);
  boolres = dbus_signature_iter_next (&iter);
  _dbus_assert (!boolres);

  sig = DBUS_TYPE_DICT_ENTRY_AS_STRING;
  _dbus_assert (!dbus_signature_validate (sig, NULL));

  sig = DBUS_TYPE_ARRAY_AS_STRING;
  _dbus_assert (!dbus_signature_validate (sig, NULL));

  sig = DBUS_TYPE_UINT32_AS_STRING
    DBUS_TYPE_ARRAY_AS_STRING;
  _dbus_assert (!dbus_signature_validate (sig, NULL));

  sig = DBUS_TYPE_ARRAY_AS_STRING
    DBUS_TYPE_DICT_ENTRY_AS_STRING;
  _dbus_assert (!dbus_signature_validate (sig, NULL));

  sig = DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING;
  _dbus_assert (!dbus_signature_validate (sig, NULL));

  sig = DBUS_DICT_ENTRY_END_CHAR_AS_STRING;
  _dbus_assert (!dbus_signature_validate (sig, NULL));

  sig = DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
    DBUS_TYPE_INT32_AS_STRING;
  _dbus_assert (!dbus_signature_validate (sig, NULL));

  sig = DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
    DBUS_TYPE_INT32_AS_STRING
    DBUS_TYPE_STRING_AS_STRING;
  _dbus_assert (!dbus_signature_validate (sig, NULL));

  sig = DBUS_STRUCT_END_CHAR_AS_STRING
    DBUS_STRUCT_BEGIN_CHAR_AS_STRING;
  _dbus_assert (!dbus_signature_validate (sig, NULL));

  sig = DBUS_STRUCT_BEGIN_CHAR_AS_STRING
    DBUS_TYPE_BOOLEAN_AS_STRING;
  _dbus_assert (!dbus_signature_validate (sig, NULL));
  return TRUE;
#if 0
 oom:
  _dbus_assert_not_reached ("out of memory");
  return FALSE;
#endif
}
示例#2
0
gboolean js_to_dbus(JSContextRef ctx, const JSValueRef jsvalue,
    DBusMessageIter *iter, const char* sig, JSValueRef* exception)
{
    DBusSignatureIter s_iter;
    dbus_signature_iter_init(&s_iter, sig);

    int type;
    switch (type = dbus_signature_iter_get_current_type(&s_iter)) {
        case DBUS_TYPE_BOOLEAN:
            {
                dbus_bool_t value = JSValueToBoolean(ctx, jsvalue);
                if (!dbus_message_iter_append_basic(iter, type, (void*)&value)) {
                    g_warning("signatuer:%c error!", type);
                    return FALSE;
                }  else {
                    return TRUE;
                }
            }
        case DBUS_TYPE_DOUBLE:
            CASE_NUMBER
            {
                if (!JSValueIsNumber(ctx, jsvalue)) {
                    js_fill_exception(ctx, exception, "jsvalue is not an number!");
                    return FALSE;
                }
                double value = JSValueToNumber(ctx, jsvalue, NULL);
                if (!dbus_message_iter_append_basic(iter, type, (void*)&value)) {
                    g_warning("signatuer:%c error!", type);
                    return FALSE;
                } else {
                    return TRUE;
                }
            }
            CASE_STRING
            {
                char* value = jsvalue_to_cstr(ctx, jsvalue);
                if (value == NULL ||
                        !dbus_message_iter_append_basic(iter, type, (void*)&value)) {
                    g_free(value);
                    js_fill_exception(ctx, exception, "jsvalue is not an string or memory not enough!");
                    return FALSE;
                } else {
                    g_free(value);
                    return TRUE;
                }
            }

        case DBUS_TYPE_STRUCT:
            {
                if (!jsvalue_instanceof(ctx, jsvalue, "Array")) {
                    js_fill_exception(ctx, exception, "jsvalue should an array");
                    return FALSE;
                }

                JSPropertyNameArrayRef prop_names =
                    JSObjectCopyPropertyNames(ctx, (JSObjectRef)jsvalue);
                int p_num = JSPropertyNameArrayGetCount(prop_names);
                if (p_num == 0) {
                    JSPropertyNameArrayRelease(prop_names);
                    js_fill_exception(ctx, exception, "Struct at least have one element!");
                    return FALSE;
                }

                DBusMessageIter sub_iter;
                OPEN_CONTAINER(iter, type, NULL, &sub_iter);

                DBusSignatureIter sub_s_iter;
                dbus_signature_iter_recurse(&s_iter, &sub_s_iter);

                for (int i=0; i<p_num; i++) {
                    JSValueRef value = JSObjectGetProperty(ctx,
                            (JSObjectRef)jsvalue,
                            JSPropertyNameArrayGetNameAtIndex(prop_names, i),
                            NULL);

                    char *sig = dbus_signature_iter_get_signature(&sub_s_iter);
                    if (!js_to_dbus(ctx, value, &sub_iter, sig, exception)) {
                        js_fill_exception(ctx, exception, "Failed append struct with sig:%sTODO");
                        dbus_free(sig);
                        return FALSE;
                    }
                    dbus_free(sig);

                    if (i != p_num-1 && !dbus_signature_iter_next(&sub_s_iter)) {
                        JSPropertyNameArrayRelease(prop_names);
                        CLOSE_CONTAINER(iter, &sub_iter);
                        js_fill_exception(ctx, exception, "to many params filled to struct");
                        return FALSE;
                    }
                }

                if (dbus_signature_iter_next(&sub_s_iter)) {
                    JSPropertyNameArrayRelease(prop_names);
                    CLOSE_CONTAINER(iter, &sub_iter);
                    js_fill_exception(ctx, exception, "need more params by this struct");
                    return FALSE;
                }
                JSPropertyNameArrayRelease(prop_names);
                CLOSE_CONTAINER(iter, &sub_iter);
                return TRUE;
            }
        case DBUS_TYPE_ARRAY:
            if (dbus_signature_iter_get_element_type(&s_iter) ==
                    DBUS_TYPE_DICT_ENTRY) {

                DBusSignatureIter dict_s_iter;
                dbus_signature_iter_recurse(&s_iter, &dict_s_iter);
                char *d_sig = dbus_signature_iter_get_signature(&dict_s_iter);

                DBusMessageIter sub_iter;
                OPEN_CONTAINER(iter, type, d_sig, &sub_iter);
                dbus_free(d_sig);

                JSPropertyNameArrayRef prop_names = JSObjectCopyPropertyNames(ctx,
                        (JSObjectRef)jsvalue);
                int p_num = JSPropertyNameArrayGetCount(prop_names);

                DBusSignatureIter dict_sub_s_iter;
                dbus_signature_iter_recurse(&dict_s_iter, &dict_sub_s_iter);

                int key_type = dbus_signature_iter_get_current_type(&dict_sub_s_iter);
                dbus_signature_iter_next(&dict_sub_s_iter);
                char *val_sig = dbus_signature_iter_get_signature(&dict_sub_s_iter);


                for (int i=0; i<p_num; i++) {
                    DBusMessageIter dict_iter;
                    OPEN_CONTAINER(&sub_iter, DBUS_TYPE_DICT_ENTRY,
                            NULL, &dict_iter);

                    JSStringRef key_str = JSPropertyNameArrayGetNameAtIndex(prop_names, i);

                    //TODO: fetch key type
                    switch (key_type) {
                        CASE_STRING
                        {
                            char *value = jsstring_to_cstr(ctx, key_str);
                            dbus_message_iter_append_basic(&dict_iter, key_type, (void*)&value);
                            g_free(value);
                            break;
                        }
                        case DBUS_TYPE_DOUBLE:
                        CASE_NUMBER
                        {
                            //TODO detect illegal number format
                            JSValueRef excp;
                            double value = JSValueToNumber(ctx,
                                    JSValueMakeString(ctx, key_str), &excp);

                            if (excp != NULL) {
                                js_fill_exception(ctx, exception, "dict_entry's key must be an number to match the signature!");
                                return FALSE;
                            }

                            dbus_message_iter_append_basic(&dict_iter, key_type,
                                    (void*)&value);
                            break;
                        }
                        default:
                        {
                            js_fill_exception(ctx, exception, "DICT_ENTRY's key must basic type, and you should not see this warning in javascript runtime");
                            dbus_free(val_sig);
                            JSPropertyNameArrayRelease(prop_names);
                            CLOSE_CONTAINER(iter, &sub_iter);
                            return FALSE;
                        }
                    }



                    js_to_dbus(ctx,
                            JSObjectGetProperty(ctx, (JSObjectRef)jsvalue,
                                key_str, NULL),
                            &dict_iter, val_sig,
                            exception);

                    CLOSE_CONTAINER(&sub_iter, &dict_iter);
                }
                dbus_free(val_sig);
                JSPropertyNameArrayRelease(prop_names);

                CLOSE_CONTAINER(iter, &sub_iter);
                return TRUE;
            } else {