efl

Форк
0
/
eldbus_message.c 
928 строк · 27.1 Кб
1
#include "eldbus_private.h"
2
#include "eldbus_private_types.h"
3
#include <dbus/dbus.h>
4
#include <stdint.h>
5

6
/* TODO: mempool of Eldbus_Message and Eldbus_Message_Iter */
7

8
#define ELDBUS_MESSAGE_CHECK(msg)                        \
9
  do                                                    \
10
    {                                                   \
11
       EINA_SAFETY_ON_NULL_RETURN(msg);                 \
12
       if (!EINA_MAGIC_CHECK(msg, ELDBUS_MESSAGE_MAGIC)) \
13
         {                                              \
14
            EINA_MAGIC_FAIL(msg, ELDBUS_MESSAGE_MAGIC);  \
15
            return;                                     \
16
         }                                              \
17
       EINA_SAFETY_ON_TRUE_RETURN(msg->refcount <= 0);  \
18
    }                                                   \
19
  while (0)
20

21
#define ELDBUS_MESSAGE_CHECK_RETVAL(msg, retval)                    \
22
  do                                                               \
23
    {                                                              \
24
       EINA_SAFETY_ON_NULL_RETURN_VAL(msg, retval);                \
25
       if (!EINA_MAGIC_CHECK(msg, ELDBUS_MESSAGE_MAGIC))            \
26
         {                                                         \
27
            EINA_MAGIC_FAIL(msg, ELDBUS_MESSAGE_MAGIC);             \
28
            return retval;                                         \
29
         }                                                         \
30
       EINA_SAFETY_ON_TRUE_RETURN_VAL(msg->refcount <= 0, retval); \
31
    }                                                              \
32
  while (0)
33

34
#define ELDBUS_MESSAGE_ITERATOR_CHECK(iter)                        \
35
  do                                                             \
36
    {                                                            \
37
       EINA_SAFETY_ON_NULL_RETURN(iter);                          \
38
       if (!EINA_MAGIC_CHECK(iter, ELDBUS_MESSAGE_ITERATOR_MAGIC)) \
39
         {                                                       \
40
            EINA_MAGIC_FAIL(iter, ELDBUS_MESSAGE_ITERATOR_MAGIC);  \
41
            return;                                              \
42
         }                                                       \
43
    }                                                            \
44
  while (0)
45

46
#define ELDBUS_MESSAGE_ITERATOR_CHECK_RETVAL(iter, retval)          \
47
  do                                                              \
48
    {                                                             \
49
       EINA_SAFETY_ON_NULL_RETURN_VAL(iter, retval);               \
50
       if (!EINA_MAGIC_CHECK(iter, ELDBUS_MESSAGE_ITERATOR_MAGIC))  \
51
         {                                                        \
52
            EINA_MAGIC_FAIL(iter, ELDBUS_MESSAGE_ITERATOR_MAGIC);   \
53
            return retval;                                        \
54
         }                                                        \
55
    }                                                             \
56
  while (0)
57

58
static Eina_Bool append_basic(char type, va_list *vl, DBusMessageIter *iter);
59

60
Eina_Bool
61
eldbus_message_init(void)
62
{
63
   return EINA_TRUE;
64
}
65

66
void
67
eldbus_message_shutdown(void)
68
{
69
}
70

71
static Eldbus_Message_Iter *
72
_message_iterator_new(Eina_Bool writable)
73
{
74
   Eldbus_Message_Iter *iter;
75

76
   iter = calloc(1, sizeof(Eldbus_Message_Iter));
77
   EINA_SAFETY_ON_NULL_RETURN_VAL(iter, NULL);
78
   EINA_MAGIC_SET(iter, ELDBUS_MESSAGE_ITERATOR_MAGIC);
79
   iter->writable = writable;
80

81
   return iter;
82
}
83

84
Eldbus_Message *eldbus_message_new(Eina_Bool writable)
85
{
86
   Eldbus_Message *msg = calloc(1, sizeof(Eldbus_Message));
87
   EINA_SAFETY_ON_NULL_RETURN_VAL(msg, NULL);
88
   EINA_MAGIC_SET(msg, ELDBUS_MESSAGE_MAGIC);
89
   msg->refcount = 1;
90

91
   msg->iterator = _message_iterator_new(writable);
92
   EINA_SAFETY_ON_NULL_GOTO(msg->iterator, fail);
93

94
   return msg;
95

96
fail:
97
   eldbus_message_unref(msg);
98
   return NULL;
99
}
100

