libdap++
Updated for version 3.8.2
|
00001 /* 00002 * XMLWriter.cpp 00003 * 00004 * Created on: Jul 28, 2010 00005 * Author: jimg 00006 */ 00007 00008 #include "XMLWriter.h" 00009 00010 #include <libxml/encoding.h> 00011 #include <libxml/xmlwriter.h> 00012 00013 #include <InternalErr.h> 00014 00015 const char *ENCODING = "ISO-8859-1"; 00016 const int XML_BUF_SIZE = 2000000; 00017 00018 using namespace libdap; 00019 00020 XMLWriter::XMLWriter(const string &pad) { 00021 LIBXML_TEST_VERSION; 00022 00023 /* Create a new XML buffer, to which the XML document will be 00024 * written */ 00025 try { 00026 if (!(d_doc_buf = xmlBufferCreateSize(XML_BUF_SIZE))) 00027 throw InternalErr(__FILE__, __LINE__, "Error allocating the xml buffer"); 00028 00029 xmlBufferSetAllocationScheme(d_doc_buf, XML_BUFFER_ALLOC_DOUBLEIT); 00030 00031 /* Create a new XmlWriter for memory, with no compression. 00032 * Remark: there is no compression for this kind of xmlTextWriter */ 00033 if (!(d_writer = xmlNewTextWriterMemory(d_doc_buf, 0))) 00034 throw InternalErr(__FILE__, __LINE__, "Error allocating memory for xml writer"); 00035 00036 if (xmlTextWriterSetIndent(d_writer, pad.length()) < 0) 00037 throw InternalErr(__FILE__, __LINE__, "Error starting indentation for response document "); 00038 00039 if (xmlTextWriterSetIndentString(d_writer, (const xmlChar*)pad.c_str()) < 0) 00040 throw InternalErr(__FILE__, __LINE__, "Error setting indentation for response document "); 00041 00042 d_started = true; 00043 d_ended = false; 00044 00045 /* Start the document with the xml default for the version, 00046 * encoding ISO 8859-1 and the default for the standalone 00047 * declaration. MY_ENCODING defined at top of this file*/ 00048 if (xmlTextWriterStartDocument(d_writer, NULL, ENCODING, NULL) < 0) 00049 throw InternalErr(__FILE__, __LINE__, "Error starting xml response document"); 00050 } 00051 catch (InternalErr &e) { 00052 m_cleanup(); 00053 throw; 00054 } 00055 00056 } 00057 00058 XMLWriter::~XMLWriter() { 00059 m_cleanup(); 00060 } 00061 00062 void XMLWriter::m_cleanup() { 00063 // make sure the buffer and writer are all cleaned up 00064 if (d_writer) { 00065 xmlFreeTextWriter(d_writer); // This frees both d_writer and d_doc_buf 00066 d_writer = 0; 00067 // d_doc_buf = 0; 00068 } 00069 00070 // We could be here because of an exception and d_writer might be zero 00071 if (d_doc_buf) { 00072 xmlBufferFree(d_doc_buf); 00073 d_doc_buf = 0; 00074 } 00075 00076 d_started = false; 00077 d_ended = false; 00078 } 00079 00080 const char *XMLWriter::get_doc() { 00081 if (d_writer && d_started) { 00082 if (xmlTextWriterEndDocument(d_writer) < 0) 00083 throw InternalErr(__FILE__, __LINE__, "Error ending the document"); 00084 00085 d_ended = true; 00086 00087 // must call this before getting the buffer content. Odd, but appears to be true. 00088 // jhrg 00089 xmlFreeTextWriter(d_writer); 00090 d_writer = 0; 00091 } 00092 00093 if (!d_doc_buf->content) 00094 throw InternalErr(__FILE__, __LINE__, "Error retrieving response document as string"); 00095 #if 0 00096 // This is not needed when the TextWriter is freed before getting buffer content. 00097 if (xmlTextWriterFlush(d_writer) < 0) 00098 throw InternalErr(__FILE__, __LINE__, "Error flushing the xml writer buffer"); 00099 #endif 00100 00101 return (const char *)d_doc_buf->content; 00102 }