~ubuntu-branches/ubuntu/wily/bluez/wily

« back to all changes in this revision

Viewing changes to common/sdp-xml.c

ImportĀ upstreamĀ versionĀ 4.81

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 *
3
 
 *  BlueZ - Bluetooth protocol stack for Linux
4
 
 *
5
 
 *  Copyright (C) 2005-2009  Marcel Holtmann <marcel@holtmann.org>
6
 
 *
7
 
 *
8
 
 *  This program is free software; you can redistribute it and/or modify
9
 
 *  it under the terms of the GNU General Public License as published by
10
 
 *  the Free Software Foundation; either version 2 of the License, or
11
 
 *  (at your option) any later version.
12
 
 *
13
 
 *  This program is distributed in the hope that it will be useful,
14
 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 
 *  GNU General Public License for more details.
17
 
 *
18
 
 *  You should have received a copy of the GNU General Public License
19
 
 *  along with this program; if not, write to the Free Software
20
 
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
21
 
 *
22
 
 */
23
 
 
24
 
#ifdef HAVE_CONFIG_H
25
 
#include <config.h>
26
 
#endif
27
 
 
28
 
#define _GNU_SOURCE
29
 
#include <stdio.h>
30
 
#include <errno.h>
31
 
#include <ctype.h>
32
 
#include <string.h>
33
 
#include <limits.h>
34
 
#include <stdlib.h>
35
 
 
36
 
#include <bluetooth/sdp.h>
37
 
#include <bluetooth/sdp_lib.h>
38
 
 
39
 
#include "logging.h"
40
 
#include "sdp-xml.h"
41
 
 
42
 
#define STRBUFSIZE 1024
43
 
#define MAXINDENT 64
44
 
 
45
 
static void convert_raw_data_to_xml(sdp_data_t *value, int indent_level,
46
 
                void *data, void (*appender)(void *, const char *))
47
 