101
EAPI Eldbus_Message *
102
eldbus_message_method_call_new(const char *dest, const char *path, const char *iface, const char *method)
103
{
104
   Eldbus_Message *msg;
105

106
   EINA_SAFETY_ON_NULL_RETURN_VAL(dest, NULL);
107
   EINA_SAFETY_ON_NULL_RETURN_VAL(path, NULL);
108
   EINA_SAFETY_ON_NULL_RETURN_VAL(iface, NULL);
109
   EINA_SAFETY_ON_NULL_RETURN_VAL(method, NULL);
110

111
#ifdef DBUS_SYNTAX_H
112
   // added to libdbus:
113
   // f426c6cddd158d6324923f28117bc8e512d6f64f Fri Feb 24 12:43:55 2012 +0000
114
   if (!dbus_validate_bus_name(dest, NULL))
115
     {
116
        ERR("Invalid bus name '%s'", dest);
117
        return NULL;
118
     }
119
   if (!dbus_validate_path(path, NULL))
120
     {
121
        ERR("Invalid path '%s'", path);
122
        return NULL;
123
     }
124
   if (!dbus_validate_interface(iface, NULL))
125
     {
126
        ERR("Invalid interface '%s'", iface);
127
        return NULL;
128
     }
129
#endif
130

131
   msg = eldbus_message_new(EINA_TRUE);
132
   EINA_SAFETY_ON_NULL_GOTO(msg, fail);
133

134
   msg->dbus_msg = dbus_message_new_method_call(dest, path, iface, method);
135
   dbus_message_iter_init_append(msg->dbus_msg, &msg->iterator->dbus_iterator);
136

137
   return msg;
138

139
fail:
140
   eldbus_message_unref(msg);
141
   return NULL;
142
}
143

144
EAPI Eldbus_Message *
145
eldbus_message_ref(Eldbus_Message *msg)
146
{
147
   ELDBUS_MESSAGE_CHECK_RETVAL(msg, NULL);
148
   DBG("msg=%p, pre-refcount=%d", msg, msg->refcount);
149
   msg->refcount++;
150
   return msg;
151
}
152

153
static void
154
_message_iterator_free(Eldbus_Message_Iter *iter)
155
{
156
   Eina_Inlist *lst, *next;
157
   Eldbus_Message_Iter *sub;
158
   if (!iter) return;
159

160
   lst = iter->iterators;
161
   while (lst)
162
     {
163
        next = lst->next;
164
        sub = EINA_INLIST_CONTAINER_GET(lst, Eldbus_Message_Iter);
165
        _message_iterator_free(sub);
166
        lst = next;
167
     }
168
   free(iter);
169
}
170

171
EAPI void
172
eldbus_message_unref(Eldbus_Message *msg)
173
{
174
   ELDBUS_MESSAGE_CHECK(msg);
175
   DBG("msg=%p, pre-refcount=%d", msg, msg->refcount);
176
   msg->refcount--;
177
   if (msg->refcount > 0) return;
178

179
   DBG("message free %p", msg);
180

181
   EINA_MAGIC_SET(msg, EINA_MAGIC_NONE);
182
   if (msg->dbus_msg)
183
     dbus_message_unref(msg->dbus_msg);
184
   msg->dbus_msg = NULL;
185

186
   _message_iterator_free(msg->iterator);
187
   free(msg);
188
}
189

190
EAPI const char *
191
eldbus_message_path_get(const Eldbus_Message *msg)
192
{
193
   ELDBUS_MESSAGE_CHECK_RETVAL(msg, NULL);
194
   return dbus_message_get_path(msg->dbus_msg);
195
}
196

197
EAPI const char *
198
eldbus_message_interface_get(const Eldbus_Message *msg)
199
{
200
   ELDBUS_MESSAGE_CHECK_RETVAL(msg, NULL);
201
   return dbus_message_get_interface(msg->dbus_msg);
202
}
203

204
EAPI const char *
205
eldbus_message_member_get(const Eldbus_Message *msg)
206
{
207
   ELDBUS_MESSAGE_CHECK_RETVAL(msg, NULL);
208
   return dbus_message_get_member(msg->dbus_msg);
209
}
210

211
EAPI const char *
212
eldbus_message_destination_get(const Eldbus_Message *msg)
213
{
214
   ELDBUS_MESSAGE_CHECK_RETVAL(msg, NULL);
215
   return dbus_message_get_destination(msg->dbus_msg);
216
}
217

218
EAPI const char *
219
eldbus_message_sender_get(const Eldbus_Message *msg)
220
{
221
   ELDBUS_MESSAGE_CHECK_RETVAL(msg, NULL);
222
   return dbus_message_get_sender(msg->dbus_msg);
223
}
224

225
EAPI const char *
226
eldbus_message_signature_get(const Eldbus_Message *msg)
227
{
228
   ELDBUS_MESSAGE_CHECK_RETVAL(msg, NULL);
229
   return dbus_message_get_signature(msg->dbus_msg);
230
}
231

