libdap++  Updated for version 3.8.2
XMLWriter.cc
Go to the documentation of this file.
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 }