@@ -151,17 +151,23 @@ typedef bool (*CheckTypeCallback) (Local<Value>& value, const char* sig);
151
151
return " " ;
152
152
}
153
153
154
- bool EncodeObject (Local<Value> value, DBusMessageIter *iter, const char *signature)
154
+ bool EncodeObject (Local<Value> value, DBusMessageIter *iter,
155
+ const DBusSignatureIter *siter,
156
+ const DBusSignatureIter *concreteSiter)
155
157
{
156
158
// printf("EncodeObject %s\n",signature);
157
159
// printf("%p", value);
158
160
Nan::HandleScope scope;
159
- DBusSignatureIter siter;
160
161
int type;
162
+
163
+ if (concreteSiter == NULL )
164
+ {
165
+ // this is safe because we never modify siter
166
+ concreteSiter = siter;
167
+ }
161
168
162
169
// Get type of current value
163
- dbus_signature_iter_init (&siter, signature);
164
- type = dbus_signature_iter_get_current_type (&siter);
170
+ type = dbus_signature_iter_get_current_type (siter);
165
171
166
172
switch (type) {
167
173
case DBUS_TYPE_INVALID:
@@ -315,11 +321,12 @@ typedef bool (*CheckTypeCallback) (Local<Value>& value, const char* sig);
315
321
}
316
322
317
323
DBusMessageIter subIter;
318
- DBusSignatureIter arraySiter;
324
+ DBusSignatureIter arraySiter, arrayConcreteSiter ;
319
325
char *array_sig = NULL ;
320
326
321
327
// Getting signature of array object
322
- dbus_signature_iter_recurse (&siter, &arraySiter);
328
+ dbus_signature_iter_recurse (siter, &arraySiter);
329
+ dbus_signature_iter_recurse (concreteSiter, &arrayConcreteSiter);
323
330
array_sig = dbus_signature_iter_get_signature (&arraySiter);
324
331
325
332
// Open array container to process elements in there
@@ -328,27 +335,24 @@ typedef bool (*CheckTypeCallback) (Local<Value>& value, const char* sig);
328
335
printf (" Can't open container for Array type\n " );
329
336
return false ;
330
337
}
338
+ dbus_free (array_sig);
331
339
332
340
// It's a dictionary
333
- if (dbus_signature_iter_get_element_type (&siter) == DBUS_TYPE_DICT_ENTRY) {
334
-
335
- dbus_free (array_sig);
336
-
341
+ if (dbus_signature_iter_get_element_type (siter) == DBUS_TYPE_DICT_ENTRY) {
337
342
Local<Object> value_object = value->ToObject ();
338
- DBusSignatureIter dictSubSiter;
339
-
340
- // Getting sub-signature object
341
- dbus_signature_iter_recurse (&arraySiter, &dictSubSiter);
342
- dbus_signature_iter_next (&dictSubSiter);
343
- char *sig = dbus_signature_iter_get_signature (&dictSubSiter);
344
343
345
344
// process each elements
346
345
Local<Array> prop_names = value_object->GetPropertyNames ();
347
346
unsigned int len = prop_names->Length ();
348
347
349
348
bool failed = false ;
350
349
for (unsigned int i = 0 ; i < len; ++i) {
350
+ DBusSignatureIter dictSubSiter, dictSubConcreteSiter;
351
351
DBusMessageIter dict_iter;
352
+
353
+ // Getting sub-signature object
354
+ dbus_signature_iter_recurse (&arraySiter, &dictSubSiter);
355
+ dbus_signature_iter_recurse (&arrayConcreteSiter, &dictSubConcreteSiter);
352
356
353
357
// Open dict entry container
354
358
if (!dbus_message_iter_open_container (&subIter, DBUS_TYPE_DICT_ENTRY, NULL , &dict_iter)) {
@@ -362,13 +366,17 @@ typedef bool (*CheckTypeCallback) (Local<Value>& value, const char* sig);
362
366
Local<Value> prop_value = value_object->Get (prop_key);
363
367
364
368
// Append the key
365
- char *prop_key_str = strdup (*String::Utf8Value (prop_key->ToString ()));
366
- // printf("key: %s\n", prop_key_str);
367
- dbus_message_iter_append_basic (&dict_iter, DBUS_TYPE_STRING, &prop_key_str);
368
- dbus_free (prop_key_str);
369
+ if (!EncodeObject (prop_key, &dict_iter, &dictSubSiter, &dictSubConcreteSiter)) {
370
+ dbus_message_iter_close_container (&subIter, &dict_iter);
371
+ printf (" Failed to encode element of dictionary\n " );
372
+ failed = true ;
373
+ break ;
374
+ }
369
375
370
376
// Append the value
371
- if (!EncodeObject (prop_value, &dict_iter, sig)) {
377
+ dbus_signature_iter_next (&dictSubSiter);
378
+ dbus_signature_iter_next (&dictSubConcreteSiter);
379
+ if (!EncodeObject (prop_value, &dict_iter, &dictSubSiter, &dictSubConcreteSiter)) {
372
380
dbus_message_iter_close_container (&subIter, &dict_iter);
373
381
printf (" Failed to encode element of dictionary\n " );
374
382
failed = true ;
@@ -378,7 +386,6 @@ typedef bool (*CheckTypeCallback) (Local<Value>& value, const char* sig);
378
386
dbus_message_iter_close_container (&subIter, &dict_iter);
379
387
}
380
388
381
- dbus_free (sig);
382
389
dbus_message_iter_close_container (iter, &subIter);
383
390
384
391
if (failed)
@@ -396,42 +403,54 @@ typedef bool (*CheckTypeCallback) (Local<Value>& value, const char* sig);
396
403
Local<Array> arrayData = Local<Array>::Cast (value);
397
404
for (unsigned int i = 0 ; i < arrayData->Length (); ++i) {
398
405
Local<Value> arrayItem = arrayData->Get (i);
399
- if (!EncodeObject (arrayItem, &subIter, array_sig ))
406
+ if (!EncodeObject (arrayItem, &subIter, &arraySiter, &arrayConcreteSiter ))
400
407
break ;
401
408
}
402
409
403
410
dbus_message_iter_close_container (iter, &subIter);
404
- dbus_free (array_sig);
405
411
406
412
break ;
407
413
}
408
414
409
415
case DBUS_TYPE_VARIANT:
410
416
{
411
417
DBusMessageIter subIter;
412
-
413
- string str_sig = GetSignatureFromV8Type (value);
414
- const char *var_sig = str_sig.c_str ();
418
+ DBusSignatureIter subSiter;
419
+
420
+ char *var_sig;
421
+ if (dbus_signature_iter_get_current_type (concreteSiter) == DBUS_TYPE_VARIANT)
422
+ {
423
+ string str_sig = GetSignatureFromV8Type (value);
424
+ var_sig = strdup (str_sig.c_str ());
425
+ }
426
+ else
427
+ {
428
+ var_sig = dbus_signature_iter_get_signature (concreteSiter);
429
+ }
415
430
416
431
if (!dbus_message_iter_open_container (iter, DBUS_TYPE_VARIANT, var_sig, &subIter)) {
432
+ dbus_free (var_sig);
417
433
printf (" Can't open container for VARIANT type\n " );
418
434
return false ;
419
435
}
420
436
421
- if (!EncodeObject (value, &subIter, var_sig)) {
437
+ dbus_signature_iter_init (&subSiter, var_sig);
438
+ if (!EncodeObject (value, &subIter, &subSiter, &subSiter)) {
422
439
dbus_message_iter_close_container (iter, &subIter);
440
+ dbus_free (var_sig);
423
441
return false ;
424
442
}
425
443
426
444
dbus_message_iter_close_container (iter, &subIter);
445
+ dbus_free (var_sig);
427
446
428
447
break ;
429
448
}
430
449
case DBUS_TYPE_STRUCT:
431
450
{
432
451
// printf("struct\n");
433
452
DBusMessageIter subIter;
434
- DBusSignatureIter structSiter;
453
+ DBusSignatureIter structSiter, structConcreteSiter ;
435
454
436
455
// Open array container to process elements in there
437
456
if (!dbus_message_iter_open_container (iter, DBUS_TYPE_STRUCT, NULL , &subIter)) {
@@ -442,28 +461,27 @@ typedef bool (*CheckTypeCallback) (Local<Value>& value, const char* sig);
442
461
Local<Object> value_object = value->ToObject ();
443
462
444
463
// Getting sub-signature object
445
- dbus_signature_iter_recurse (&siter, &structSiter);
464
+ dbus_signature_iter_recurse (siter, &structSiter);
465
+ dbus_signature_iter_recurse (concreteSiter, &structConcreteSiter);
446
466
447
467
// process each elements
448
468
Local<Array> prop_names = value_object->GetPropertyNames ();
449
469
unsigned int len = prop_names->Length ();
450
470
451
471
for (unsigned int i = 0 ; i < len; ++i) {
452
472
453
- char *sig = dbus_signature_iter_get_signature (&structSiter);
454
-
455
473
Local<Value> prop_key = prop_names->Get (i);
456
474
457
- if (!EncodeObject (value_object->Get (prop_key), &subIter, sig)) {
458
- dbus_free (sig);
475
+ if (!EncodeObject (value_object->Get (prop_key), &subIter, &structSiter, &structConcreteSiter)) {
459
476
printf (" Failed to encode element of dictionary\n " );
460
477
return false ;
461
478
}
462
479
463
- dbus_free (sig);
464
-
465
480
if (!dbus_signature_iter_next (&structSiter))
466
481
break ;
482
+
483
+ if (!dbus_signature_iter_next (&structConcreteSiter))
484
+ break ;
467
485
}
468
486
469
487
dbus_message_iter_close_container (iter, &subIter);
0 commit comments