bes  Updated for version 3.20.6
BESXMLWriter.cc
1 /*
2  * BESXMLWriter.cpp
3  *
4  * Created on: Jul 28, 2010
5  * Author: jimg
6  */
7 
8 // Copyright (c) 2013 OPeNDAP, Inc. Author: James Gallagher
9 // <jgallagher@opendap.org>, Patrick West <pwest@opendap.org>
10 // Nathan Potter <npotter@opendap.org>
11 //
12 // modify it under the terms of the GNU Lesser General Public License
13 // as published by the Free Software Foundation; either version 2.1 of
14 // the License, or (at your option) any later version.
15 //
16 // This library is distributed in the hope that it will be useful, but
17 // WITHOUT ANY WARRANTY; without even the implied warranty of
18 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 // Lesser General Public License for more details.
20 //
21 // License along with this library; if not, write to the Free Software
22 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
23 // 02110-1301 U\ SA
24 //
25 // You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI.
26 // 02874-0112.
27 #include "BESXMLWriter.h"
28 
29 #include <libxml/encoding.h>
30 #include <libxml/xmlwriter.h>
31 
32 #include <BESInternalFatalError.h>
33 
34 const char *ENCODING = "ISO-8859-1";
35 // Hack
36 const char *HAI_NS = "http://xml.opendap.org/ns/bes/admin/1.0#";
37 const int XML_BUF_SIZE = 2000000;
38 
39 BESXMLWriter::BESXMLWriter() // : d_ns_uri(HAI_NS)
40 {
41  LIBXML_TEST_VERSION;
42 
43  /* Create a new XML buffer, to which the XML document will be
44  * written */
45  try {
46  if (!(d_doc_buf = xmlBufferCreateSize(XML_BUF_SIZE)))
47  throw BESInternalFatalError("Error allocating the xml buffer", __FILE__, __LINE__);
48 
49  xmlBufferSetAllocationScheme(d_doc_buf, XML_BUFFER_ALLOC_DOUBLEIT);
50 
51  /* Create a new XmlWriter for memory, with no compression.
52  * Remark: there is no compression for this kind of xmlTextWriter */
53  if (!(d_writer = xmlNewTextWriterMemory(d_doc_buf, 0)))
54  throw BESInternalFatalError("Error allocating memory for xml writer", __FILE__, __LINE__);
55 
56  if (xmlTextWriterSetIndent(d_writer, 4) < 0)
57  throw BESInternalFatalError("Error starting indentation for response document ", __FILE__, __LINE__);
58 
59  if (xmlTextWriterSetIndentString(d_writer, (const xmlChar*) " ") < 0)
60  throw BESInternalFatalError("Error setting indentation for response document ", __FILE__, __LINE__);
61 
62  d_started = true;
63  d_ended = false;
64 
65  /* Start the document with the xml default for the version,
66  * encoding ISO 8859-1 and the default for the standalone
67  * declaration. MY_ENCODING defined at top of this file*/
68  if (xmlTextWriterStartDocument(d_writer, NULL, ENCODING, NULL) < 0)
69  throw BESInternalFatalError("Error starting xml response document", __FILE__, __LINE__);
70 
71  /* Start an element named "Dataset". Since this is the first element,
72  * this will be the root element of the document */
73  if (xmlTextWriterStartElementNS(d_writer, (const xmlChar*) "hai", (const xmlChar*) "BesAdminCmd", (const xmlChar*) HAI_NS) < 0)
74  throw BESInternalFatalError("Error starting the response element for response ", __FILE__, __LINE__);
75  }
76  catch (BESInternalFatalError &e) {
77  m_cleanup();
78  throw;
79  }
80 }
81 
82 BESXMLWriter::~BESXMLWriter()
83 {
84  m_cleanup();
85 }
86 
87 void BESXMLWriter::m_cleanup()
88 {
89  // make sure the buffer and writer are all cleaned up
90  if (d_writer) {
91  xmlFreeTextWriter(d_writer);
92  d_writer = 0;
93  //d_doc_buf = 0;
94  }
95  if (d_doc_buf) {
96  xmlBufferFree(d_doc_buf);
97  d_doc_buf = 0;
98  }
99 
100  d_started = false;
101  d_ended = false;
102 }
103 
104 const char *BESXMLWriter::get_doc()
105 {
106  if (d_writer && d_started) {
107  // this should end the response element
108  if (xmlTextWriterEndElement(d_writer) < 0)
109  throw BESInternalFatalError("Error ending Dataset element.", __FILE__, __LINE__);
110 
111  if (xmlTextWriterEndDocument(d_writer) < 0)
112  throw BESInternalFatalError("Error ending the document", __FILE__, __LINE__);
113 
114  d_ended = true;
115 
116  // must call this before getting the buffer content. Odd, but appears to be true.
117  // jhrg
118  xmlFreeTextWriter(d_writer);
119  d_writer = 0;
120  }
121 
122  // get the xml document as a string and return
123  if (!d_doc_buf->content)
124  throw BESInternalFatalError("Error retrieving response document as string", __FILE__, __LINE__);
125 
126  return (const char *) d_doc_buf->content;
127 }
BESInternalFatalError
exception thrown if an internal error is found and is fatal to the BES
Definition: BESInternalFatalError.h:43