7
7
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
8
8
* Portions Copyright (c) 1994, Regents of the University of California
9
9
*
10
- * $PostgreSQL: pgsql/src/backend/utils/adt/xml.c,v 1.10 2007/01/05 22: 19:42 momjian Exp $
10
+ * $PostgreSQL: pgsql/src/backend/utils/adt/xml.c,v 1.11 2007/01/06 19:18:36 petere Exp $
11
11
*
12
12
*-------------------------------------------------------------------------
13
13
*/
31
31
#include <libxml/tree.h>
32
32
#include <libxml/uri.h>
33
33
#include <libxml/xmlerror.h>
34
+ #include <libxml/xmlsave.h>
34
35
#endif /* USE_LIBXML */
35
36
36
37
#include "fmgr.h"
49
50
static StringInfo xml_err_buf = NULL ;
50
51
51
52
static void xml_init (void );
53
+ #ifdef NOT_USED
52
54
static void * xml_palloc (size_t size );
53
55
static void * xml_repalloc (void * ptr , size_t size );
54
56
static void xml_pfree (void * ptr );
55
57
static char * xml_pstrdup (const char * string );
58
+ #endif
56
59
static void xml_ereport (int level , int sqlcode ,
57
60
const char * msg , void * ctxt );
58
61
static void xml_errorHandler (void * ctxt , const char * msg , ...);
@@ -76,6 +79,7 @@ xml_in(PG_FUNCTION_ARGS)
76
79
char * s = PG_GETARG_CSTRING (0 );
77
80
size_t len ;
78
81
xmltype * vardata ;
82
+ xmlDocPtr doc ;
79
83
80
84
len = strlen (s );
81
85
vardata = palloc (len + VARHDRSZ );
@@ -86,7 +90,8 @@ xml_in(PG_FUNCTION_ARGS)
86
90
* Parse the data to check if it is well-formed XML data. Assume
87
91
* that ERROR occurred if parsing failed.
88
92
*/
89
- xml_parse (vardata , false, true);
93
+ doc = xml_parse (vardata , false, true);
94
+ xmlFreeDoc (doc );
90
95
91
96
PG_RETURN_XML_P (vardata );
92
97
#else
@@ -120,6 +125,7 @@ xml_recv(PG_FUNCTION_ARGS)
120
125
xmltype * result ;
121
126
char * str ;
122
127
int nbytes ;
128
+ xmlDocPtr doc ;
123
129
124
130
str = pq_getmsgtext (buf , buf -> len - buf -> cursor , & nbytes );
125
131
@@ -132,7 +138,8 @@ xml_recv(PG_FUNCTION_ARGS)
132
138
* Parse the data to check if it is well-formed XML data. Assume
133
139
* that ERROR occurred if parsing failed.
134
140
*/
135
- xml_parse (result , false, true);
141
+ doc = xml_parse (result , false, true);
142
+ xmlFreeDoc (doc );
136
143
137
144
PG_RETURN_XML_P (result );
138
145
#else
@@ -175,6 +182,21 @@ stringinfo_to_xmltype(StringInfo buf)
175
182
176
183
return result ;
177
184
}
185
+
186
+
187
+ static xmltype *
188
+ xmlBuffer_to_xmltype (xmlBufferPtr buf )
189
+ {
190
+ int32 len ;
191
+ xmltype * result ;
192
+
193
+ len = xmlBufferLength (buf ) + VARHDRSZ ;
194
+ result = palloc (len );
195
+ VARATT_SIZEP (result ) = len ;
196
+ memcpy (VARDATA (result ), xmlBufferContent (buf ), len - VARHDRSZ );
197
+
198
+ return result ;
199
+ }
178
200
#endif
179
201
180
202
@@ -221,7 +243,10 @@ xmltype *
221
243
xmlparse (text * data , bool is_document , bool preserve_whitespace )
222
244
{
223
245
#ifdef USE_LIBXML
224
- xml_parse (data , is_document , preserve_whitespace );
246
+ xmlDocPtr doc ;
247
+
248
+ doc = xml_parse (data , is_document , preserve_whitespace );
249
+ xmlFreeDoc (doc );
225
250
226
251
return (xmltype * ) data ;
227
252
#else
@@ -280,31 +305,38 @@ xmltype *
280
305
xmlroot (xmltype * data , text * version , int standalone )
281
306
{
282
307
#ifdef USE_LIBXML
283
- xmltype * result ;
284
- StringInfoData buf ;
308
+ xmlDocPtr doc ;
309
+ xmlBufferPtr buffer ;
310
+ xmlSaveCtxtPtr save ;
285
311
286
- initStringInfo ( & buf );
312
+ doc = xml_parse (( text * ) data , true, true );
287
313
288
- /*
289
- * FIXME: This is probably supposed to be cleverer if there
290
- * already is an XML preamble.
291
- */
292
- appendStringInfo (& buf ,"<?xml" );
293
314
if (version )
315
+ doc -> version = xmlStrdup (xml_text2xmlChar (version ));
316
+ else
317
+ doc -> version = NULL ;
318
+
319
+ switch (standalone )
294
320
{
295
- appendStringInfo (& buf , " version=\"" );
296
- appendStringInfoText (& buf , version );
297
- appendStringInfo (& buf , "\"" );
321
+ case 1 :
322
+ doc -> standalone = 1 ;
323
+ break ;
324
+ case -1 :
325
+ doc -> standalone = 0 ;
326
+ break ;
327
+ default :
328
+ doc -> standalone = -1 ;
329
+ break ;
298
330
}
299
- if (standalone )
300
- appendStringInfo (& buf , " standalone=\"%s\"" ,
301
- (standalone == 1 ? "yes" : "no" ));
302
- appendStringInfo (& buf , "?>" );
303
- appendStringInfoText (& buf , (text * ) data );
304
331
305
- result = stringinfo_to_xmltype (& buf );
306
- pfree (buf .data );
307
- return result ;
332
+ buffer = xmlBufferCreate ();
333
+ save = xmlSaveToBuffer (buffer , NULL , 0 );
334
+ xmlSaveDoc (save , doc );
335
+ xmlSaveClose (save );
336
+
337
+ xmlFreeDoc (doc );
338
+
339
+ return xmlBuffer_to_xmltype (buffer );
308
340
#else
309
341
NO_XML_SUPPORT ();
310
342
return NULL ;
@@ -444,7 +476,14 @@ xml_init(void)
444
476
/* Now that xml_err_buf exists, safe to call xml_errorHandler */
445
477
xmlSetGenericErrorFunc (NULL , xml_errorHandler );
446
478
479
+ #ifdef NOT_USED
480
+ /*
481
+ * FIXME: This doesn't work because libxml assumes that whatever
482
+ * libxml allocates, only libxml will free, so we can't just drop
483
+ * memory contexts behind it. This needs to be refined.
484
+ */
447
485
xmlMemSetup (xml_pfree , xml_palloc , xml_repalloc , xml_pstrdup );
486
+ #endif
448
487
xmlInitParser ();
449
488
LIBXML_TEST_VERSION ;
450
489
}
@@ -528,8 +567,6 @@ xml_parse(text *data, bool is_document, bool preserve_whitespace)
528
567
* ) */
529
568
/* ... */
530
569
531
- if (doc )
532
- xmlFreeDoc (doc );
533
570
if (ctxt )
534
571
xmlFreeParserCtxt (ctxt );
535
572
xmlCleanupParser ();
@@ -538,6 +575,7 @@ xml_parse(text *data, bool is_document, bool preserve_whitespace)
538
575
{
539
576
if (doc )
540
577
xmlFreeDoc (doc );
578
+ doc = NULL ;
541
579
if (ctxt )
542
580
xmlFreeParserCtxt (ctxt );
543
581
xmlCleanupParser ();
@@ -567,6 +605,7 @@ xml_text2xmlChar(text *in)
567
605
}
568
606
569
607
608
+ #ifdef NOT_USED
570
609
/*
571
610
* Wrappers for memory management functions
572
611
*/
@@ -596,6 +635,7 @@ xml_pstrdup(const char *string)
596
635
{
597
636
return pstrdup (string );
598
637
}
638
+ #endif /* NOT_USED */
599
639
600
640
601
641
/*
0 commit comments