{
48
 
        int i, hex;
49
 
        char buf[STRBUFSIZE];
50
 
        char indent[MAXINDENT];
51
 
        char next_indent[MAXINDENT];
52
 
 
53
 
        if (!value)
54
 
                return;
55
 
 
56
 
        if (indent_level >= MAXINDENT)
57
 
                indent_level = MAXINDENT - 2;
58
 
 
59
 
        for (i = 0; i < indent_level; i++) {
60
 
                indent[i] = '\t';
61
 
                next_indent[i] = '\t';
62
 
        }
63
 
 
64
 
        indent[i] = '\0';
65
 
        next_indent[i] = '\t';
66
 
        next_indent[i + 1] = '\0';
67
 
 
68
 
        buf[STRBUFSIZE - 1] = '\0';
69
 
 
70
 
        switch (value->dtd) {
71
 
        case SDP_DATA_NIL:
72
 
                appender(data, indent);
73
 
                appender(data, "<nil/>\n");
74
 
                break;
75
 
 
76
 
        case SDP_BOOL:
77
 
                appender(data, indent);
78
 
                appender(data, "<boolean value=\"");
79
 
                appender(data, value->val.uint8 ? "true" : "false");
80
 
                appender(data, "\" />\n");
81
 
                break;
82
 
 
83
 
        case SDP_UINT8:
84
 
                appender(data, indent);
85
 
                appender(data, "<uint8 value=\"");
86
 
                snprintf(buf, STRBUFSIZE - 1, "0x%02x", value->val.uint8);
87
 
                appender(data, buf);
88
 
                appender(data, "\" />\n");
89
 
                break;
90
 
 
91
 
        case SDP_UINT16:
92
 
                appender(data, indent);
93
 
                appender(data, "<uint16 value=\"");
94
 
                snprintf(buf, STRBUFSIZE - 1, "0x%04x", value->val.uint16);
95
 
                appender(data, buf);
96
 
                appender(data, "\" />\n");
97
 
                break;
98
 
 
99
 
        case SDP_UINT32:
100
 
                appender(data, indent);
101
 
                appender(data, "<uint32 value=\"");
102
 
                snprintf(buf, STRBUFSIZE - 1, "0x%08x", value->val.uint32);
103
 
                appender(data, buf);
104
 
                appender(data, "\" />\n");
105
 
                break;
106
 
 
107
 
        case SDP_UINT64:
108
 
                appender(data, indent);
109
 
                appender(data, "<uint64 value=\"");
110
 
                snprintf(buf, STRBUFSIZE - 1, "0x%016jx", value->val.uint64);
111
 
                appender(data, buf);
112
 
                appender(data, "\" />\n");
113
 
                break;
114
 
 
115
 
        case SDP_UINT128:
116
 
                appender(data, indent);
117
 
                appender(data, "<uint128 value=\"");
118
 
 
119
 
                for (i = 0; i < 16; i++) {
120
 
                        sprintf(&buf[i * 2], "%02x",
121
 
                                (unsigned char) value->val.uint128.data[i]);
122
 
                }
123
 
 
124
 
                appender(data, buf);
125
 
                appender(data, "\" />\n");
126
 
                break;
127
 
 
128
 
        case SDP_INT8:
129
 
                appender(data, indent);
130
 
                appender(data, "<int8 value=\"");
131
 
                snprintf(buf, STRBUFSIZE - 1, "%d", value->val.int8);
132
 
                appender(data, buf);
133
 
                appender(data, "\" />\n");
134
 
                break;
135
 
 
136
 
        case SDP_INT16:
137
 
                appender(data, indent);
138
 
                appender(data, "<int16 value=\"");
139
 
                snprintf(buf, STRBUFSIZE - 1, "%d", value->val.int16);
140
 
                appender(data, buf);
141
 
                appender(data, "\" />\n");
142
 
                break;
143
 
 
144
 
        case SDP_INT32:
145
 
                appender(data, indent);
146
 
                appender(data, "<int32 value=\"");
147
 
                snprintf(buf, STRBUFSIZE - 1, "%d", value->val.int32);
148
 
                appender(data, buf);
149
 
                appender(data, "\" />\n");
150
 
                break;
151
 
 
152
 
        case SDP_INT64:
153
 
                appender(data, indent);
154
 
                appender(data, "<int64 value=\"");
155
 
                snprintf(buf, STRBUFSIZE - 1, "%jd", value->val.int64);
156
 
                appender(data, buf);
157
 
                appender(data, "\" />\n");
158
 
                break;
159
 
 
160
 
        case SDP_INT128:
161
 
                appender(data, indent);
162
 
                appender(data, "<int128 value=\"");
163
 
 
164
 
                for (i = 0; i < 16; i++) {
165
 
                        sprintf(&buf[i * 2], "%02x",
166
 
                                (unsigned char) value->val.int128.data[i]);
167
 
                }
168
 
                appender(data, buf);
169
 
 
170
 
                appender(data, "\" />\n");
171
 
                break;
172
 
 
173
 
        case SDP_UUID16:
174
 
                appender(data, indent);
175
 
                appender(data, "<uuid value=\"");
176
 
                snprintf(buf, STRBUFSIZE - 1, "0x%04x", value->val.uuid.value.uuid16);
177
 
                appender(data, buf);
178
 
                appender(data, "\" />\n");
179
 
                break;
180
 
 
181
 
        case SDP_UUID32:
182
 
                appender(data, indent);
183
 
                appender(data, "<uuid value=\"");
184
 
                snprintf(buf, STRBUFSIZE - 1, "0x%08x", value->val.uuid.value.uuid32);
185
 
                appender(data, buf);
186
 
                appender(data, "\" />\n");
187
 
                break;
188
 
 
189
 
        case SDP_UUID128:
190
 
                appender(data, indent);
191
 
                appender(data, "<uuid value=\"");
192
 
 
193
 
                snprintf(buf, STRBUFSIZE - 1,
194
 
                         "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
195
 
                         (unsigned char) value->val.uuid.value.
196
 
                         uuid128.data[0],
197
 
                         (unsigned char) value->val.uuid.value.
198
 
                         uuid128.data[1],
199
 
                         (unsigned char) value->val.uuid.value.
200
 
                         uuid128.data[2],
201
 
                         (unsigned char) value->val.uuid.value.
202
 
                         uuid128.data[3],
203
 
                         (unsigned char) value->val.uuid.value.
204
 
                         uuid128.data[4],
205
 
                         (unsigned char) value->val.uuid.value.
206
 
                         uuid128.data[5],
207
 
                         (unsigned char) value->val.uuid.value.
208
 
                         uuid128.data[6],
209
 
                         (unsigned char) value->val.uuid.value.
210
 
                         uuid128.data[7],
211
 
                         (unsigned char) value->val.uuid.value.
212
 
                         uuid128.data[8],
213
 
                         (unsigned char) value->val.uuid.value.
214
 
                         uuid128.data[9],
215
 
                         (unsigned char) value->val.uuid.value.
216
 
                         uuid128.data[10],
217
 
                         (unsigned char) value->val.uuid.value.
218
 
                         uuid128.data[11],
219
 
                         (unsigned char) value->val.uuid.value.
220
 
                         uuid128.data[12],
221
 
                         (unsigned char) value->val.uuid.value.
222
 
                         uuid128.data[13],
223
 
                         (unsigned char) value->val.uuid.value.
224
 
                         uuid128.data[14],
225
 
                         (unsigned char) value->val.uuid.value.
226
 
                         uuid128.data[15]);
227
 
 
228
 
                appender(data, buf);
229
 
                appender(data, "\" />\n");
230
 
                break;
231
 
 
232
 
        case SDP_TEXT_STR8:
233
 
        case SDP_TEXT_STR16:
234
 
        case SDP_TEXT_STR32:
235
 
        {
236
 
                int num_chars_to_escape = 0;
237
 
                int length = value->unitSize - 1;
238
 
                char *strBuf = 0;
239
 
 
240
 
                hex = 0;
241
 
 
242
 
                for (i = 0; i < length; i++) {
243
 
                        if (!isprint(value->val.str[i]) &&
244
 
                                        value->val.str[i] != '\0') {
245
 
                                hex = 1;
246
 
                                break;
247
 
                        }
248
 
 
249
 
                        /* XML is evil, must do this... */
250
 
                        if ((value->val.str[i] == '<') ||
251
 
                                        (value->val.str[i] == '>') ||
252
 
                                        (value->val.str[i] == '"') ||
253
 
                                        (value->val.str[i] == '&'))
254
 
                                num_chars_to_escape++;
255
 
                }
256
 
 
257
 
                appender(data, indent);
258
 
 
259
 
                appender(data, "<text ");
260
 
 
261
 
                if (hex) {
262
 
                        appender(data, "encoding=\"hex\" ");
263
 
                        strBuf = (char *) malloc(sizeof(char)
264
 
                                                 * ((value->unitSize-1) * 2 + 1));
265
 
 
266
 
                        /* Unit Size seems to include the size for dtd
267
 
                           It is thus off by 1
268
 
                           This is safe for Normal strings, but not
269
 
                           hex encoded data */
270
 
                        for (i = 0; i < (value->unitSize-1); i++)
271
 
                                sprintf(&strBuf[i*sizeof(char)*2],
272
 
                                        "%02x",
273
 
                                        (unsigned char) value->val.str[i]);
274
 
 
275
 
                        strBuf[(value->unitSize-1) * 2] = '\0';
276
 
                }
277
 
                else {
278
 
                        int j;
279
 
                        /* escape the XML disallowed chars */
280
 
                        strBuf = (char *)
281
 
                                malloc(sizeof(char) *
282
 
                                (value->unitSize + 1 + num_chars_to_escape * 4));
283
 
                        for (i = 0, j = 0; i < length; i++) {
284
 
                                if (value->val.str[i] == '&') {
285
 
                                        strBuf[j++] = '&';
286
 
                                        strBuf[j++] = 'a';
287
 
                                        strBuf[j++] = 'm';
288
 
                                        strBuf[j++] = 'p';
289
 
                                }
290
 
                                else if (value->val.str[i] == '<') {
291
 
                                        strBuf[j++] = '&';
292
 
                                        strBuf[j++] = 'l';
293
 
                                        strBuf[j++] = 't';
294
 
                                }
295
 
                                else if (value->val.str[i] == '>') {
296
 
                                        strBuf[j++] = '&';
297
 
                                        strBuf[j++] = 'g';
298
 
                                        strBuf[j++] = 't';
299
 
                                }
300
 
                                else if (value->val.str[i] == '"') {
301
 
                                        strBuf[j++] = '&';
302
 
                                        strBuf[j++] = 'q';
303
 
                                        strBuf[j++] = 'u';
304
 
                                        strBuf[j++] = 'o';
305
 
                                        strBuf[j++] = 't';
306
 
                                }
307
 
                                else if (value->val.str[i] == '\0') {
308
 
                                        strBuf[j++] = ' ';
309
 
                                } else {
310
 
                                        strBuf[j++] = value->val.str[i];
311
 
                                }
312
 
                        }
313
 
 
314
 
                        strBuf[j] = '\0';
315
 
                }
316
 
 
317
 
                appender(data, "value=\"");
318
 
                appender(data, strBuf);
319
 
                appender(data, "\" />\n");
320
 
                free(strBuf);
321
 
                break;
322
 
        }
323
 
 
324
 
        case SDP_URL_STR8:
325
 
        case SDP_URL_STR16:
326
 
        case SDP_URL_STR32:
327
 
        {
328
 
                char *strBuf;
329
 
 
330
 
                appender(data, indent);
331
 
                appender(data, "<url value=\"");
332
 
                strBuf = strndup(value->val.str, value->unitSize - 1);
333
 
                appender(data, strBuf);
334
 
                free(strBuf);
335
 
                appender(data, "\" />\n");
336
 
                break;
337
 
        }
338
 
 
339
 
        case SDP_SEQ8:
340
 
        case SDP_SEQ16:
341
 
        case SDP_SEQ32:
342
 
                appender(data, indent);
343
 
                appender(data, "<sequence>\n");
344
 
 
345
 
                convert_raw_data_to_xml(value->val.dataseq,
346
 
                                        indent_level + 1, data, appender);
347
 
 
348
 
                appender(data, indent);
349
 
                appender(data, "</sequence>\n");
350
 
 
351
 
                break;
352
 
 
353
 
        case SDP_ALT8:
354
 
        case SDP_ALT16:
355
 
        case SDP_ALT32:
356
 
                appender(data, indent);
357
 
 
358
 
                appender(data, "<alternate>\n");
359
 
 
360
 
                convert_raw_data_to_xml(value->val.dataseq,
361
 
                                        indent_level + 1, data, appender);
362
 
                appender(data, indent);
363
 
 
364
 
                appender(data, "</alternate>\n");
365
 
 
366
 
                break;
367
 
        }
368
 
 
369
 
        convert_raw_data_to_xml(value->next, indent_level, data, appender);
370
 
}
371
 
 
372
 
