gwenhywfar
4.3.3
Main Page
Related Pages
Modules
Data Structures
Files
File List
Globals
src
parser
xmlrw.c
Go to the documentation of this file.
1
/***************************************************************************
2
copyright : (C) 2007-2010 by Martin Preuss
3
email : martin@libchipcard.de
4
5
***************************************************************************
6
* *
7
* This library is free software; you can redistribute it and/or *
8
* modify it under the terms of the GNU Lesser General Public *
9
* License as published by the Free Software Foundation; either *
10
* version 2.1 of the License, or (at your option) any later version. *
11
* *
12
* This library is distributed in the hope that it will be useful, *
13
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
14
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
15
* Lesser General Public License for more details. *
16
* *
17
* You should have received a copy of the GNU Lesser General Public *
18
* License along with this library; if not, write to the Free Software *
19
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, *
20
* MA 02111-1307 USA *
21
* *
22
***************************************************************************/
23
24
25
/* this file is included from xml.c */
26
27
28
29
int
GWEN_XMLNode__WriteToStream
(
const
GWEN_XMLNODE
*n,
30
GWEN_FAST_BUFFER
*fb,
31
uint32_t flags,
32
unsigned
int
ind) {
33
GWEN_XMLPROPERTY
*p;
34
GWEN_XMLNODE
*c;
35
int
i;
36
int
simpleTag;
37
int
rv;
38
39
#define CHECK_ERROR(rv) \
40
if (rv<0) {\
41
DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);\
42
return rv;\
43
}
44
45
assert(n);
46
47
if
(flags &
GWEN_XML_FLAGS_INDENT
) {
48
for
(i=0; i<ind; i++) {
49
GWEN_FASTBUFFER_WRITEBYTE
(fb, rv,
' '
);
50
CHECK_ERROR
(rv);
51
}
52
}
53
54
simpleTag=0;
55
if
(n->type==
GWEN_XMLNodeTypeTag
) {
56
if
(n->data) {
57
GWEN_FASTBUFFER_WRITEBYTE
(fb, rv,
'<'
);
58
CHECK_ERROR
(rv);
59
GWEN_FASTBUFFER_WRITEFORCED
(fb, rv, n->data, -1);
60
CHECK_ERROR
(rv);
61
}
62
else
{
63
GWEN_FASTBUFFER_WRITEFORCED
(fb, rv,
"<UNKNOWN"
, -1);
64
CHECK_ERROR
(rv);
65
}
66
67
if
(flags &
GWEN_XML_FLAGS_HANDLE_NAMESPACES
) {
68
GWEN_XMLNODE_NAMESPACE
*ns;
69
70
ns=GWEN_XMLNode_NameSpace_List_First(n->nameSpaces);
71
while
(ns) {
72
const
char
*name;
73
const
char
*url;
74
75
name=
GWEN_XMLNode_NameSpace_GetName
(ns);
76
url=
GWEN_XMLNode_NameSpace_GetUrl
(ns);
77
GWEN_FASTBUFFER_WRITEBYTE
(fb, rv,
' '
);
78
CHECK_ERROR
(rv);
79
GWEN_FASTBUFFER_WRITEFORCED
(fb, rv,
"xmlns"
, -1);
80
CHECK_ERROR
(rv);
81
if
(name) {
82
GWEN_FASTBUFFER_WRITEFORCED
(fb, rv,
":"
, -1);
83
CHECK_ERROR
(rv);
84
GWEN_FASTBUFFER_WRITEFORCED
(fb, rv, name, -1);
85
CHECK_ERROR
(rv);
86
}
87
GWEN_FASTBUFFER_WRITEFORCED
(fb, rv,
"=\""
, -1);
88
CHECK_ERROR
(rv);
89
if
(url) {
90
GWEN_FASTBUFFER_WRITEFORCED
(fb, rv, url, -1);
91
CHECK_ERROR
(rv);
92
}
93
GWEN_FASTBUFFER_WRITEFORCED
(fb, rv,
"\""
, -1);
94
CHECK_ERROR
(rv);
95
96
ns=GWEN_XMLNode_NameSpace_List_Next(ns);
97
}
98
}
99
100
p=n->properties;
101
while
(p) {
102
GWEN_FASTBUFFER_WRITEBYTE
(fb, rv,
' '
);
103
CHECK_ERROR
(rv);
104
GWEN_FASTBUFFER_WRITEFORCED
(fb, rv, p->name, -1);
105
CHECK_ERROR
(rv);
106
if
(p->value) {
107
GWEN_FASTBUFFER_WRITEFORCED
(fb, rv,
"=\""
, -1);
108
CHECK_ERROR
(rv);
109
GWEN_FASTBUFFER_WRITEFORCED
(fb, rv, p->value, -1);
110
CHECK_ERROR
(rv);
111
GWEN_FASTBUFFER_WRITEFORCED
(fb, rv,
"\""
, -1);
112
CHECK_ERROR
(rv);
113
}
114
p=p->next;
115
}
116
117
if
(n->data) {
118
if
(n->data[0]==
'?'
) {
119
simpleTag=1;
120
GWEN_FASTBUFFER_WRITEBYTE
(fb, rv,
'?'
);
121
CHECK_ERROR
(rv);
122
}
123
else
if
(n->data[0]==
'!'
) {
124
simpleTag=1;
125
}
126
}
127
128
GWEN_FASTBUFFER_WRITELINE
(fb, rv,
">"
);
129
CHECK_ERROR
(rv);
130
if
(!simpleTag) {
131
c=
GWEN_XMLNode_GetChild
(n);
132
while
(c) {
133
rv=
GWEN_XMLNode__WriteToStream
(c, fb, flags, ind+2);
134
CHECK_ERROR
(rv);
135
c=
GWEN_XMLNode_Next
(c);
136
}
137
if
(flags & GWEN_XML_FLAGS_INDENT) {
138
for
(i=0; i<ind; i++) {
139
GWEN_FASTBUFFER_WRITEBYTE
(fb, rv,
' '
);
140
CHECK_ERROR
(rv);
141
}
142
}
143
if
(n->data) {
144
GWEN_FASTBUFFER_WRITEFORCED
(fb, rv,
"</"
, -1);
145
CHECK_ERROR
(rv);
146
GWEN_FASTBUFFER_WRITEFORCED
(fb, rv, n->data, -1);
147
CHECK_ERROR
(rv);
148
GWEN_FASTBUFFER_WRITELINE
(fb, rv,
">"
);
149
CHECK_ERROR
(rv);
150
}
151
else
{
152
GWEN_FASTBUFFER_WRITELINE
(fb, rv,
"</UNKNOWN>"
);
153
CHECK_ERROR
(rv);
154
}
155
}
156
}
157
else
if
(n->type==
GWEN_XMLNodeTypeData
) {
158
if
(n->data) {
159
GWEN_FASTBUFFER_WRITEFORCED
(fb, rv, n->data, -1);
160
CHECK_ERROR
(rv);
161
GWEN_FASTBUFFER_WRITELINE
(fb, rv,
""
);
162
CHECK_ERROR
(rv);
163
}
164
}
165
else
if
(n->type==
GWEN_XMLNodeTypeComment
) {
166
if
(flags &
GWEN_XML_FLAGS_HANDLE_COMMENTS
) {
167
GWEN_FASTBUFFER_WRITEFORCED
(fb, rv,
"<!--"
, -1);
168
CHECK_ERROR
(rv);
169
if
(n->data) {
170
GWEN_FASTBUFFER_WRITEFORCED
(fb, rv, n->data, -1);
171
CHECK_ERROR
(rv);
172
}
173
GWEN_FASTBUFFER_WRITELINE
(fb, rv,
"-->"
);
174
CHECK_ERROR
(rv);
175
}
176
}
177
else
{
178
DBG_ERROR
(
GWEN_LOGDOMAIN
,
"Unknown tag type (%d)"
, n->type);
179
}
180
181
return
0;
182
#undef CHECK_ERROR
183
}
184
185
186
187
int
GWEN_XMLNode_WriteToStream
(
const
GWEN_XMLNODE
*n,
188
GWEN_XML_CONTEXT
*ctx,
189
GWEN_SYNCIO
*sio){
190
const
GWEN_XMLNODE
*nn;
191
const
GWEN_XMLNODE
*nchild;
192
const
GWEN_XMLNODE
*nheader;
193
uint32_t flags;
194
GWEN_FAST_BUFFER
*fb;
195
int
rv;
196
197
flags=
GWEN_XmlCtx_GetFlags
(ctx);
198
nchild=
GWEN_XMLNode_GetChild
(n);
199
nheader=
GWEN_XMLNode_GetHeader
(n);
200
201
fb=
GWEN_FastBuffer_new
(512, sio);
202
203
if
(nheader && (flags &
GWEN_XML_FLAGS_HANDLE_HEADERS
)) {
204
uint32_t lflags;
205
206
lflags=flags & ~GWEN_XML_FLAGS_HANDLE_HEADERS;
207
nn=nheader;
208
while
(nn) {
209
const
GWEN_XMLNODE
*next;
210
211
rv=
GWEN_XMLNode__WriteToStream
(nn, fb,
GWEN_XmlCtx_GetFlags
(ctx), 0);
212
if
(rv<0) {
213
DBG_INFO
(
GWEN_LOGDOMAIN
,
"here (%d)"
, rv);
214
GWEN_FastBuffer_free
(fb);
215
return
rv;
216
}
217
next=
GWEN_XMLNode_Next
(nn);
218
if
(next) {
219
int
err;
220
221
GWEN_FASTBUFFER_WRITELINE
(fb, err,
""
);
222
if
(err<0) {
223
DBG_INFO
(
GWEN_LOGDOMAIN
,
"here (%d)"
, err);
224
GWEN_FastBuffer_free
(fb);
225
return
err;
226
}
227
}
228
229
nn=next;
230
}
231
232
if
(nchild) {
233
int
err;
234
235
GWEN_FASTBUFFER_WRITELINE
(fb, err,
""
);
236
if
(err<0) {
237
DBG_INFO
(
GWEN_LOGDOMAIN
,
"here (%d)"
, err);
238
GWEN_FastBuffer_free
(fb);
239
return
err;
240
}
241
}
242
}
243
244
nn=nchild;
245
while
(nn) {
246
const
GWEN_XMLNODE
*next;
247
248
if
(
GWEN_XMLNode__WriteToStream
(nn, fb,
GWEN_XmlCtx_GetFlags
(ctx), 0))
249
return
-1;
250
next=
GWEN_XMLNode_Next
(nn);
251
if
(next) {
252
int
err;
253
254
GWEN_FASTBUFFER_WRITELINE
(fb, err,
""
);
255
if
(err<0) {
256
DBG_INFO
(
GWEN_LOGDOMAIN
,
"here (%d)"
, err);
257
GWEN_FastBuffer_free
(fb);
258
return
err;
259
}
260
}
261
262
nn=next;
263
}
/* while */
264
265
GWEN_FASTBUFFER_FLUSH
(fb, rv);
266
if
(rv<0) {
267
DBG_INFO
(
GWEN_LOGDOMAIN
,
"here (%d)"
, rv);
268
GWEN_FastBuffer_free
(fb);
269
return
rv;
270
}
271
GWEN_FastBuffer_free
(fb);
272
273
return
0;
274
}
275
276
277
278
int
GWEN_XMLNode_WriteFile
(
const
GWEN_XMLNODE
*n,
279
const
char
*fname,
280
uint32_t flags){
281
GWEN_XML_CONTEXT
*ctx;
282
GWEN_SYNCIO
*sio;
283
int
rv;
284
285
sio=
GWEN_SyncIo_File_new
(fname,
GWEN_SyncIo_File_CreationMode_CreateAlways
);
286
GWEN_SyncIo_AddFlags
(sio,
287
GWEN_SYNCIO_FILE_FLAGS_READ
|
GWEN_SYNCIO_FILE_FLAGS_WRITE
|
288
GWEN_SYNCIO_FILE_FLAGS_UREAD
|
GWEN_SYNCIO_FILE_FLAGS_UWRITE
);
289
rv=
GWEN_SyncIo_Connect
(sio);
290
if
(rv<0) {
291
DBG_INFO
(
GWEN_LOGDOMAIN
,
"here (%d)"
, rv);
292
GWEN_SyncIo_free
(sio);
293
return
rv;
294
}
295
296
/* create context and io layers */
297
ctx=
GWEN_XmlCtxStore_new
(
NULL
, flags);
298
299
/* write data to stream */
300
rv=
GWEN_XMLNode_WriteToStream
(n, ctx, sio);
301
if
(rv<0) {
302
DBG_INFO
(
GWEN_LOGDOMAIN
,
"here (%d)"
, rv);
303
GWEN_SyncIo_Disconnect
(sio);
304
GWEN_SyncIo_free
(sio);
305
GWEN_XmlCtx_free
(ctx);
306
return
rv;
307
}
308
309
/* close file */
310
GWEN_SyncIo_Disconnect
(sio);
311
GWEN_SyncIo_free
(sio);
312
313
GWEN_XmlCtx_free
(ctx);
314
315
return
0;
316
}
317
318
319
320
int
GWEN_XMLNode_toBuffer
(
const
GWEN_XMLNODE
*n,
GWEN_BUFFER
*buf, uint32_t flags){
321
GWEN_XML_CONTEXT
*ctx;
322
GWEN_SYNCIO
*sio;
323
int
rv;
324
325
sio=
GWEN_SyncIo_Memory_new
(buf, 0);
326
327
/* create context and io layers */
328
ctx=
GWEN_XmlCtxStore_new
(
NULL
, flags);
329
330
/* write data to stream */
331
rv=
GWEN_XMLNode_WriteToStream
(n, ctx, sio);
332
if
(rv<0) {
333
DBG_INFO
(
GWEN_LOGDOMAIN
,
"here (%d)"
, rv);
334
GWEN_SyncIo_free
(sio);
335
GWEN_XmlCtx_free
(ctx);
336
return
rv;
337
}
338
339
GWEN_SyncIo_free
(sio);
340
341
GWEN_XmlCtx_free
(ctx);
342
343
return
0;
344
}
345
346
347
348
349
350
351
352
353
int
GWEN_XML__ReadData
(
GWEN_XML_CONTEXT
*ctx,
354
GWEN_FAST_BUFFER
*fb,
355
GWEN_UNUSED
uint32_t flags){
356
int
chr;
357
unsigned
char
uc;
358
GWEN_BUFFER
*dbuf;
359
360
dbuf=
GWEN_Buffer_new
(0, 256, 0, 1);
361
362
for
(;;) {
363
GWEN_FASTBUFFER_PEEKBYTE
(fb, chr);
364
if
(chr<0) {
365
if
(chr==
GWEN_ERROR_EOF
)
366
break
;
367
else
{
368
GWEN_Buffer_free
(dbuf);
369
return
chr;
370
}
371
}
372
373
uc=(
unsigned
char) chr;
374
if
(uc==
'<'
)
375
break
;
376
fb->
bufferReadPos
++;
377
GWEN_Buffer_AppendByte
(dbuf, uc);
378
}
379
380
if
(
GWEN_Buffer_GetUsedBytes
(dbuf)) {
381
int
rv;
382
const
char
*s;
383
384
s=
GWEN_Buffer_GetStart
(dbuf);
385
if
(*s) {
386
rv=
GWEN_XmlCtx_AddData
(ctx, s);
387
if
(rv) {
388
GWEN_Buffer_free
(dbuf);
389
return
rv;
390
}
391
}
392
}
393
GWEN_Buffer_free
(dbuf);
394
395
return
0;
396
}
397
398
399
400
int
GWEN_XML__ReadTag
(
GWEN_XML_CONTEXT
*ctx,
401
GWEN_FAST_BUFFER
*fb,
402
GWEN_UNUSED
uint32_t flags,
403
GWEN_BUFFER
*dbuf){
404
int
chr;
405
unsigned
char
uc=0;
406
int
rv;
407
408
/* skip blanks */
409
for
(;;) {
410
GWEN_FASTBUFFER_READBYTE
(fb, chr);
411
if
(chr<0) {
412
return
chr;
413
}
414
uc=(
unsigned
char) chr;
415
if
(uc>32)
416
break
;
417
}
418
419
if
(uc==
'/'
) {
420
/* read end tag */
421
GWEN_Buffer_AppendByte
(dbuf, uc);
422
for
(;;) {
423
GWEN_FASTBUFFER_READBYTE
(fb, chr);
424
if
(chr<0) {
425
return
chr;
426
}
427
uc=(
unsigned
char) chr;
428
if
(uc==
'>'
|| uc<33)
429
break
;
430
431
GWEN_Buffer_AppendByte
(dbuf, uc);
432
}
433
434
rv=
GWEN_XmlCtx_StartTag
(ctx,
GWEN_Buffer_GetStart
(dbuf));
435
if
(rv) {
436
return
rv;
437
}
438
if
(uc!=
'>'
) {
439
for
(;;) {
440
/* skip blanks, expect '>' */
441
GWEN_FASTBUFFER_READBYTE
(fb, chr);
442
if
(chr<0) {
443
return
chr;
444
}
445
uc=(
unsigned
char) chr;
446
if
(uc>32)
447
break
;
448
}
449
}
450
if
(uc!=
'>'
) {
451
DBG_ERROR
(
GWEN_LOGDOMAIN
,
"Unexpected character"
);
452
return
GWEN_ERROR_BAD_DATA
;
453
}
454
455
/* tag finished */
456
rv=
GWEN_XmlCtx_EndTag
(ctx, 0);
457
if
(rv) {
458
return
rv;
459
}
460
return
0;
461
}
462
else
if
(uc==
'!'
) {
463
/* check for comment */
464
GWEN_FASTBUFFER_PEEKBYTE
(fb, chr);
465
if
(chr<0) {
466
return
chr;
467
}
468
uc=(
unsigned
char) chr;
469
if
(uc==
'-'
) {
470
fb->
bufferReadPos
++;
471
GWEN_FASTBUFFER_PEEKBYTE
(fb, chr);
472
if
(chr<0) {
473
return
chr;
474
}
475
uc=(
unsigned
char) chr;
476
if
(uc==
'-'
) {
477
GWEN_BUFFER
*cbuf;
478
479
/* found comment */
480
fb->
bufferReadPos
++;
481
cbuf=
GWEN_Buffer_new
(0, 256, 0, 1);
482
for
(;;) {
483
GWEN_FASTBUFFER_READBYTE
(fb, chr);
484
if
(chr<0) {
485
GWEN_Buffer_free
(cbuf);
486
return
chr;
487
}
488
uc=(
unsigned
char) chr;
489
GWEN_Buffer_AppendByte
(cbuf, uc);
490
if
(
GWEN_Buffer_GetUsedBytes
(cbuf)>2) {
491
char
*p;
492
493
p=
GWEN_Buffer_GetStart
(cbuf);
494
p+=
GWEN_Buffer_GetUsedBytes
(cbuf)-3;
495
if
(strcmp(p,
"-->"
)==0) {
496
*p=0;
497
rv=
GWEN_XmlCtx_AddComment
(ctx,
GWEN_Buffer_GetStart
(cbuf));
498
if
(rv) {
499
GWEN_Buffer_free
(cbuf);
500
return
rv;
501
}
502
GWEN_Buffer_free
(cbuf);
503
return
0;
504
}
505
}
506
}
507
}
508
else
{
509
GWEN_Buffer_AppendString
(dbuf,
"!-"
);
510
}
511
}
512
else
513
uc=
'!'
;
514
}
515
516
/* read name */
517
for
(;;) {
518
if
(uc==
' '
|| uc==
'>'
|| uc==
'/'
)
519
break
;
520
else
if
(
GWEN_Buffer_GetUsedBytes
(dbuf)) {
521
unsigned
char
fc;
522
523
fc=*
GWEN_Buffer_GetStart
(dbuf);
524
if
((fc==
'!'
&& uc==
'!'
) || (fc==
'?'
&& uc==
'?'
)) {
525
GWEN_FASTBUFFER_PEEKBYTE
(fb, chr);
526
if
(chr<0) {
527
return
chr;
528
}
529
uc=(
unsigned
char) chr;
530
if
(uc==
'>'
) {
531
fb->
bufferReadPos
++;
532
break
;
533
}
534
}
535
}
536
537
GWEN_Buffer_AppendByte
(dbuf, uc);
538
539
GWEN_FASTBUFFER_READBYTE
(fb, chr);
540
if
(chr<0) {
541
if
(chr==
GWEN_ERROR_EOF
) {
542
return
chr;
543
}
544
else
{
545
return
chr;
546
}
547
}
548
549
uc=(
unsigned
char) chr;
550
}
551
552
/* tag started */
553
if
(
GWEN_Buffer_GetUsedBytes
(dbuf)==0) {
554
DBG_ERROR
(
GWEN_LOGDOMAIN
,
"Element name missing"
);
555
return
GWEN_ERROR_BAD_DATA
;
556
}
557
558
rv=
GWEN_XmlCtx_StartTag
(ctx,
GWEN_Buffer_GetStart
(dbuf));
559
if
(rv) {
560
return
rv;
561
}
562
563
if
(uc==
'/'
|| uc==
'?'
|| uc==
'!'
) {
564
GWEN_FASTBUFFER_PEEKBYTE
(fb, chr);
565
if
(chr<0) {
566
return
chr;
567
}
568
uc=(
unsigned
char) chr;
569
if
(uc==
'>'
) {
570
fb->
bufferReadPos
++;
571
rv=
GWEN_XmlCtx_EndTag
(ctx, 1);
572
if
(rv) {
573
return
rv;
574
}
575
/* tag finished */
576
return
0;
577
}
578
}
579
580
if
(uc==
'>'
) {
581
rv=
GWEN_XmlCtx_EndTag
(ctx, 0);
582
if
(rv) {
583
return
rv;
584
}
585
/* tag finished */
586
return
0;
587
}
588
589
/* read attributes */
590
for
(;;) {
591
GWEN_BUFFER
*nbuf;
592
GWEN_BUFFER
*vbuf=
NULL
;
593
594
nbuf=
GWEN_Buffer_new
(0, 256, 0, 1);
595
596
/* skip blanks */
597
for
(;;) {
598
GWEN_FASTBUFFER_READBYTE
(fb, chr);
599
if
(chr<0) {
600
GWEN_Buffer_free
(nbuf);
601
return
chr;
602
}
603
uc=(
unsigned
char) chr;
604
if
(uc>32)
605
break
;
606
}
607
608
/* read attribute name */
609
for
(;;) {
610
if
(uc==
'/'
|| uc==
'!'
|| uc==
'?'
|| uc==
'='
|| uc==
'>'
)
611
break
;
612
GWEN_Buffer_AppendByte
(nbuf, uc);
613
614
GWEN_FASTBUFFER_READBYTE
(fb, chr);
615
if
(chr<0) {
616
GWEN_Buffer_free
(nbuf);
617
return
chr;
618
}
619
uc=(
unsigned
char) chr;
620
}
621
622
if
(
GWEN_Buffer_GetUsedBytes
(nbuf)) {
623
if
(uc==
'='
) {
624
/* read attribute value if there is an equation mark */
625
int
inQuote=0;
626
627
vbuf=
GWEN_Buffer_new
(0, 256, 0, 1);
628
for
(;;) {
629
GWEN_FASTBUFFER_READBYTE
(fb, chr);
630
if
(chr<0) {
631
GWEN_Buffer_free
(nbuf);
632
return
chr;
633
}
634
uc=(
unsigned
char) chr;
635
if
(uc==
'"'
) {
636
if
(inQuote) {
637
inQuote=0;
638
break
;
639
}
640
else
641
inQuote=1;
642
}
643
else
{
644
if
(!inQuote) {
645
if
(uc==
'>'
|| uc<33)
646
break
;
647
else
if
(uc==
'<'
) {
648
DBG_ERROR
(
GWEN_LOGDOMAIN
,
649
"Nested element definitions"
);
650
GWEN_Buffer_free
(vbuf);
651
GWEN_Buffer_free
(nbuf);
652
return
GWEN_ERROR_BAD_DATA
;
653
}
654
else
if
(
GWEN_Buffer_GetUsedBytes
(dbuf)) {
655
if
(uc==
'/'
|| uc==
'!'
|| uc==
'?'
) {
656
unsigned
char
tc;
657
658
GWEN_FASTBUFFER_PEEKBYTE
(fb, chr);
659
if
(chr<0) {
660
GWEN_Buffer_free
(vbuf);
661
GWEN_Buffer_free
(nbuf);
662
return
chr;
663
}
664
tc=(
unsigned
char) chr;
665
if
(tc==
'>'
) {
666
break
;
667
}
668
}
669
}
670
}
671
GWEN_Buffer_AppendByte
(vbuf, uc);
672
}
673
}
674
if
(inQuote) {
675
DBG_ERROR
(
GWEN_LOGDOMAIN
,
"No matching number of quote chars"
);
676
GWEN_Buffer_free
(vbuf);
677
GWEN_Buffer_free
(nbuf);
678
return
GWEN_ERROR_BAD_DATA
;
679
}
680
681
if
(
GWEN_Buffer_GetUsedBytes
(vbuf)==0) {
682
GWEN_Buffer_free
(vbuf);
683
vbuf=
NULL
;
684
}
685
}
686
rv=
GWEN_XmlCtx_AddAttr
(ctx,
687
GWEN_Buffer_GetStart
(nbuf),
688
vbuf?
GWEN_Buffer_GetStart
(vbuf):
NULL
);
689
if
(rv) {
690
GWEN_Buffer_free
(vbuf);
691
GWEN_Buffer_free
(nbuf);
692
return
rv;
693
}
694
}
695
696
GWEN_Buffer_free
(vbuf);
697
GWEN_Buffer_free
(nbuf);
698
699
if
(uc==
'>'
|| uc==
'?'
|| uc==
'!'
|| uc==
'/'
)
700
break
;
701
}
702
703
if
(uc==
'?'
|| uc==
'!'
|| uc==
'/'
) {
704
unsigned
char
ucsave=uc;
705
706
GWEN_FASTBUFFER_PEEKBYTE
(fb, chr);
707
if
(chr<0) {
708
return
chr;
709
}
710
uc=(
unsigned
char) chr;
711
if
(uc==
'>'
) {
712
DBG_VERBOUS
(
GWEN_LOGDOMAIN
,
"Ending tag [%s]"
,
GWEN_Buffer_GetStart
(dbuf));
713
fb->
bufferReadPos
++;
714
rv=
GWEN_XmlCtx_EndTag
(ctx, 1);
715
if
(rv) {
716
return
rv;
717
}
718
/* tag finished */
719
return
0;
720
}
721
else
{
722
DBG_ERROR
(
GWEN_LOGDOMAIN
,
723
"Got an unexpected character here (after %02x[%c]): %02x[%c], "
724
"maybe the text contains unescaped XML characters?"
,
725
ucsave, ucsave, uc, uc);
726
}
727
}
728
else
if
(uc==
'>'
) {
729
rv=
GWEN_XmlCtx_EndTag
(ctx, 0);
730
if
(rv) {
731
return
rv;
732
}
733
/* tag finished */
734
return
0;
735
}
736
737
DBG_ERROR
(
GWEN_LOGDOMAIN
,
738
"Internal error: Should never reach this point"
);
739
return
GWEN_ERROR_INTERNAL
;
740
}
741
742
743
744
745
int
GWEN_XML_ReadFromFastBuffer
(
GWEN_XML_CONTEXT
*ctx,
GWEN_FAST_BUFFER
*fb){
746
int
oks=0;
747
int
startingDepth;
748
GWEN_BUFFER
*workBuf;
749
750
startingDepth=
GWEN_XmlCtx_GetDepth
(ctx);
751
752
workBuf=
GWEN_Buffer_new
(0, 256, 0, 1);
753
GWEN_XmlCtx_ResetFinishedElement
(ctx);
754
for
(;;) {
755
int
rv;
756
757
GWEN_FASTBUFFER_PEEKBYTE
(fb, rv);
758
if
(rv<0) {
759
if
(rv!=
GWEN_ERROR_EOF
|| !oks) {
760
DBG_DEBUG
(
GWEN_LOGDOMAIN
,
"here (%d), after reading %d bytes"
,
761
rv, (
int
)
GWEN_FastBuffer_GetBytesRead
(fb));
762
GWEN_Buffer_free
(workBuf);
763
return
rv;
764
}
765
GWEN_Buffer_free
(workBuf);
766
return
0;
767
}
768
769
rv=
GWEN_XML__ReadData
(ctx, fb,
GWEN_XmlCtx_GetFlags
(ctx));
770
if
(rv) {
771
DBG_INFO
(
GWEN_LOGDOMAIN
,
"here (%d)"
, rv);
772
GWEN_Buffer_free
(workBuf);
773
return
rv;
774
}
775
oks=1;
776
777
GWEN_FASTBUFFER_PEEKBYTE
(fb, rv);
778
if
(rv<0) {
779
if
(rv!=
GWEN_ERROR_EOF
|| !oks ||
780
(
GWEN_XmlCtx_GetDepth
(ctx)!=startingDepth)) {
781
DBG_INFO
(
GWEN_LOGDOMAIN
,
"here (%d)"
, rv);
782
GWEN_Buffer_free
(workBuf);
783
return
rv;
784
}
785
GWEN_Buffer_free
(workBuf);
786
return
0;
787
}
788
else
if
(rv==
'<'
) {
789
fb->
bufferReadPos
++;
790
rv=
GWEN_XML__ReadTag
(ctx, fb,
GWEN_XmlCtx_GetFlags
(ctx), workBuf);
791
if
(rv) {
792
DBG_INFO
(
GWEN_LOGDOMAIN
,
"here (%d)"
, rv);
793
GWEN_Buffer_free
(workBuf);
794
return
rv;
795
}
796
GWEN_Buffer_Reset
(workBuf);
797
oks=1;
798
}
799
800
if
(
GWEN_XmlCtx_GetFinishedElement
(ctx) &&
801
GWEN_XmlCtx_GetDepth
(ctx)==startingDepth)
802
break
;
803
}
804
805
if
(
GWEN_XmlCtx_GetDepth
(ctx)!=startingDepth) {
806
DBG_ERROR
(
GWEN_LOGDOMAIN
,
807
"Not on same level where we started...(%d!=%d)"
,
808
GWEN_XmlCtx_GetDepth
(ctx), startingDepth);
809
}
810
GWEN_Buffer_free
(workBuf);
811
812
return
0;
813
}
814
815
816
817
int
GWEN_XML__ReadAllFromIo
(
GWEN_XML_CONTEXT
*ctx,
GWEN_SYNCIO
*sio){
818
GWEN_FAST_BUFFER
*fb;
819
int
oks=0;
820
821
fb=
GWEN_FastBuffer_new
(
GWEN_XML_BUFFERSIZE
, sio);
822
assert(fb);
823
for
(;;) {
824
int
rv;
825
826
rv=
GWEN_XML_ReadFromFastBuffer
(ctx, fb);
827
if
(rv<0) {
828
if
(rv==
GWEN_ERROR_EOF
&& oks)
829
break
;
830
else
{
831
DBG_INFO
(
GWEN_LOGDOMAIN
,
"here"
);
832
GWEN_FastBuffer_free
(fb);
833
return
rv;
834
}
835
}
836
oks=1;
837
}
838
839
GWEN_FastBuffer_free
(fb);
840
return
0;
841
}
842
843
844
845
int
GWEN_XMLContext_ReadFromIo
(
GWEN_XML_CONTEXT
*ctx,
GWEN_SYNCIO
*sio){
846
#if 0
847
GWEN_FAST_BUFFER
*fb;
848
int
rv;
849
850
fb=
GWEN_FastBuffer_new
(
GWEN_XML_BUFFERSIZE
, sio);
851
assert(fb);
852
rv=
GWEN_XML_ReadFromFastBuffer
(ctx, fb);
853
if
(rv) {
854
DBG_INFO
(
GWEN_LOGDOMAIN
,
"here"
);
855
GWEN_FastBuffer_free
(fb);
856
return
rv;
857
}
858
859
GWEN_FastBuffer_free
(fb);
860
return
0;
861
#else
862
int
rv;
863
864
rv=
GWEN_XML__ReadAllFromIo
(ctx, sio);
865
if
(rv<0) {
866
DBG_INFO
(
GWEN_LOGDOMAIN
,
"here (%d)"
, rv);
867
return
rv;
868
}
869
870
return
rv;
871
#endif
872
}
873
874
875
876
int
GWEN_XMLContext_ReadFromFile
(
GWEN_XML_CONTEXT
*ctx,
const
char
*fname) {
877
GWEN_SYNCIO
*sio;
878
int
rv;
879
880
sio=
GWEN_SyncIo_File_new
(fname,
GWEN_SyncIo_File_CreationMode_OpenExisting
);
881
GWEN_SyncIo_AddFlags
(sio,
GWEN_SYNCIO_FILE_FLAGS_READ
);
882
rv=
GWEN_SyncIo_Connect
(sio);
883
if
(rv<0) {
884
DBG_INFO
(
GWEN_LOGDOMAIN
,
"here (%d)"
, rv);
885
GWEN_SyncIo_free
(sio);
886
return
rv;
887
}
888
889
rv=
GWEN_XML__ReadAllFromIo
(ctx, sio);
890
if
(rv<0) {
891
DBG_INFO
(
GWEN_LOGDOMAIN
,
"here (%d)"
, rv);
892
GWEN_SyncIo_Disconnect
(sio);
893
GWEN_SyncIo_free
(sio);
894
return
rv;
895
}
896
897
GWEN_SyncIo_Disconnect
(sio);
898
GWEN_SyncIo_free
(sio);
899
900
return
0;
901
}
902
903
904
905
int
GWEN_XMLContext_ReadFromString
(
GWEN_XML_CONTEXT
*ctx,
const
char
*text) {
906
if
(text && *text) {
907
GWEN_SYNCIO
*sio;
908
int
rv;
909
GWEN_BUFFER
*tbuf;
910
int
i;
911
912
i=strlen(text)+1;
913
tbuf=
GWEN_Buffer_new
((
char
*)text, i, i, 0);
914
/* static buffer, don't resize */
915
GWEN_Buffer_SubMode
(tbuf,
GWEN_BUFFER_MODE_DYNAMIC
);
916
GWEN_Buffer_AddMode
(tbuf,
GWEN_BUFFER_MODE_READONLY
);
917
sio=
GWEN_SyncIo_Memory_new
(tbuf, 0);
918
919
rv=
GWEN_XML__ReadAllFromIo
(ctx, sio);
920
if
(rv<0) {
921
DBG_INFO
(
GWEN_LOGDOMAIN
,
"here (%d)"
, rv);
922
GWEN_SyncIo_free
(sio);
923
GWEN_Buffer_free
(tbuf);
924
return
rv;
925
}
926
927
GWEN_SyncIo_free
(sio);
928
GWEN_Buffer_free
(tbuf);
929
}
930
return
0;
931
}
932
933
934
935
936
int
GWEN_XML_ReadFile
(
GWEN_XMLNODE
*n,
const
char
*filepath, uint32_t flags) {
937
GWEN_XML_CONTEXT
*ctx;
938
GWEN_SYNCIO
*sio;
939
int
rv;
940
941
sio=
GWEN_SyncIo_File_new
(filepath,
GWEN_SyncIo_File_CreationMode_OpenExisting
);
942
GWEN_SyncIo_AddFlags
(sio,
GWEN_SYNCIO_FILE_FLAGS_READ
);
943
rv=
GWEN_SyncIo_Connect
(sio);
944
if
(rv<0) {
945
DBG_INFO
(
GWEN_LOGDOMAIN
,
"here (%d)"
, rv);
946
GWEN_SyncIo_free
(sio);
947
return
rv;
948
}
949
950
ctx=
GWEN_XmlCtxStore_new
(n, flags);
951
rv=
GWEN_XML__ReadAllFromIo
(ctx, sio);
952
if
(rv<0) {
953
DBG_INFO
(
GWEN_LOGDOMAIN
,
"here (%d)"
, rv);
954
GWEN_SyncIo_Disconnect
(sio);
955
GWEN_SyncIo_free
(sio);
956
GWEN_XmlCtx_free
(ctx);
957
return
rv;
958
}
959
960
GWEN_SyncIo_Disconnect
(sio);
961
GWEN_SyncIo_free
(sio);
962
963
GWEN_XmlCtx_free
(ctx);
964
965
return
0;
966
}
967
968
969
970
GWEN_XMLNODE
*
GWEN_XMLNode_fromString
(
const
char
*s,
int
len, uint32_t flags) {
971
#if 0
972
GWEN_XML_CONTEXT
*ctx;
973
GWEN_SYNCIO
*sio;
974
GWEN_XMLNODE
*n;
975
int
rv;
976
977
if
(len==0)
978
len=strlen(s);
979
sio=
GWEN_SyncIo_Memory_fromBuffer
((
const
uint8_t*)s, len);
980
981
n=
GWEN_XMLNode_new
(
GWEN_XMLNodeTypeTag
,
"doc"
);
982
ctx=
GWEN_XmlCtxStore_new
(n, flags);
983
rv=
GWEN_XML__ReadAllFromIo
(ctx, sio);
984
if
(rv<0) {
985
DBG_INFO
(
GWEN_LOGDOMAIN
,
"here (%d)"
, rv);
986
GWEN_SyncIo_free
(sio);
987
GWEN_XmlCtx_free
(ctx);
988
GWEN_XMLNode_free
(n);
989
return
NULL
;
990
}
991
992
GWEN_SyncIo_free
(sio);
993
994
GWEN_XmlCtx_free
(ctx);
995
996
return
n;
997
#else
998
GWEN_XML_CONTEXT
*ctx;
999
GWEN_SYNCIO
*sio;
1000
GWEN_XMLNODE
*n;
1001
int
rv;
1002
GWEN_BUFFER
*tbuf;
1003
1004
tbuf=
GWEN_Buffer_new
((
char
*)s, len, len, 0);
1005
/* static buffer, don't resize */
1006
GWEN_Buffer_SubMode
(tbuf,
GWEN_BUFFER_MODE_DYNAMIC
);
1007
GWEN_Buffer_AddMode
(tbuf,
GWEN_BUFFER_MODE_READONLY
);
1008
sio=
GWEN_SyncIo_Memory_new
(tbuf, 0);
1009
1010
n=
GWEN_XMLNode_new
(
GWEN_XMLNodeTypeTag
,
"doc"
);
1011
ctx=
GWEN_XmlCtxStore_new
(n, flags);
1012
rv=
GWEN_XML__ReadAllFromIo
(ctx, sio);
1013
if
(rv<0) {
1014
DBG_INFO
(
GWEN_LOGDOMAIN
,
"here (%d)"
, rv);
1015
GWEN_XmlCtx_free
(ctx);
1016
GWEN_XMLNode_free
(n);
1017
GWEN_SyncIo_free
(sio);
1018
GWEN_Buffer_free
(tbuf);
1019
return
NULL
;
1020
}
1021
1022
GWEN_XmlCtx_free
(ctx);
1023
GWEN_SyncIo_free
(sio);
1024
GWEN_Buffer_free
(tbuf);
1025
1026
return
n;
1027
#endif
1028
}
1029
1030
1031
1032
Generated on Thu Mar 20 2014 17:06:00 for gwenhywfar by
1.8.1.2