efl

Форк
0
/
eldbus_message_to_eina_value.c 
467 строк · 12.8 Кб
1
#include "eldbus_private.h"
2
#include "eldbus_private_types.h"
3

4
static void _message_iter_basic_array_to_eina_value(char type, Eina_Value *value, Eldbus_Message_Iter *iter);
5

6
const Eina_Value_Type *
7
_dbus_type_to_eina_value_type(char type)
8
{
9
   switch (type)
10
     {
11
      case 'i':
12
      case 'h':
13
         return EINA_VALUE_TYPE_INT;
14
      case 's':
15
      case 'o':
16
      case 'g':
17
         return EINA_VALUE_TYPE_STRING;
18
      case 'b':
19
      case 'y':
20
         return EINA_VALUE_TYPE_UCHAR;
21
      case 'n':
22
         return EINA_VALUE_TYPE_SHORT;
23
      case 'q':
24
         return EINA_VALUE_TYPE_USHORT;
25
      case 'u':
26
         return EINA_VALUE_TYPE_UINT;
27
      case 'x':
28
         return EINA_VALUE_TYPE_INT64;
29
      case 't':
30
         return EINA_VALUE_TYPE_UINT64;
31
      case 'd':
32
         return EINA_VALUE_TYPE_DOUBLE;
33
      case 'a':
34
         return EINA_VALUE_TYPE_ARRAY;
35
      case '(':
36
      case '{':
37
      case 'e':
38
      case 'r':
39
      case 'v':
40
         return EINA_VALUE_TYPE_STRUCT;
41
      default:
42
         ERR("Unknown type %c", type);
43
         return NULL;
44
     }
45
}
46

47
static unsigned int
48
_type_size(char type)
49
{
50
   switch (type)
51
     {
52
      case 'i':
53
      case 'h':
54
      case 'u':
55
         return(sizeof(int32_t));
56
      case 's':
57
      case 'o':
58
      case 'g':
59
         return(sizeof(char *));
60
      case 'b':
61
      case 'y':
62
         return(sizeof(unsigned char));
63
      case 'n':
64
      case 'q':
65
         return(sizeof(int16_t));
66
      case 'x':
67
      case 't':
68
         return(sizeof(int64_t));
69
      case 'd':
70
         return(sizeof(double));
71
      case 'a':
72
         return(sizeof(Eina_Value_Array));
73
      case '(':
74
      case '{':
75
      case 'e':
76
      case 'r':
77
      case 'v':
78
         return(sizeof(Eina_Value_Struct));
79
      default:
80
         ERR("Unknown type %c", type);
81
         return 0;
82
     }
83
}
84

85
static unsigned int
86
_type_offset(char type, unsigned base)
87
{
88
   unsigned size, padding;
89
   size = _type_size(type);
90
   if (size == 0)
91
     return base;
92
   if (!(base % size))
93
     return base;
94
   padding = (base > size) ? base - size : size - base;
95
   return base + padding;
96
}
97

98
static Eina_Value *
99
_message_iter_array_to_eina_value(Eldbus_Message_Iter *iter)
100
{
101
   Eina_Value *array_value;
102
   char *sig;
103

104
   sig = eldbus_message_iter_signature_get(iter);
105
   DBG("array of %s", sig);
106
   array_value = eina_value_array_new(_dbus_type_to_eina_value_type(sig[0]), 0);
107
   if (sig[0] == '(' || sig[0] == '{' || sig[0] == 'v')
108
     {
109
        Eldbus_Message_Iter *entry;
110

111
        if (sig[0] == '{')
112
          sig[0] = 'e';
113
        else if (sig[0] == '(')
114
          sig[0] = 'r';
115

116
        while (eldbus_message_iter_get_and_next(iter, sig[0], &entry))
117
          {
118
             Eina_Value *data = _message_iter_struct_to_eina_value(entry);
119
             Eina_Value_Struct st;
120
             eina_value_get(data, &st);
121
             eina_value_array_append(array_value, st);
122
             eina_value_free(data);
123
          }
124
     }
125
   else if (sig[0] == 'a')
126
     {
127
        Eldbus_Message_Iter *entry;
128
        while (eldbus_message_iter_get_and_next(iter, sig[0], &entry))
129
          {
130
             Eina_Value *data = _message_iter_array_to_eina_value(entry);
131
             Eina_Value_Array inner_array;
132
             eina_value_get(data, &inner_array);
133
             eina_value_array_append(array_value, inner_array);
134
             eina_value_free(data);
135
          }
136
     }
137
   else
138
     _message_iter_basic_array_to_eina_value(sig[0], array_value, iter);
139

140
   DBG("return array of %s", sig);
141
   free(sig);
142
   return array_value;
143
}
144