struct conversion_data {
373
 
        void *data;
374
 
        void (*appender)(void *data, const char *);
375
 
};
376
 
 
377
 
static void convert_raw_attr_to_xml_func(void *val, void *data)
378
 
{
379
 
        struct conversion_data *cd = (struct conversion_data *) data;
380
 
        sdp_data_t *value = (sdp_data_t *) val;
381
 
        char buf[STRBUFSIZE];
382
 
 
383
 
        buf[STRBUFSIZE - 1] = '\0';
384
 
        snprintf(buf, STRBUFSIZE - 1, "\t<attribute id=\"0x%04x\">\n",
385
 
                 value->attrId);
386
 
        cd->appender(cd->data, buf);
387
 
 
388
 
        if (data)
389
 
                convert_raw_data_to_xml(value, 2, cd->data, cd->appender);
390
 
        else
391
 
                cd->appender(cd->data, "\t\tNULL\n");
392
 
 
393
 
        cd->appender(cd->data, "\t</attribute>\n");
394
 
}
395
 
 
396
 
/*
397
 
 * Will convert the sdp record to XML.  The appender and data can be used
398
 
 * to control where to output the record (e.g. file or a data buffer).  The
399
 
 * appender will be called repeatedly with data and the character buffer
400
 
 * (containing parts of the generated XML) to append.
401
 
 */