232
EAPI Eina_Bool
233
eldbus_message_error_get(const Eldbus_Message *msg, const char **name, const char **text)
234
{
235
   if (name) *name = NULL;
236
   if (text) *text = NULL;
237

238
   ELDBUS_MESSAGE_CHECK_RETVAL(msg, EINA_FALSE);
239

240
   if (dbus_message_get_type(msg->dbus_msg) != DBUS_MESSAGE_TYPE_ERROR)
241
     return EINA_FALSE;
242

243
   if (name)
244
     *name = dbus_message_get_error_name(msg->dbus_msg);
245

246
   if (text)
247
     dbus_message_get_args(msg->dbus_msg, NULL, DBUS_TYPE_STRING, text,
248
                           DBUS_TYPE_INVALID);
249

250
   return EINA_TRUE;
251
}
252

253
static Eina_Bool
254
_eldbus_message_arguments_vget(Eldbus_Message *msg, const char *signature, va_list ap)
255
{
256
   Eldbus_Message_Iter *iter;
257
   iter = eldbus_message_iter_get(msg);
258
   ELDBUS_MESSAGE_ITERATOR_CHECK_RETVAL(iter, EINA_FALSE);
259

260
   return eldbus_message_iter_arguments_vget(iter, signature, ap);
261
}
262

263
EAPI Eldbus_Message_Iter *
264
eldbus_message_iter_get(const Eldbus_Message *msg)
265
{
266
   ELDBUS_MESSAGE_CHECK_RETVAL(msg, NULL);
267
   /* Something went wrong, msg->iterator should not be NULL */
268
   EINA_SAFETY_ON_NULL_RETURN_VAL(msg->iterator, NULL);
269

270
   return msg->iterator;
271
}
272

273
EAPI Eina_Bool
274
eldbus_message_arguments_get(const Eldbus_Message *msg, const char *signature, ...)
275
{
276
   Eina_Bool ret;
277
   va_list ap;
278

279
   ELDBUS_MESSAGE_CHECK_RETVAL(msg, EINA_FALSE);
280
   EINA_SAFETY_ON_NULL_RETURN_VAL(signature, EINA_FALSE);
281

282
   va_start(ap, signature);
283
   ret = _eldbus_message_arguments_vget((Eldbus_Message *)msg, signature, ap);
284
   va_end(ap);
285
   return ret;
286
}
287

288
EAPI Eina_Bool
289
eldbus_message_arguments_vget(const Eldbus_Message *msg, const char *signature, va_list ap)
290
{
291
   ELDBUS_MESSAGE_CHECK_RETVAL(msg, EINA_FALSE);
292
   EINA_SAFETY_ON_NULL_RETURN_VAL(signature, EINA_FALSE);
293
   return _eldbus_message_arguments_vget((Eldbus_Message *)msg, signature, ap);
294
}
295