145
static void
146
_message_iter_basic_array_to_eina_value(char type, Eina_Value *value, Eldbus_Message_Iter *iter)
147
{
148
   switch (type)
149
    {
150
       case 'i':
151
       case 'h'://fd
152
         {
153
            int32_t i;
154
            while (eldbus_message_iter_get_and_next(iter, type, &i))
155
              eina_value_array_append(value, i);
156
            break;
157
         }
158
       case 's':
159
       case 'o'://object path
160
       case 'g'://signature
161
         {
162
            const char *txt;
163
            while (eldbus_message_iter_get_and_next(iter, type, &txt))
164
              eina_value_array_append(value, txt);
165
            break;
166
         }
167
       case 'y'://byte
168
         {
169
            unsigned char byte;
170
            while (eldbus_message_iter_get_and_next(iter, type, &byte))
171
              eina_value_array_append(value, byte);
172
            break;
173
         }
174
       case 'b'://boolean
175
         {
176
            uint32_t boolean;
177
            while (eldbus_message_iter_get_and_next(iter, type, &boolean))
178
              eina_value_array_append(value, (uint8_t)boolean);
179
            break;
180
         }
181
       case 'n'://int16
182
         {
183
            int16_t i;
184
            while (eldbus_message_iter_get_and_next(iter, type, &i))
185
              eina_value_array_append(value, i);
186
            break;
187
         }
188
       case 'q'://uint16
189
         {
190
            uint16_t i;
191
            while (eldbus_message_iter_get_and_next(iter, type, &i))
192
              eina_value_array_append(value, i);
193
            break;
194
         }
195
       case 'u'://uint32
196
         {
197
            uint32_t i;
198
            while (eldbus_message_iter_get_and_next(iter, type, &i))
199
              eina_value_array_append(value, i);
200
            break;
201
         }
202
       case 'x'://int64
203
         {
204
            int64_t i;
205
            while (eldbus_message_iter_get_and_next(iter, type, &i))
206
              eina_value_array_append(value, i);
207
            break;
208
         }
209
       case 't'://uint64
210
         {
211
            uint64_t i;
212
            while (eldbus_message_iter_get_and_next(iter, type, &i))
213
              eina_value_array_append(value, i);
214
            break;
215
         }
216
       case 'd'://double
217
         {
218
            double d;
219
            while (eldbus_message_iter_get_and_next(iter, type, &d))
220
              eina_value_array_append(value, d);
221
            break;
222
         }
223
    }
224
}
225

226
#define ARG "arg%u"
227

228
typedef struct _Eldbus_Struct_Desc
229
{
230
   Eina_Value_Struct_Desc base;
231
   int refcount;
232
} Eldbus_Struct_Desc;
233

234
static void *
235
_ops_malloc(const Eina_Value_Struct_Operations *ops EINA_UNUSED, const Eina_Value_Struct_Desc *desc)
236
{
237
   Eldbus_Struct_Desc *edesc = (Eldbus_Struct_Desc*)desc;
238
   edesc->refcount++;
239
   DBG("%p refcount=%d", edesc, edesc->refcount);
240
   return malloc(desc->size);
241
}
242