402
 
void convert_sdp_record_to_xml(sdp_record_t *rec,
403
 
                        void *data, void (*appender)(void *, const char *))
404
 
{
405
 
        struct conversion_data cd;
406
 
 
407
 
        cd.data = data;
408
 
        cd.appender = appender;
409
 
 
410
 
        if (rec && rec->attrlist) {
411
 
                appender(data, "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n\n");
412
 
                appender(data, "<record>\n");
413
 
                sdp_list_foreach(rec->attrlist,
414
 
                                 convert_raw_attr_to_xml_func, &cd);
415
 
                appender(data, "</record>\n");
416
 
        }
417
 
}
418
 
 
419
 
static sdp_data_t *sdp_xml_parse_uuid128(const char *data)
420
 
{
421
 
        uint128_t val;
422
 
        unsigned int i, j;
423
 
 
424
 
        char buf[3];
425
 
 
426
 
        memset(&val, 0, sizeof(val));
427
 
 
428
 
        buf[2] = '\0';
429
 
 
430
 
        for (j = 0, i = 0; i < strlen(data);) {
431
 
                if (data[i] == '-') {
432
 
                        i++;
433
 
                        continue;
434
 
                }
435
 
 
436
 
                buf[0] = data[i];
437
 
                buf[1] = data[i + 1];
438
 
 
439
 
                val.data[j++] = strtoul(buf, 0, 16);
440
 
                i += 2;
441
 
        }
442
 
 
443
 
        return sdp_data_alloc(SDP_UUID128, &val);
444
 
}
445
 
 
446
 
