libdap
Updated for version 3.17.0
|
00001 00002 // This file is part of libdap, A C++ implementation of the OPeNDAP Data 00003 // Access Protocol. 00004 00005 // Copyright (c) 2010 OPeNDAP, Inc. 00006 // Author: James Gallagher <jgallagher@opendap.org> 00007 // 00008 // This library is free software; you can redistribute it and/or 00009 // modify it under the terms of the GNU Lesser General Public 00010 // License as published by the Free Software Foundation; either 00011 // version 2.1 of the License, or (at your option) any later version. 00012 // 00013 // This library is distributed in the hope that it will be useful, 00014 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00016 // Lesser General Public License for more details. 00017 // 00018 // You should have received a copy of the GNU Lesser General Public 00019 // License along with this library; if not, write to the Free Software 00020 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00021 // 00022 // You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112. 00023 00024 /* 00025 * XMLWriter.cpp 00026 * 00027 * Created on: Jul 28, 2010 00028 * Author: jimg 00029 */ 00030 00031 #include "config.h" 00032 00033 #include <libxml/encoding.h> 00034 #include <libxml/xmlwriter.h> 00035 00036 #include "XMLWriter.h" 00037 #include "InternalErr.h" 00038 00039 const char *ENCODING = "ISO-8859-1"; 00040 const int XML_BUF_SIZE = 2000000; 00041 00042 using namespace libdap; 00043 00044 XMLWriter::XMLWriter(const string &pad) { 00045 LIBXML_TEST_VERSION; 00046 00047 /* Create a new XML buffer, to which the XML document will be 00048 * written */ 00049 try { 00050 if (!(d_doc_buf = xmlBufferCreateSize(XML_BUF_SIZE))) 00051 throw InternalErr(__FILE__, __LINE__, "Error allocating the xml buffer"); 00052 00053 xmlBufferSetAllocationScheme(d_doc_buf, XML_BUFFER_ALLOC_DOUBLEIT); 00054 00055 /* Create a new XmlWriter for memory, with no compression. 00056 * Remark: there is no compression for this kind of xmlTextWriter */ 00057 if (!(d_writer = xmlNewTextWriterMemory(d_doc_buf, 0))) 00058 throw InternalErr(__FILE__, __LINE__, "Error allocating memory for xml writer"); 00059 00060 if (xmlTextWriterSetIndent(d_writer, pad.length()) < 0) 00061 throw InternalErr(__FILE__, __LINE__, "Error starting indentation for response document "); 00062 00063 if (xmlTextWriterSetIndentString(d_writer, (const xmlChar*)pad.c_str()) < 0) 00064 throw InternalErr(__FILE__, __LINE__, "Error setting indentation for response document "); 00065 00066 d_started = true; 00067 d_ended = false; 00068 00069 /* Start the document with the xml default for the version, 00070 * encoding ISO 8859-1 and the default for the standalone 00071 * declaration. MY_ENCODING defined at top of this file*/ 00072 if (xmlTextWriterStartDocument(d_writer, NULL, ENCODING, NULL) < 0) 00073 throw InternalErr(__FILE__, __LINE__, "Error starting xml response document"); 00074 } 00075 catch (InternalErr &e) { 00076 m_cleanup(); 00077 throw; 00078 } 00079 00080 } 00081 00082 XMLWriter::~XMLWriter() { 00083 m_cleanup(); 00084 } 00085 00086 void XMLWriter::m_cleanup() { 00087 // make sure the buffer and writer are all cleaned up 00088 if (d_writer) { 00089 xmlFreeTextWriter(d_writer); // This frees both d_writer and d_doc_buf 00090 d_writer = 0; 00091 // d_doc_buf = 0; 00092 } 00093 00094 // We could be here because of an exception and d_writer might be zero 00095 if (d_doc_buf) { 00096 xmlBufferFree(d_doc_buf); 00097 d_doc_buf = 0; 00098 } 00099 00100 d_started = false; 00101 d_ended = false; 00102 } 00103 00104 const char *XMLWriter::get_doc() { 00105 if (d_writer && d_started) { 00106 if (xmlTextWriterEndDocument(d_writer) < 0) 00107 throw InternalErr(__FILE__, __LINE__, "Error ending the document"); 00108 00109 d_ended = true; 00110 00111 // must call this before getting the buffer content. Odd, but appears to be true. 00112 // jhrg 00113 xmlFreeTextWriter(d_writer); 00114 d_writer = 0; 00115 } 00116 00117 if (!d_doc_buf->content) 00118 throw InternalErr(__FILE__, __LINE__, "Error retrieving response document as string"); 00119 00120 return (const char *)d_doc_buf->content; 00121 } 00122 00123 unsigned int XMLWriter::get_doc_size() { 00124 if (d_writer && d_started) { 00125 if (xmlTextWriterEndDocument(d_writer) < 0) 00126 throw InternalErr(__FILE__, __LINE__, "Error ending the document"); 00127 00128 d_ended = true; 00129 00130 // must call this before getting the buffer content. Odd, but appears to be true. 00131 // jhrg 00132 xmlFreeTextWriter(d_writer); 00133 d_writer = 0; 00134 } 00135 00136 if (!d_doc_buf->content) 00137 throw InternalErr(__FILE__, __LINE__, "Error retrieving response document as string"); 00138 00139 // how much of the buffer is in use? 00140 return d_doc_buf->use; 00141 }