summaryrefslogtreecommitdiffstats
path: root/cpp/sca/kernel/xml.hpp
diff options
context:
space:
mode:
authorjsdelfino <jsdelfino@13f79535-47bb-0310-9956-ffa450edef68>2009-10-05 08:21:40 +0000
committerjsdelfino <jsdelfino@13f79535-47bb-0310-9956-ffa450edef68>2009-10-05 08:21:40 +0000
commit71fb4b80593369073dbd5f3c892aef2865c5a2ae (patch)
tree4c4d464b65b37d3d96a6de60ce031942200c9317 /cpp/sca/kernel/xml.hpp
parent217907b995a000ed949d976f706d72676c270d84 (diff)
Changed XML and JSON databindings to use lazy lists and writer functions instead of STL streams, to help integrate them with HTTPD and CURL, which don't use streams.
git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@821715 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'cpp/sca/kernel/xml.hpp')
-rw-r--r--cpp/sca/kernel/xml.hpp125
1 files changed, 50 insertions, 75 deletions
diff --git a/cpp/sca/kernel/xml.hpp b/cpp/sca/kernel/xml.hpp
index 7ddfd6bc44..cfae5678b8 100644
--- a/cpp/sca/kernel/xml.hpp
+++ b/cpp/sca/kernel/xml.hpp
@@ -30,8 +30,6 @@
#include <libxml/xmlwriter.h>
#include <libxml/xmlschemas.h>
#include <libxml/globals.h>
-#include <iostream>
-#include <fstream>
#include <string>
#include "list.hpp"
@@ -158,7 +156,7 @@ const list<value> readList(const list<value>& listSoFar, XMLReader& reader) {
}
/**
- * Read an XML document from a libxml2 XML reader.
+ * Read a list of values from a libxml2 XML reader.
*/
const list<value> read(XMLReader& reader) {
value nextToken = readToken(reader);
@@ -168,49 +166,35 @@ const list<value> read(XMLReader& reader) {
}
/**
- * Callback function called by libxml2 to read the XML input stream.
+ * Context passed to the read callback function.
*/
-int readCallback(void *context, char* buffer, int len) {
- std::istream* is = static_cast<std::istream*>(context);
- is->read(buffer, len);
- const int n = is->gcount();
- return n;
-}
-
-/**
- * Read an XML document from an input stream.
- */
-const list<value> readXML(std::istream& is) {
- xmlTextReaderPtr xml = xmlReaderForIO(readCallback, NULL, &is, NULL, NULL, XML_PARSE_NONET);
- if (xml == NULL)
- return list<value>();
- XMLReader reader(xml);
- return read(reader);
-}
-
-/**
- * Callback function called by libxml2 to read the XML file input stream.
- */
-int readFileCallback(void *context, char* buffer, int len) {
- std::ifstream* is = static_cast<std::ifstream*>(context);
- is->read(buffer, len);
- return is->gcount();
-}
+class XMLReadContext {
+public:
+ XMLReadContext(const list<std::string>& ilist) : ilist(ilist) {
+ }
+ list<std::string> ilist;
+};
/**
- * Callback function called by libxml2 to close the XML file input stream.
+ * Callback function called by libxml2 to read XML.
*/
-int readCloseFileCallback(void *context) {
- std::ifstream* fis = static_cast<std::ifstream*>(context);
- fis->close();
- return 0;
+int readCallback(void *context, char* buffer, int len) {
+ XMLReadContext& rc = *static_cast<XMLReadContext*>(context);
+ if (isNil(rc.ilist))
+ return 0;
+ rc.ilist = fragment(rc.ilist, len);
+ std::string s = car(rc.ilist);
+ rc.ilist = cdr(rc.ilist);
+ s.copy(buffer, s.length());
+ return s.length();
}
/**
- * Read an XML document from a file input stream.
+ * Read a list values from a list of strings representing an XML document.
*/
-const list<value> readXML(std::ifstream& is) {
- xmlTextReaderPtr xml = xmlReaderForIO(readFileCallback, readCloseFileCallback, &is, NULL, NULL, XML_PARSE_NONET);
+const list<value> readXML(const list<std::string>& ilist) {
+ XMLReadContext cx(ilist);
+ xmlTextReaderPtr xml = xmlReaderForIO(readCallback, NULL, &cx, NULL, NULL, XML_PARSE_NONET);
if (xml == NULL)
return list<value>();
XMLReader reader(xml);
@@ -313,7 +297,7 @@ const bool writeList(const list<value>& l, const xmlTextWriterPtr xml) {
}
/**
- * Write an XML document to a libxml2 XML writer.
+ * Write a list of values to a libxml2 XML writer.
*/
const bool write(const list<value>& l, const xmlTextWriterPtr xml) {
if (xmlTextWriterStartDocument(xml, NULL, encoding, NULL) < 0)
@@ -325,56 +309,47 @@ const bool write(const list<value>& l, const xmlTextWriterPtr xml) {
}
/**
- * Callback function called by libxml2 to write to the XML output stream.
+ * Context passed to the write callback function.
*/
-int writeCallback(void *context, const char* buffer, int len) {
- std::ostream* os = static_cast<std::ostream*>(context);
- os->write(buffer, len);
- if (os->fail() || os->bad())
- return -1;
- return len;
-}
+template<typename R> class XMLWriteContext {
+public:
+ XMLWriteContext(const lambda<R(R, std::string)>& reduce, const R& accum) : reduce(reduce), accum(accum) {
+ }
+ const lambda<R(R, std::string)> reduce;
+ R accum;
+};
/**
- * Write an XML document to an output stream.
+ * Callback function called by libxml2 to write XML out.
*/
-const bool writeXML(const list<value>& l, std::ostream& os) {
- xmlOutputBufferPtr out = xmlOutputBufferCreateIO(writeCallback, NULL, &os, NULL);
- xmlTextWriterPtr xml = xmlNewTextWriter(out);
- if (xml == NULL)
- return false;
- return write(l, xml);
+template<typename R> int writeCallback(void *context, const char* buffer, int len) {
+ XMLWriteContext<R>& cx = *static_cast<XMLWriteContext<R>*>(context);
+ cx.accum = cx.reduce(cx.accum, std::string(buffer, len));
+ return len;
}
/**
- * Callback function called by libxml2 to write to the XML file output stream.
+ * Write a list of values as an XML document.
*/
-int writeFileCallback(void *context, const char* buffer, int len) {
- std::ofstream* os = static_cast<std::ofstream*>(context);
- os->write(buffer, len);
- if (os->fail() || os->bad())
- return -1;
- return len;
+template<typename R> const R writeXML(const lambda<R(R, std::string)>& reduce, const R& initial, const list<value>& l) {
+ XMLWriteContext<R> cx(reduce, initial);
+ xmlOutputBufferPtr out = xmlOutputBufferCreateIO(writeCallback<R>, NULL, &cx, NULL);
+ xmlTextWriterPtr xml = xmlNewTextWriter(out);
+ if (xml != NULL)
+ write(l, xml);
+ return cx.accum;
}
-/**
- * Callback function called by libxml2 to close the XML file output stream.
- */
-int writeCloseFileCallback(void *context) {
- std::ofstream* fos = static_cast<std::ofstream*>(context);
- fos->close();
- return 0;
+const list<std::string> writeXMLList(const list<std::string>& listSoFar, const std::string& s) {
+ return cons(s, listSoFar);
}
/**
- * Write an XML document to a file output stream.
+ * Write a list of values as an XML document represented as a list of strings.
*/
-const bool writeXML(const list<value>& l, std::ofstream& os) {
- xmlOutputBufferPtr out = xmlOutputBufferCreateIO(writeFileCallback, writeCloseFileCallback, &os, NULL);
- xmlTextWriterPtr xml = xmlNewTextWriter(out);
- if (xml == NULL)
- return false;
- return write(l, xml);
+const list<std::string> writeXML(const list<value>& l) {
+ lambda<list<std::string>(list<std::string>, std::string)> writer(writeXMLList);
+ return reverse(writeXML(writer, list<std::string>(), l));
}
}