sdp_data_t *sdp_xml_parse_uuid(const char *data, sdp_record_t *record)
447
 
{
448
 
        sdp_data_t *ret;
449
 
        char *endptr;
450
 
        uint32_t val;
451
 
        uint16_t val2;
452
 
        int len;
453
 
 
454
 
        len = strlen(data);
455
 
 
456
 
        if (len == 36) {
457
 
                ret = sdp_xml_parse_uuid128(data);
458
 
                goto result;
459
 
        }
460
 
 
461
 
        val = strtoll(data, &endptr, 16);
462
 
 
463
 
        /* Couldn't parse */
464
 
        if (*endptr != '\0')
465
 
                return NULL;
466
 
 
467
 
        if (val > USHRT_MAX) {
468
 
                ret = sdp_data_alloc(SDP_UUID32, &val);
469
 
                goto result;
470
 
        }
471
 
 
472
 
        val2 = val;
473
 
 
474
 
        ret = sdp_data_alloc(SDP_UUID16, &val2);
475
 
 
476
 
result:
477
 
        if (record && ret)
478
 
                sdp_pattern_add_uuid(record, &ret->val.uuid);
479
 
 
480
 
        return ret;
481
 
}
482
 
 
483
 
sdp_data_t *sdp_xml_parse_int(const char * data, uint8_t dtd)
484
 