296
static Eina_Bool
297
_eldbus_message_iter_arguments_vappend(Eldbus_Message_Iter *iter, const char *signature, va_list *aq)
298
{
299
   DBusSignatureIter signature_iter;
300
   Eina_Bool r = EINA_TRUE;
301
   char *type;
302

303
   ELDBUS_MESSAGE_ITERATOR_CHECK_RETVAL(iter, EINA_FALSE);
304
   EINA_SAFETY_ON_FALSE_RETURN_VAL(iter->writable, EINA_FALSE);
305
   EINA_SAFETY_ON_NULL_RETURN_VAL(signature, EINA_FALSE);
306

307
   dbus_signature_iter_init(&signature_iter, signature);
308
   while ((type = dbus_signature_iter_get_signature(&signature_iter)))
309
     {
310
        if (type[0] != DBUS_TYPE_VARIANT && !type[1])
311
          r = append_basic(type[0], aq, &iter->dbus_iterator);
312
        else
313
          {
314
             Eldbus_Message_Iter **user_itr;
315
             Eldbus_Message_Iter *sub;
316

317
             user_itr = va_arg(*aq, Eldbus_Message_Iter **);
318
             sub = _message_iterator_new(EINA_TRUE);
319
             if (!sub)
320
               {
321
                  ERR("Could not create sub iterator");
322
                  r = EINA_FALSE;
323
                  goto next;
324
               }
325

326
             iter->iterators = eina_inlist_append(iter->iterators,
327
                                                  EINA_INLIST_GET(sub));
328

329
             if (type[0] == DBUS_TYPE_ARRAY)
330
               r = dbus_message_iter_open_container(&iter->dbus_iterator,
331
                                                    type[0], type+1,
332
                                                    &sub->dbus_iterator);
333
             else if (type[1] == DBUS_TYPE_VARIANT)
334
               {
335
                  ERR("variant not supported by \
336
                      eldbus_message_iter_arguments_append(), \
337
                      try eldbus_message_iter_container_new()");
338
                  r = EINA_FALSE;
339
                  goto next;
340
               }
341
             else
342
               {
343
                  char real_type;
344

345
                  if (type[0] == DBUS_STRUCT_BEGIN_CHAR)
346
                    real_type = DBUS_TYPE_STRUCT;
347
                  else real_type = DBUS_TYPE_DICT_ENTRY;
348
                  r = dbus_message_iter_open_container(&iter->dbus_iterator,
349
                                                       real_type, NULL,
350
                                                       &sub->dbus_iterator);
351
               }
352
             *user_itr = sub;
353
          }
354

355
next:
356
        dbus_free(type);
357
        if (!r || !dbus_signature_iter_next(&signature_iter))
358
          break;
359
     }
360

361
   return r;
362

363
}
364

365
EAPI Eina_Bool
366
eldbus_message_iter_arguments_vappend(Eldbus_Message_Iter *iter, const char *signature, va_list ap)
367
{
368
   va_list aq;
369
   Eina_Bool ret;
370

371
   va_copy(aq, ap);
372
   ret = _eldbus_message_iter_arguments_vappend(iter, signature, &aq);
373
   va_end(aq);
374

375
   return ret;
376
}
377

378
EAPI Eina_Bool
379
eldbus_message_iter_arguments_append(Eldbus_Message_Iter *iter, const char *signature, ...)
380
{
381
   Eina_Bool r;
382
   va_list ap;
383
   ELDBUS_MESSAGE_ITERATOR_CHECK_RETVAL(iter, EINA_FALSE);
384
   EINA_SAFETY_ON_NULL_RETURN_VAL(signature, EINA_FALSE);
385

386
   va_start(ap, signature);
387
   r = eldbus_message_iter_arguments_vappend(iter, signature, ap);
388
   va_end(ap);
389
   return r;
390
}
391

392
static Eina_Bool
393
append_basic(char type, va_list *vl, DBusMessageIter *iter)
394
{
395
   switch (type)
396
     {
397
      case DBUS_TYPE_BYTE:
398
        {
399
           uint32_t read_byte = va_arg(*vl, uint32_t);
400
           uint8_t byte = read_byte;
401
           return dbus_message_iter_append_basic(iter, type, &byte);
402
        }
403
      case DBUS_TYPE_INT16:
404
        {
405
           int32_t read_int16 = va_arg(*vl, int32_t);
406
           int16_t int16 = read_int16;
407
           return dbus_message_iter_append_basic(iter, type, &int16);
408
        }
409
      case DBUS_TYPE_UINT16:
410
        {
411
           uint32_t read_uint16 = va_arg(*vl, uint32_t);
412
           uint16_t uint16 = read_uint16;
413
           return dbus_message_iter_append_basic(iter, type, &uint16);
414
        }
415
      case DBUS_TYPE_BOOLEAN:
416
      case DBUS_TYPE_INT32:
417
#ifdef DBUS_TYPE_UNIX_FD
418
      case DBUS_TYPE_UNIX_FD:
419
#endif
420
        {
421
           int32_t int32 = va_arg(*vl, int32_t);
422
           return dbus_message_iter_append_basic(iter, type, &int32);
423
        }
424
      case DBUS_TYPE_UINT32:
425
        {
426
           uint32_t uint32 = va_arg(*vl, uint32_t);
427
           return dbus_message_iter_append_basic(iter, type, &uint32);
428
        }
429
      case DBUS_TYPE_INT64:
430
        {
431
           int64_t int64 = va_arg(*vl, int64_t);
432
           return dbus_message_iter_append_basic(iter, type, &int64);
433
        }
434
      case DBUS_TYPE_UINT64:
435
        {
436
           uint64_t uint64 = va_arg(*vl, uint64_t);
437
           return dbus_message_iter_append_basic(iter, type, &uint64);
438
        }
439
      case DBUS_TYPE_DOUBLE:
440
        {
441
           double double_ieee = va_arg(*vl, double);
442
           return dbus_message_iter_append_basic(iter, type, &double_ieee);
443
        }
444
      case DBUS_TYPE_STRING:
445
      case DBUS_TYPE_OBJECT_PATH:
446
      case DBUS_TYPE_SIGNATURE:
447
        {
448
           char *string = va_arg(*vl, char*);
449
           return dbus_message_iter_append_basic(iter, type, &string);
450
        }
451
      default:
452
         ERR("Type not handled %c", type);
453
         return EINA_FALSE;
454
     }
455
}
456

457
static Eina_Bool
458
_eldbus_message_arguments_vappend(Eldbus_Message *msg, const char *signature, va_list *aq)
459
{
460
   DBusSignatureIter signature_iter;
461
   Eldbus_Message_Iter *iter;
462
   int type;
463
   Eina_Bool r = EINA_TRUE;
464

465
   if (!signature[0]) return EINA_TRUE;
466
   EINA_SAFETY_ON_FALSE_RETURN_VAL(dbus_signature_validate(signature, NULL),
467
                                   EINA_FALSE);
468

469
   iter = eldbus_message_iter_get(msg);
470
   EINA_SAFETY_ON_NULL_RETURN_VAL(iter, EINA_FALSE);
471
   EINA_SAFETY_ON_FALSE_RETURN_VAL(iter->writable, EINA_FALSE);
472

473
   dbus_signature_iter_init(&signature_iter, signature);
474
   while ((type = dbus_signature_iter_get_current_type(&signature_iter)))
475
     {
476
        if (dbus_type_is_basic(type))
477
          r = append_basic(type, aq, &iter->dbus_iterator);
478
        else
479
          {
480
             ERR("sig = %s | eldbus_message_arguments_append() and \
481
                  eldbus_message_arguments_vappend() only support basic types, \
482
                  to complex types use eldbus_message_iter_* functions",
483
                  signature);
484
             r = EINA_FALSE;
485
          }
486

487
        if (!r || !dbus_signature_iter_next(&signature_iter))
488
          break;
489
     }
490

491
   return r;
492
}
493

494
EAPI Eina_Bool
495
eldbus_message_arguments_append(Eldbus_Message *msg, const char *signature, ...)
496
{
497
   Eina_Bool ret;
498
   va_list ap;
499

500
   ELDBUS_MESSAGE_CHECK_RETVAL(msg, EINA_FALSE);
501
   EINA_SAFETY_ON_NULL_RETURN_VAL(signature, EINA_FALSE);
502

503
   va_start(ap, signature);
504
   ret = _eldbus_message_arguments_vappend(msg, signature, &ap);
505
   va_end(ap);
506
   return ret;
507
}
508

509
EAPI Eina_Bool
510
eldbus_message_arguments_vappend(Eldbus_Message *msg, const char *signature, va_list ap)
511
{
512
   va_list aq;
513
   Eina_Bool ret;
514

515
   ELDBUS_MESSAGE_CHECK_RETVAL(msg, EINA_FALSE);
516
   EINA_SAFETY_ON_NULL_RETURN_VAL(signature, EINA_FALSE);
517

518
   va_copy(aq, ap);
519
   ret = _eldbus_message_arguments_vappend(msg, signature, &aq);
520
   va_end(aq);
521

522
   return ret;
523
}
524

525
EAPI Eldbus_Message_Iter *
526
eldbus_message_iter_container_new(Eldbus_Message_Iter *iter, int type, const char* contained_signature)
527
{
528
   Eldbus_Message_Iter *sub;
529

530
   ELDBUS_MESSAGE_ITERATOR_CHECK_RETVAL(iter, NULL);
531
   sub = _message_iterator_new(EINA_TRUE);
532
   EINA_SAFETY_ON_NULL_RETURN_VAL(sub, NULL);
533

534
   if (!dbus_message_iter_open_container(&iter->dbus_iterator, type,
535
                                         contained_signature,
536
                                         &sub->dbus_iterator))
537
     goto cleanup;
538

539
   iter->iterators = eina_inlist_append(iter->iterators, EINA_INLIST_GET(sub));
540
   return sub;
541

542
cleanup:
543
   free(sub);
544
   return NULL;
545
}
546

547
EAPI Eina_Bool
548
eldbus_message_iter_container_close(Eldbus_Message_Iter *iter, Eldbus_Message_Iter *sub)
549
{
550
   ELDBUS_MESSAGE_ITERATOR_CHECK_RETVAL(iter, EINA_FALSE);
551
   ELDBUS_MESSAGE_ITERATOR_CHECK_RETVAL(sub, EINA_FALSE);
552
   EINA_SAFETY_ON_FALSE_RETURN_VAL(iter->writable, EINA_FALSE);
553
   return dbus_message_iter_close_container(&iter->dbus_iterator,
554
                                            &sub->dbus_iterator);
555
}
556

557
EAPI Eina_Bool
558
eldbus_message_iter_basic_append(Eldbus_Message_Iter *iter, int type, ...)
559
{
560
   Eina_Bool r;
561
   va_list vl;
562
   ELDBUS_MESSAGE_ITERATOR_CHECK_RETVAL(iter, EINA_FALSE);
563
   EINA_SAFETY_ON_FALSE_RETURN_VAL(iter->writable, EINA_FALSE);
564

565
   va_start(vl, type);
566
   r = append_basic(type, &vl, &iter->dbus_iterator);
567
   va_end(vl);
568

569
   return r;
570
}
571

572
EAPI Eina_Bool
573
eldbus_message_iter_fixed_array_append(Eldbus_Message_Iter *iter, int type, const void *array, unsigned int size)
574
{
575
   ELDBUS_MESSAGE_ITERATOR_CHECK_RETVAL(iter, EINA_FALSE);
576
   EINA_SAFETY_ON_NULL_RETURN_VAL(array, EINA_FALSE);
577
   EINA_SAFETY_ON_FALSE_RETURN_VAL(iter->writable, EINA_FALSE);
578
   EINA_SAFETY_ON_FALSE_RETURN_VAL(dbus_type_is_basic(type), EINA_FALSE);
579
   return dbus_message_iter_append_fixed_array(&iter->dbus_iterator, type, &array, (int)size);
580
}
581

582
EAPI void
583
eldbus_message_iter_basic_get(Eldbus_Message_Iter *iter, void *value)
584
{
585
   ELDBUS_MESSAGE_ITERATOR_CHECK(iter);
586
   EINA_SAFETY_ON_TRUE_RETURN(iter->writable);
587
   dbus_message_iter_get_basic(&iter->dbus_iterator, value);
588
}
589

590
Eldbus_Message_Iter *
591
eldbus_message_iter_sub_iter_get(Eldbus_Message_Iter *iter)
592
{
593
   Eldbus_Message_Iter *sub;
594
   ELDBUS_MESSAGE_ITERATOR_CHECK_RETVAL(iter, NULL);
595
   EINA_SAFETY_ON_TRUE_RETURN_VAL(iter->writable, NULL);
596

597
   sub = _message_iterator_new(EINA_FALSE);
598
   dbus_message_iter_recurse(&iter->dbus_iterator, &sub->dbus_iterator);
599
   iter->iterators = eina_inlist_append(iter->iterators,
600
                                        EINA_INLIST_GET(sub));
601
   return sub;
602
}
603

604
EAPI char *
605
eldbus_message_iter_signature_get(Eldbus_Message_Iter *iter)
606
{
607
   ELDBUS_MESSAGE_ITERATOR_CHECK_RETVAL(iter, NULL);
608
   return dbus_message_iter_get_signature(&iter->dbus_iterator);
609
}
610

611
EAPI Eina_Bool
612
eldbus_message_iter_next(Eldbus_Message_Iter *iter)
613
{
614
   ELDBUS_MESSAGE_ITERATOR_CHECK_RETVAL(iter, EINA_FALSE);
615
   EINA_SAFETY_ON_TRUE_RETURN_VAL(iter->writable, EINA_FALSE);
616
   return dbus_message_iter_next(&iter->dbus_iterator);
617
}
618

619
static void
620
get_basic(char type, DBusMessageIter *iter, va_list *vl)
621
{
622
   DBusBasicValue val;
623

624
   switch (type)
625
     {
626
      case DBUS_TYPE_BYTE:
627
        {
628
           uint8_t *byte = va_arg(*vl, uint8_t *);
629
           dbus_message_iter_get_basic(iter, &val);
630
           *byte = val.bool_val;
631
           break;
632
        }
633
      case DBUS_TYPE_BOOLEAN:
634
        {
635
           Eina_Bool *boolean = va_arg(*vl, Eina_Bool *);
636
           dbus_message_iter_get_basic(iter, &val);
637
           *boolean = val.bool_val;
638
           break;
639
        }
640
      case DBUS_TYPE_INT16:
641
        {
642
           int16_t *int16 = va_arg(*vl, int16_t *);
643
           dbus_message_iter_get_basic(iter, &val);
644
           *int16 = val.i16;
645
           break;
646
        }
647
      case DBUS_TYPE_UINT16:
648
        {
649
           uint16_t *uint16 = va_arg(*vl, uint16_t *);
650
           dbus_message_iter_get_basic(iter, &val);
651
           *uint16 = val.u16;
652
           break;
653
        }
654
      case DBUS_TYPE_INT32:
655
#ifdef DBUS_TYPE_UNIX_FD
656
      case DBUS_TYPE_UNIX_FD:
657
#endif
658
        {
659
           int32_t *int32 = va_arg(*vl, int32_t *);
660
           dbus_message_iter_get_basic(iter, &val);
661
           *int32 = val.i32;
662
           break;
663
        }
664
      case DBUS_TYPE_UINT32:
665
        {
666
           uint32_t *uint32 = va_arg(*vl, uint32_t *);
667
           dbus_message_iter_get_basic(iter, &val);
668
           *uint32 = val.u32;
669
           break;
670
        }
671
      case DBUS_TYPE_INT64:
672
        {
673
           int64_t *int64 = va_arg(*vl, int64_t *);
674
           dbus_message_iter_get_basic(iter, &val);
675
           *int64 = val.i64;
676
           break;
677
        }
678
      case DBUS_TYPE_UINT64:
679
        {
680
           uint64_t *uint64 = va_arg(*vl, uint64_t *);
681
           dbus_message_iter_get_basic(iter, &val);
682
           *uint64 = val.u64;
683
           break;
684
        }
685
      case DBUS_TYPE_DOUBLE:
686
        {
687
           double *double_ieee = va_arg(*vl, double *);
688
           dbus_message_iter_get_basic(iter, &val);
689
           *double_ieee = val.dbl;
690
           break;
691
        }
692
      case DBUS_TYPE_STRING:
693
      case DBUS_TYPE_OBJECT_PATH:
694
      case DBUS_TYPE_SIGNATURE:
695
        {
696
           char **string = va_arg(*vl, char**);
697
           dbus_message_iter_get_basic(iter, &val);
698
           *string = val.str;
699
           break;
700
        }
701
      default:
702
        {
703
           ERR("Type not handled %c", type);
704
        }
705
     }
706
}
707

708
EAPI Eina_Bool
709
eldbus_message_iter_fixed_array_get(Eldbus_Message_Iter *iter, int signature, void *value, int *n_elements)
710
{
711
   int iter_type;
712

713
   ELDBUS_MESSAGE_ITERATOR_CHECK_RETVAL(iter, EINA_FALSE);
714
   EINA_SAFETY_ON_TRUE_RETURN_VAL(iter->writable, EINA_FALSE);
715
   EINA_SAFETY_ON_NULL_RETURN_VAL(n_elements, EINA_FALSE);
716

717
   iter_type = dbus_message_iter_get_arg_type(&iter->dbus_iterator);
718

719
   if (iter_type == DBUS_TYPE_INVALID)
720
     {
721
        *n_elements = 0;
722
        return EINA_TRUE;
723
     }
724

725
   EINA_SAFETY_ON_FALSE_RETURN_VAL(
726
        (dbus_message_iter_get_arg_type(&iter->dbus_iterator) == signature),
727
        EINA_FALSE);
728
   dbus_message_iter_get_fixed_array(&iter->dbus_iterator, value, n_elements);
729
   return EINA_TRUE;
730
}
731

732
/**
733
 * Useful when iterating over arrays
734
 */
735
EAPI Eina_Bool
736
eldbus_message_iter_get_and_next(Eldbus_Message_Iter *iter, char signature, ...)
737
{
738
   char type;
739
   va_list vl;
740

741
   ELDBUS_MESSAGE_ITERATOR_CHECK_RETVAL(iter, EINA_FALSE);
742
   EINA_SAFETY_ON_TRUE_RETURN_VAL(iter->writable, EINA_FALSE);
743
   va_start(vl, signature);
744

745
   type = dbus_message_iter_get_arg_type(&iter->dbus_iterator);
746
   if (type == DBUS_TYPE_INVALID)
747
     {
748
        va_end(vl);
749
        return EINA_FALSE;
750
     }
751
   if (type != signature)
752
     {
753
        if (signature == '(') signature = 'r';
754
        else if (signature == '{') signature = 'e';
755
        if (type != signature)
756
          {
757
             va_end(vl);
758
             return EINA_FALSE;
759
          }
760
     }
761

762
   if (dbus_type_is_basic(type))
763
     get_basic(type, &iter->dbus_iterator, &vl);
764
   else
765
     {
766
        Eldbus_Message_Iter *sub;
767
        Eldbus_Message_Iter **iter_var = va_arg(vl, Eldbus_Message_Iter**);
768

769
        sub = _message_iterator_new(EINA_FALSE);
770
        if (!sub)
771
          {
772
             va_end(vl);
773
             return EINA_FALSE;
774
          }
775
        dbus_message_iter_recurse(&iter->dbus_iterator,
776
                                  &sub->dbus_iterator);
777
        iter->iterators = eina_inlist_append(iter->iterators,
778
                                             EINA_INLIST_GET(sub));
779

780
        *iter_var = sub;
781
     }
782
   va_end(vl);
783

784
   dbus_message_iter_next(&iter->dbus_iterator);
785
   return EINA_TRUE;
786
}
787

788
static Eina_Bool
789
_eldbus_message_iter_arguments_vget(Eldbus_Message_Iter *iter, const char *signature, va_list *aq)
790
{
791
   int iter_type;
792
   DBusSignatureIter sig_iter;
793

794
   ELDBUS_MESSAGE_ITERATOR_CHECK_RETVAL(iter, EINA_FALSE);
795
   EINA_SAFETY_ON_TRUE_RETURN_VAL(iter->writable, EINA_FALSE);
796
   EINA_SAFETY_ON_NULL_RETURN_VAL(signature, EINA_FALSE);
797
   EINA_SAFETY_ON_FALSE_RETURN_VAL(dbus_signature_validate(signature, NULL), EINA_FALSE);
798

799
   dbus_signature_iter_init(&sig_iter, signature);
800
   iter_type = dbus_message_iter_get_arg_type(&iter->dbus_iterator);
801

802
   while (iter_type != DBUS_TYPE_INVALID)
803
     {
804
        int sig_type = dbus_signature_iter_get_current_type(&sig_iter);
805

806
        if (sig_type == DBUS_TYPE_INVALID)
807
          break;
808

809
        if (sig_type != iter_type)
810
          {
811
             ERR("Type in iterator different of signature expected:%c got %c", iter_type, sig_type);
812
             return EINA_FALSE;
813
          }
814

815
        if (dbus_type_is_basic(iter_type))
816
          get_basic(iter_type, &iter->dbus_iterator, aq);
817
        else
818
          {
819
             Eldbus_Message_Iter **user_itr = va_arg(*aq, Eldbus_Message_Iter **);
820
             Eldbus_Message_Iter *sub_itr;
821

822
             sub_itr = _message_iterator_new(EINA_FALSE);
823
             EINA_SAFETY_ON_NULL_RETURN_VAL(sub_itr, EINA_FALSE);
824
             dbus_message_iter_recurse(&iter->dbus_iterator,
825
                                       &sub_itr->dbus_iterator);
826
             iter->iterators = eina_inlist_append(iter->iterators,
827
                                                  EINA_INLIST_GET(sub_itr));
828
             *user_itr = sub_itr;
829
          }
830

831
        dbus_message_iter_next(&iter->dbus_iterator);
832
        if (!dbus_signature_iter_next(&sig_iter))
833
          break;
834
        iter_type = dbus_message_iter_get_arg_type(&iter->dbus_iterator);
835
     }
836

837
   return dbus_signature_iter_get_current_type(&sig_iter) == DBUS_TYPE_INVALID;
838

839
}
840

841
EAPI Eina_Bool
842
eldbus_message_iter_arguments_get(Eldbus_Message_Iter *iter, const char *signature, ...)
843
{
844
   va_list ap;
845
   Eina_Bool ret;
846

847
   va_start(ap, signature);
848
   ret = _eldbus_message_iter_arguments_vget(iter, signature, &ap);
849
   va_end(ap);
850

851
   return ret;
852
}
853

854
EAPI Eina_Bool
855
eldbus_message_iter_arguments_vget(Eldbus_Message_Iter *iter, const char *signature, va_list ap)
856
{
857
   va_list aq;
858
   Eina_Bool ret;
859

860
   va_copy(aq, ap);
861
   ret = _eldbus_message_iter_arguments_vget(iter, signature, &aq);
862
   va_end(aq);
863

864
   return ret;
865
}
866

867
EAPI void
868
eldbus_message_iter_del(Eldbus_Message_Iter *iter)
869
{
870
   ELDBUS_MESSAGE_ITERATOR_CHECK(iter);
871
   _message_iterator_free(iter);
872
}
873

874
EAPI Eldbus_Message *
875
eldbus_message_error_new(const Eldbus_Message *msg, const char *error_name, const char *error_msg)
876
{
877
   Eldbus_Message *reply;
878

879
   ELDBUS_MESSAGE_CHECK_RETVAL(msg, NULL);
880
   EINA_SAFETY_ON_NULL_RETURN_VAL(error_name, NULL);
881
   EINA_SAFETY_ON_NULL_RETURN_VAL(error_msg, NULL);
882

883
   reply = eldbus_message_new(EINA_FALSE);
884
   EINA_SAFETY_ON_NULL_RETURN_VAL(reply, NULL);
885

886
   reply->dbus_msg = dbus_message_new_error(msg->dbus_msg,
887
                                            error_name, error_msg);
888

889
   dbus_message_iter_init(reply->dbus_msg, &reply->iterator->dbus_iterator);
890

891
   return reply;
892
}
893

894
EAPI Eldbus_Message *
895
eldbus_message_method_return_new(const Eldbus_Message *msg)
896
{
897
   Eldbus_Message *reply;
898
   ELDBUS_MESSAGE_CHECK_RETVAL(msg, NULL);
899

900
   reply = eldbus_message_new(EINA_TRUE);
901
   EINA_SAFETY_ON_NULL_RETURN_VAL(reply, NULL);
902

903
   reply->dbus_msg = dbus_message_new_method_return(msg->dbus_msg);
904

905
   dbus_message_iter_init_append(reply->dbus_msg,
906
                                 &reply->iterator->dbus_iterator);
907

908
   return reply;
909
}
910

911
EAPI Eldbus_Message *
912
eldbus_message_signal_new(const char *path, const char *interface, const char *name)
913
{
914
   Eldbus_Message *msg;
915

916
   EINA_SAFETY_ON_NULL_RETURN_VAL(path, NULL);
917
   EINA_SAFETY_ON_NULL_RETURN_VAL(interface, NULL);
918
   EINA_SAFETY_ON_FALSE_RETURN_VAL(name, NULL);
919

920
   msg = eldbus_message_new(EINA_TRUE);
921
   EINA_SAFETY_ON_NULL_RETURN_VAL(msg, NULL);
922

923
   msg->dbus_msg = dbus_message_new_signal(path, interface, name);
924
   dbus_message_iter_init_append(msg->dbus_msg,
925
                                 &msg->iterator->dbus_iterator);
926

927
   return msg;
928
}
929

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.