243
static void
244
_ops_free(const Eina_Value_Struct_Operations *ops EINA_UNUSED, const Eina_Value_Struct_Desc *desc, void *memory)
245
{
246
   Eldbus_Struct_Desc *edesc = (Eldbus_Struct_Desc*) desc;
247
   edesc->refcount--;
248
   free(memory);
249
   DBG("%p refcount=%d", edesc, edesc->refcount);
250
   if (edesc->refcount <= 0)
251
     {
252
        unsigned i;
253
        for (i = 0; i < edesc->base.member_count; i++)
254
          free((char *)edesc->base.members[i].name);
255
        free((Eina_Value_Struct_Member *)edesc->base.members);
256
        free(edesc);
257
     }
258
}
259

260
static Eina_Value_Struct_Operations operations =
261
{
262
   EINA_VALUE_STRUCT_OPERATIONS_VERSION,
263
   _ops_malloc,
264
   _ops_free,
265
   NULL,
266
   NULL,
267
   NULL
268
};
269

270
Eina_Value *
271
_message_iter_struct_to_eina_value(Eldbus_Message_Iter *iter)
272
{
273
   int type;
274
   Eina_Value *value_st = NULL;
275
   Eina_Array *st_members = eina_array_new(1);
276
   unsigned int offset = 0, z;
277
   char name[16];//arg000 + \0
278
   Eina_Value_Struct_Member *members;
279
   Eldbus_Struct_Desc *st_desc;
280
   Eina_Array *st_values = eina_array_new(1);
281

282
   DBG("begin struct");
283
   st_desc = calloc(1, sizeof(Eldbus_Struct_Desc));
284
   st_desc->base.version = EINA_VALUE_STRUCT_DESC_VERSION;
285
   st_desc->base.ops = &operations;
286

287
   //create member list
288
   z = 0;
289
   while ((type = dbus_message_iter_get_arg_type(&iter->dbus_iterator)) != DBUS_TYPE_INVALID)
290
     {
291
        Eina_Value_Struct_Member *m;
292
        Eina_Value *v;
293

294
        m = calloc(1, sizeof(Eina_Value_Struct_Member));
295
        snprintf(name, 7, ARG, z);
296
        m->name = strdup(name);
297
        offset = _type_offset(type, offset);
298
        m->offset = offset;
299
        offset += _type_size(type);
300
        m->type = _dbus_type_to_eina_value_type(type);
301
        eina_array_push(st_members, m);
302

303
        DBG("type = %c", type);
304
        switch (type)
305
          {
306
           case 'i'://int
307
           case 'h'://fd
308
             {
309
                int32_t i;
310
                v = eina_value_new(EINA_VALUE_TYPE_INT);
311
                eldbus_message_iter_basic_get(iter, &i);
312
                eina_value_set(v, i);
313
                break;
314
             }
315
           case 's':
316
           case 'o'://object path
317
           case 'g'://signature
318
             {
319
                const char *txt;
320
                v = eina_value_new(EINA_VALUE_TYPE_STRING);
321
                eldbus_message_iter_basic_get(iter, &txt);
322
                eina_value_set(v, txt);
323
                break;
324
             }
325
           case 'y'://byte
326
             {
327
                unsigned char byte;
328
                v = eina_value_new(EINA_VALUE_TYPE_UCHAR);
329
                eldbus_message_iter_basic_get(iter, &byte);
330
                eina_value_set(v, byte);
331
                break;
332
             }
333
           case 'b'://boolean
334
             {
335
                 uint32_t value;
336
                 v = eina_value_new(EINA_VALUE_TYPE_UCHAR);
337
                 eldbus_message_iter_basic_get(iter, &value);
338
                 eina_value_set(v, (uint8_t)value);
339
                 break;
340
             }
341
           case 'n'://int16
342
             {
343
                int16_t i;
344
                v = eina_value_new(EINA_VALUE_TYPE_SHORT);
345
                eldbus_message_iter_basic_get(iter, &i);
346
                eina_value_set(v, i);
347
                break;
348
             }
349
           case 'q'://uint16
350
             {
351
                uint16_t i;
352
                v = eina_value_new(EINA_VALUE_TYPE_USHORT);
353
                eldbus_message_iter_basic_get(iter, &i);
354
                eina_value_set(v, i);
355
                break;
356
             }
357
           case 'u'://uint32
358
             {
359
                uint32_t i;
360
                v = eina_value_new(EINA_VALUE_TYPE_UINT);
361
                eldbus_message_iter_basic_get(iter, &i);
362
                eina_value_set(v, i);
363
                break;
364
             }
365
           case 'x'://int64
366
             {
367
                int64_t i;
368
                v = eina_value_new(EINA_VALUE_TYPE_INT64);
369
                eldbus_message_iter_basic_get(iter, &i);
370
                eina_value_set(v, i);
371
                break;
372
             }
373
           case 't'://uint64
374
             {
375
                uint64_t i;
376
                v = eina_value_new(EINA_VALUE_TYPE_UINT64);
377
                eldbus_message_iter_basic_get(iter, &i);
378
                eina_value_set(v, i);
379
                break;
380
             }
381
           case 'd'://double
382
             {
383
                double d;
384
                v = eina_value_new(EINA_VALUE_TYPE_DOUBLE);
385
                eldbus_message_iter_basic_get(iter, &d);
386
                eina_value_set(v, d);
387
                break;
388
             }
389
           case 'a'://array
390
             {
391
                Eldbus_Message_Iter *dbus_array;
392
                dbus_array = eldbus_message_iter_sub_iter_get(iter);
393
                v = _message_iter_array_to_eina_value(dbus_array);
394
                break;
395
             }
396
           case '('://struct
397
           case 'r'://struct
398
           case 'v'://variant
399
             {
400
                Eldbus_Message_Iter *dbus_st;
401
                dbus_st = eldbus_message_iter_sub_iter_get(iter);
402
                v = _message_iter_struct_to_eina_value(dbus_st);
403
                break;
404
             }
405
           default:
406
             ERR("Unexpected type %c", type);
407
             v = NULL;
408
          }
409
        eina_array_push(st_values, v);
410
        eldbus_message_iter_next(iter);
411
        z++;
412
     }
413

414
   if (!z)
415
     {
416
        free(st_desc);
417
        goto end;
418
     }
419

420
   members = malloc(eina_array_count(st_members) * sizeof(Eina_Value_Struct_Member));
421
   for (z = 0; z < eina_array_count(st_members); z++)
422
     {
423
        Eina_Value_Struct_Member *m = eina_array_data_get(st_members, z);
424
        members[z].name = m->name;
425
        members[z].offset = m->offset;
426
        members[z].type = m->type;
427
        free(m);
428
     }
429

430
   //setup
431
   st_desc->base.members = members;
432
   st_desc->base.member_count = eina_array_count(st_members);
433
   st_desc->base.size = offset;
434
   value_st = eina_value_struct_new((Eina_Value_Struct_Desc *)st_desc);
435

436
   //filling with data
437
   for (z = 0; z < eina_array_count(st_values); z++)
438
     {
439
        Eina_Value *v = eina_array_data_get(st_values, z);
440
        sprintf(name, ARG, z);
441
        eina_value_struct_value_set(value_st, name, v);
442
        eina_value_free(v);
443
     }
444

445
end:
446
   eina_array_free(st_members);
447
   eina_array_free(st_values);
448
   DBG("end struct");
449
   return value_st;
450
}
451

452
EAPI Eina_Value *
453
eldbus_message_to_eina_value(const Eldbus_Message *msg)
454
{
455
   Eldbus_Message_Iter *iter;
456
   EINA_SAFETY_ON_FALSE_RETURN_VAL(msg, NULL);
457
   iter = eldbus_message_iter_get(msg);
458
   EINA_SAFETY_ON_NULL_RETURN_VAL(iter, NULL);
459
   return _message_iter_struct_to_eina_value(iter);
460
}
461

462
EAPI Eina_Value *
463
eldbus_message_iter_struct_like_to_eina_value(const Eldbus_Message_Iter *iter)
464
{
465
   EINA_SAFETY_ON_NULL_RETURN_VAL(iter, NULL);
466
   return _message_iter_struct_to_eina_value((Eldbus_Message_Iter *)iter);
467
}
468

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

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

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

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