{
485
 
        char *endptr;
486
 
        sdp_data_t *ret = NULL;
487
 
 
488
 
        switch (dtd) {
489
 
        case SDP_BOOL:
490
 
        {
491
 
                uint8_t val = 0;
492
 
 
493
 
                if (!strcmp("true", data)) {
494
 
                        val = 1;
495
 
                }
496
 
 
497
 
                else if (!strcmp("false", data)) {
498
 
                        val = 0;
499
 
                }
500
 
                else {
501
 
                        return NULL;
502
 
                }
503
 
 
504
 
                ret = sdp_data_alloc(dtd, &val);
505
 
                break;
506
 
        }
507
 
 
508
 
        case SDP_INT8:
509
 
        {
510
 
                int8_t val = strtoul(data, &endptr, 0);
511
 
 
512
 
                /* Failed to parse */
513
 
                if ((endptr != data) && (*endptr != '\0'))
514
 
                        return NULL;
515
 
 
516
 
                ret = sdp_data_alloc(dtd, &val);
517
 
                break;
518
 
        }
519
 
 
520
 
        case SDP_UINT8:
521
 
        {
522
 
                uint8_t val = strtoul(data, &endptr, 0);
523
 
 
524
 
                /* Failed to parse */
525
 
                if ((endptr != data) && (*endptr != '\0'))
526
 
                        return NULL;
527
 
 
528
 
                ret = sdp_data_alloc(dtd, &val);
529
 
                break;
530
 
        }
531
 
 
532
 
        case SDP_INT16:
533
 
        {
534
 
                int16_t val = strtoul(data, &endptr, 0);
535
 
 
536
 
                /* Failed to parse */
537
 
                if ((endptr != data) && (*endptr != '\0'))
538
 
                        return NULL;
539
 
 
540
 
                ret = sdp_data_alloc(dtd, &val);
541
 
                break;
542
 
        }
543
 
 
544
 
        case SDP_UINT16:
545
 
        {
546
 
                uint16_t val = strtoul(data, &endptr, 0);
547
 
 
548
 
                /* Failed to parse */
549
 
                if ((endptr != data) && (*endptr != '\0'))
550
 
                        return NULL;
551
 
 
552
 
                ret = sdp_data_alloc(dtd, &val);
553
 
                break;
554
 
        }
555
 
 
556
 
        case SDP_INT32:
557
 
        {
558
 
                int32_t val = strtoul(data, &endptr, 0);
559
 
 
560
 
                /* Failed to parse */
561
 
                if ((endptr != data) && (*endptr != '\0'))
562
 
                        return NULL;
563
 
 
564
 
                ret = sdp_data_alloc(dtd, &val);
565
 
                break;
566
 
        }
567
 
 
568
 
        case SDP_UINT32:
569
 
        {
570
 
                uint32_t val = strtoul(data, &endptr, 0);
571
 
 
572
 
                /* Failed to parse */
573
 
                if ((endptr != data) && (*endptr != '\0'))
574
 
                        return NULL;
575
 
 
576
 
                ret = sdp_data_alloc(dtd, &val);
577
 
                break;
578
 
        }
579
 
 
580
 
        case SDP_INT64:
581
 
        {
582
 
                int64_t val = strtoull(data, &endptr, 0);
583
 
 
584
 
                /* Failed to parse */
585
 
                if ((endptr != data) && (*endptr != '\0'))
586
 
                        return NULL;
587
 
 
588
 
                ret = sdp_data_alloc(dtd, &val);
589
 
                break;
590
 
        }
591
 
 
592
 
        case SDP_UINT64:
593
 
        {
594
 
                uint64_t val = strtoull(data, &endptr, 0);
595
 
 
596
 
                /* Failed to parse */
597
 
                if ((endptr != data) && (*endptr != '\0'))
598
 
                        return NULL;
599
 
 
600
 
                ret = sdp_data_alloc(dtd, &val);
601
 
                break;
602
 
        }
603
 
 
604
 
        case SDP_INT128:
605
 
        case SDP_UINT128:
606
 
        {
607
 
                uint128_t val;
608
 
                int i = 0;
609
 
                char buf[3];
610
 
 
611
 
                buf[2] = '\0';
612
 
 
613
 
                for (; i < 32; i += 2) {
614
 
                        buf[0] = data[i];
615
 
                        buf[1] = data[i + 1];
616
 
 
617
 
                        val.data[i >> 1] = strtoul(buf, 0, 16);
618
 
                }
619
 
 
620
 
                ret = sdp_data_alloc(dtd, &val);
621
 
                break;
622
 
        }
623
 
 
624
 
        };
625
 
 
626
 
        return ret;
627
 
}
628
 
 
629
 
