From 71fb4b80593369073dbd5f3c892aef2865c5a2ae Mon Sep 17 00:00:00 2001 From: jsdelfino Date: Mon, 5 Oct 2009 08:21:40 +0000 Subject: 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 --- cpp/sca/kernel/xml.hpp | 125 ++++++++++++++++++++----------------------------- 1 file changed, 50 insertions(+), 75 deletions(-) (limited to 'cpp/sca/kernel/xml.hpp') 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 #include #include -#include -#include #include #include "list.hpp" @@ -158,7 +156,7 @@ const list readList(const list& listSoFar, XMLReader& reader) { } /** - * Read an XML document from a libxml2 XML reader. + * Read a list of values from a libxml2 XML reader. */ const list read(XMLReader& reader) { value nextToken = readToken(reader); @@ -168,49 +166,35 @@ const list 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(context); - is->read(buffer, len); - const int n = is->gcount(); - return n; -} - -/** - * Read an XML document from an input stream. - */ -const list readXML(std::istream& is) { - xmlTextReaderPtr xml = xmlReaderForIO(readCallback, NULL, &is, NULL, NULL, XML_PARSE_NONET); - if (xml == NULL) - return list(); - 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(context); - is->read(buffer, len); - return is->gcount(); -} +class XMLReadContext { +public: + XMLReadContext(const list& ilist) : ilist(ilist) { + } + list 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(context); - fis->close(); - return 0; +int readCallback(void *context, char* buffer, int len) { + XMLReadContext& rc = *static_cast(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 readXML(std::ifstream& is) { - xmlTextReaderPtr xml = xmlReaderForIO(readFileCallback, readCloseFileCallback, &is, NULL, NULL, XML_PARSE_NONET); +const list readXML(const list& ilist) { + XMLReadContext cx(ilist); + xmlTextReaderPtr xml = xmlReaderForIO(readCallback, NULL, &cx, NULL, NULL, XML_PARSE_NONET); if (xml == NULL) return list(); XMLReader reader(xml); @@ -313,7 +297,7 @@ const bool writeList(const list& 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& l, const xmlTextWriterPtr xml) { if (xmlTextWriterStartDocument(xml, NULL, encoding, NULL) < 0) @@ -325,56 +309,47 @@ const bool write(const list& 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(context); - os->write(buffer, len); - if (os->fail() || os->bad()) - return -1; - return len; -} +template class XMLWriteContext { +public: + XMLWriteContext(const lambda& reduce, const R& accum) : reduce(reduce), accum(accum) { + } + const lambda 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& 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 int writeCallback(void *context, const char* buffer, int len) { + XMLWriteContext& cx = *static_cast*>(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(context); - os->write(buffer, len); - if (os->fail() || os->bad()) - return -1; - return len; +template const R writeXML(const lambda& reduce, const R& initial, const list& l) { + XMLWriteContext cx(reduce, initial); + xmlOutputBufferPtr out = xmlOutputBufferCreateIO(writeCallback, 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(context); - fos->close(); - return 0; +const list writeXMLList(const list& 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& 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 writeXML(const list& l) { + lambda(list, std::string)> writer(writeXMLList); + return reverse(writeXML(writer, list(), l)); } } -- cgit v1.2.3