aboutsummaryrefslogtreecommitdiff
path: root/src/backend/utils/adt/xml.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/utils/adt/xml.c')
-rw-r--r--src/backend/utils/adt/xml.c90
1 files changed, 65 insertions, 25 deletions
diff --git a/src/backend/utils/adt/xml.c b/src/backend/utils/adt/xml.c
index 6771360c48a..ab929eed647 100644
--- a/src/backend/utils/adt/xml.c
+++ b/src/backend/utils/adt/xml.c
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/backend/utils/adt/xml.c,v 1.10 2007/01/05 22:19:42 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/adt/xml.c,v 1.11 2007/01/06 19:18:36 petere Exp $
*
*-------------------------------------------------------------------------
*/
@@ -31,6 +31,7 @@
#include <libxml/tree.h>
#include <libxml/uri.h>
#include <libxml/xmlerror.h>
+#include <libxml/xmlsave.h>
#endif /* USE_LIBXML */
#include "fmgr.h"
@@ -49,10 +50,12 @@
static StringInfo xml_err_buf = NULL;
static void xml_init(void);
+#ifdef NOT_USED
static void *xml_palloc(size_t size);
static void *xml_repalloc(void *ptr, size_t size);
static void xml_pfree(void *ptr);
static char *xml_pstrdup(const char *string);
+#endif
static void xml_ereport(int level, int sqlcode,
const char *msg, void *ctxt);
static void xml_errorHandler(void *ctxt, const char *msg, ...);
@@ -76,6 +79,7 @@ xml_in(PG_FUNCTION_ARGS)
char *s = PG_GETARG_CSTRING(0);
size_t len;
xmltype *vardata;
+ xmlDocPtr doc;
len = strlen(s);
vardata = palloc(len + VARHDRSZ);
@@ -86,7 +90,8 @@ xml_in(PG_FUNCTION_ARGS)
* Parse the data to check if it is well-formed XML data. Assume
* that ERROR occurred if parsing failed.
*/
- xml_parse(vardata, false, true);
+ doc = xml_parse(vardata, false, true);
+ xmlFreeDoc(doc);
PG_RETURN_XML_P(vardata);
#else
@@ -120,6 +125,7 @@ xml_recv(PG_FUNCTION_ARGS)
xmltype *result;
char *str;
int nbytes;
+ xmlDocPtr doc;
str = pq_getmsgtext(buf, buf->len - buf->cursor, &nbytes);
@@ -132,7 +138,8 @@ xml_recv(PG_FUNCTION_ARGS)
* Parse the data to check if it is well-formed XML data. Assume
* that ERROR occurred if parsing failed.
*/
- xml_parse(result, false, true);
+ doc = xml_parse(result, false, true);
+ xmlFreeDoc(doc);
PG_RETURN_XML_P(result);
#else
@@ -175,6 +182,21 @@ stringinfo_to_xmltype(StringInfo buf)
return result;
}
+
+
+static xmltype *
+xmlBuffer_to_xmltype(xmlBufferPtr buf)
+{
+ int32 len;
+ xmltype *result;
+
+ len = xmlBufferLength(buf) + VARHDRSZ;
+ result = palloc(len);
+ VARATT_SIZEP(result) = len;
+ memcpy(VARDATA(result), xmlBufferContent(buf), len - VARHDRSZ);
+
+ return result;
+}
#endif
@@ -221,7 +243,10 @@ xmltype *
xmlparse(text *data, bool is_document, bool preserve_whitespace)
{
#ifdef USE_LIBXML
- xml_parse(data, is_document, preserve_whitespace);
+ xmlDocPtr doc;
+
+ doc = xml_parse(data, is_document, preserve_whitespace);
+ xmlFreeDoc(doc);
return (xmltype *) data;
#else
@@ -280,31 +305,38 @@ xmltype *
xmlroot(xmltype *data, text *version, int standalone)
{
#ifdef USE_LIBXML
- xmltype *result;
- StringInfoData buf;
+ xmlDocPtr doc;
+ xmlBufferPtr buffer;
+ xmlSaveCtxtPtr save;
- initStringInfo(&buf);
+ doc = xml_parse((text *) data, true, true);
- /*
- * FIXME: This is probably supposed to be cleverer if there
- * already is an XML preamble.
- */
- appendStringInfo(&buf,"<?xml");
if (version)
+ doc->version = xmlStrdup(xml_text2xmlChar(version));
+ else
+ doc->version = NULL;
+
+ switch (standalone)
{
- appendStringInfo(&buf, " version=\"");
- appendStringInfoText(&buf, version);
- appendStringInfo(&buf, "\"");
+ case 1:
+ doc->standalone = 1;
+ break;
+ case -1:
+ doc->standalone = 0;
+ break;
+ default:
+ doc->standalone = -1;
+ break;
}
- if (standalone)
- appendStringInfo(&buf, " standalone=\"%s\"",
- (standalone == 1 ? "yes" : "no"));
- appendStringInfo(&buf, "?>");
- appendStringInfoText(&buf, (text *) data);
- result = stringinfo_to_xmltype(&buf);
- pfree(buf.data);
- return result;
+ buffer = xmlBufferCreate();
+ save = xmlSaveToBuffer(buffer, NULL, 0);
+ xmlSaveDoc(save, doc);
+ xmlSaveClose(save);
+
+ xmlFreeDoc(doc);
+
+ return xmlBuffer_to_xmltype(buffer);
#else
NO_XML_SUPPORT();
return NULL;
@@ -444,7 +476,14 @@ xml_init(void)
/* Now that xml_err_buf exists, safe to call xml_errorHandler */
xmlSetGenericErrorFunc(NULL, xml_errorHandler);
+#ifdef NOT_USED
+ /*
+ * FIXME: This doesn't work because libxml assumes that whatever
+ * libxml allocates, only libxml will free, so we can't just drop
+ * memory contexts behind it. This needs to be refined.
+ */
xmlMemSetup(xml_pfree, xml_palloc, xml_repalloc, xml_pstrdup);
+#endif
xmlInitParser();
LIBXML_TEST_VERSION;
}
@@ -528,8 +567,6 @@ xml_parse(text *data, bool is_document, bool preserve_whitespace)
* ) */
/* ... */
- if (doc)
- xmlFreeDoc(doc);
if (ctxt)
xmlFreeParserCtxt(ctxt);
xmlCleanupParser();
@@ -538,6 +575,7 @@ xml_parse(text *data, bool is_document, bool preserve_whitespace)
{
if (doc)
xmlFreeDoc(doc);
+ doc = NULL;
if (ctxt)
xmlFreeParserCtxt(ctxt);
xmlCleanupParser();
@@ -567,6 +605,7 @@ xml_text2xmlChar(text *in)
}
+#ifdef NOT_USED
/*
* Wrappers for memory management functions
*/
@@ -596,6 +635,7 @@ xml_pstrdup(const char *string)
{
return pstrdup(string);
}
+#endif /* NOT_USED */
/*