static char *sdp_xml_parse_string_decode(const char *data, char encoding, uint32_t *length)
630
 
{
631
 
        int len = strlen(data);
632
 
        char *text;
633
 
 
634
 
        if (encoding == SDP_XML_ENCODING_NORMAL) {
635
 
                text = strdup(data);
636
 
                *length = len;
637
 
        } else {
638
 
                char buf[3], *decoded;
639
 
                int i;
640
 
 
641
 
                decoded = malloc((len >> 1) + 1);
642
 
 
643
 
                /* Ensure the string is a power of 2 */
644
 
                len = (len >> 1) << 1;
645
 
 
646
 
                buf[2] = '\0';
647
 
 
648
 
                for (i = 0; i < len; i += 2) {
649
 
                        buf[0] = data[i];
650
 
                        buf[1] = data[i + 1];
651
 
 
652
 
                        decoded[i >> 1] = strtoul(buf, 0, 16);
653
 
                }
654
 
 
655
 
                decoded[len >> 1] = '\0';
656
 
                text = decoded;
657
 
                *length = len >> 1;
658
 
        }
659
 
 
660
 
        return text;
661
 
}
662
 
 
663
 
sdp_data_t *sdp_xml_parse_url(const char *data)
664
 
{
665
 
        uint8_t dtd = SDP_URL_STR8;
666
 
        char *url;
667
 
        uint32_t length;
668
 
        sdp_data_t *ret;
669
 
 
670
 
        url = sdp_xml_parse_string_decode(data,
671
 
                                SDP_XML_ENCODING_NORMAL, &length);
672
 
 
673
 
        if (length > UCHAR_MAX)
674
 
                dtd = SDP_URL_STR16;
675
 
 
676
 
        ret = sdp_data_alloc_with_length(dtd, url, length);
677
 
 
678
 
        debug("URL size %d length %d: -->%s<--", ret->unitSize, length, url);
679
 
 
680
 
        free(url);
681
 
 
682
 
        return ret;
683
 
}
684
 
 
685
 
sdp_data_t *sdp_xml_parse_text(const char *data, char encoding)
686
 
{
687
 
        uint8_t dtd = SDP_TEXT_STR8;
688
 
        char *text;
689
 
        uint32_t length;
690
 
        sdp_data_t *ret;
691
 
 
692
 
        text = sdp_xml_parse_string_decode(data, encoding, &length);
693
 
 
694
 
        if (length > UCHAR_MAX)
695
 
                dtd = SDP_TEXT_STR16;
696
 
 
697
 
        ret = sdp_data_alloc_with_length(dtd, text, length);
698
 
 
699
 
        debug("Text size %d length %d: -->%s<--", ret->unitSize, length, text);
700
 
 
701
 
        free(text);
702
 
 
703
 
        return ret;
704
 
}
705
 
 
706
 
sdp_data_t *sdp_xml_parse_nil(const char *data)
707
 
{
708
 
        return sdp_data_alloc(SDP_DATA_NIL, 0);
709
 
}
710
 
 
711
 
#define DEFAULT_XML_DATA_SIZE 1024
712
 
 
713
 
struct sdp_xml_data *sdp_xml_data_alloc()
714
 
{
715
 
        struct sdp_xml_data *elem;
716
 
 
717
 
        elem = malloc(sizeof(struct sdp_xml_data));
718
 
        if (!elem)
719
 
                return NULL;
720
 
 
721
 
        memset(elem, 0, sizeof(struct sdp_xml_data));
722
 
 
723
 
        /* Null terminate the text */
724
 
        elem->size = DEFAULT_XML_DATA_SIZE;
725
 
        elem->text = malloc(DEFAULT_XML_DATA_SIZE);
726
 
        elem->text[0] = '\0';
727
 
 
728
 
        return elem;
729
 
}
730
 
 
731
 
void sdp_xml_data_free(struct sdp_xml_data *elem)
732
 
{
733
 
        if (elem->data)
734
 
                sdp_data_free(elem->data);
735
 
 
736
 
        if (elem->name)
737
 
                free(elem->name);
738
 
 
739
 
        if (elem->text)
740
 
 
741
 
                free(elem->text);
742
 
        free(elem);
743
 
}
744
 
 
745
 
struct sdp_xml_data *sdp_xml_data_expand(struct sdp_xml_data *elem)
746
 
{
747
 
        char *newbuf;
748
 
 
749
 
        newbuf = malloc(elem->size * 2);
750
 
        if (!newbuf)
751
 
                return NULL;
752
 
 
753
 
        memcpy(newbuf, elem->text, elem->size);
754
 
        elem->size *= 2;
755
 
        free(elem->text);
756
 
 
757
 
        elem->text = newbuf;
758
 
 
759
 
        return elem;
760
 
}
761
 
 
762
 
sdp_data_t *sdp_xml_parse_datatype(const char *el, struct sdp_xml_data *elem,
763
 
                                                        sdp_record_t *record)
764
 
{
765
 
        const char *data = elem->text;
766
 
 
767
 
        if (!strcmp(el, "boolean"))
768
 
                return sdp_xml_parse_int(data, SDP_BOOL);
769
 
        else if (!strcmp(el, "uint8"))
770
 
                return sdp_xml_parse_int(data, SDP_UINT8);
771
 
        else if (!strcmp(el, "uint16"))
772
 
                return sdp_xml_parse_int(data, SDP_UINT16);
773
 
        else if (!strcmp(el, "uint32"))
774
 
                return sdp_xml_parse_int(data, SDP_UINT32);
775
 
        else if (!strcmp(el, "uint64"))
776
 
                return sdp_xml_parse_int(data, SDP_UINT64);
777
 
        else if (!strcmp(el, "uint128"))
778
 
                return sdp_xml_parse_int(data, SDP_UINT128);
779
 
        else if (!strcmp(el, "int8"))
780
 
                return sdp_xml_parse_int(data, SDP_INT8);
781
 
        else if (!strcmp(el, "int16"))
782
 
                return sdp_xml_parse_int(data, SDP_INT16);
783
 
        else if (!strcmp(el, "int32"))
784
 
                return sdp_xml_parse_int(data, SDP_INT32);
785
 
        else if (!strcmp(el, "int64"))
786
 
                return sdp_xml_parse_int(data, SDP_INT64);
787
 
        else if (!strcmp(el, "int128"))
788
 
                return sdp_xml_parse_int(data, SDP_INT128);
789
 
        else if (!strcmp(el, "uuid"))
790
 
                return sdp_xml_parse_uuid(data, record);
791
 
        else if (!strcmp(el, "url"))
792
 
                return sdp_xml_parse_url(data);
793
 
        else if (!strcmp(el, "text"))
794
 
                return sdp_xml_parse_text(data, elem->type);
795
 
        else if (!strcmp(el, "nil"))
796
 
                return sdp_xml_parse_nil(data);
797
 
 
798
 
        return NULL;
799
 
}