OPeNDAP Hyrax Back End Server (BES)  Updated for version 3.8.3
BESXMLWriter.cc
Go to the documentation of this file.
1 /*
2  * BESXMLWriter.cpp
3  *
4  * Created on: Jul 28, 2010
5  * Author: jimg
6  */
7 
8 #include "BESXMLWriter.h"
9 
10 #include <libxml/encoding.h>
11 #include <libxml/xmlwriter.h>
12 
13 #include <BESInternalFatalError.h>
14 
15 const char *ENCODING = "ISO-8859-1";
16 // Hack
17 const char *HAI_NS = "http://xml.opendap.org/ns/bes/admin/1.0#";
18 const int XML_BUF_SIZE = 2000000;
19 
20 BESXMLWriter::BESXMLWriter() // : d_ns_uri(HAI_NS)
21 {
22  LIBXML_TEST_VERSION;
23 
24  /* Create a new XML buffer, to which the XML document will be
25  * written */
26  try {
27  if (!(d_doc_buf = xmlBufferCreateSize(XML_BUF_SIZE)))
28  throw BESInternalFatalError("Error allocating the xml buffer", __FILE__, __LINE__);
29 
30  xmlBufferSetAllocationScheme(d_doc_buf, XML_BUFFER_ALLOC_DOUBLEIT);
31 
32  /* Create a new XmlWriter for memory, with no compression.
33  * Remark: there is no compression for this kind of xmlTextWriter */
34  if (!(d_writer = xmlNewTextWriterMemory(d_doc_buf, 0)))
35  throw BESInternalFatalError("Error allocating memory for xml writer", __FILE__, __LINE__);
36 
37  if (xmlTextWriterSetIndent(d_writer, 4) < 0)
38  throw BESInternalFatalError("Error starting indentation for response document ", __FILE__, __LINE__);
39 
40  if (xmlTextWriterSetIndentString(d_writer, (const xmlChar*) " ") < 0)
41  throw BESInternalFatalError("Error setting indentation for response document ", __FILE__, __LINE__);
42 
43  d_started = true;
44  d_ended = false;
45 
46  /* Start the document with the xml default for the version,
47  * encoding ISO 8859-1 and the default for the standalone
48  * declaration. MY_ENCODING defined at top of this file*/
49  if (xmlTextWriterStartDocument(d_writer, NULL, ENCODING, NULL) < 0)
50  throw BESInternalFatalError("Error starting xml response document", __FILE__, __LINE__);
51 
52  /* Start an element named "Dataset". Since this is the first element,
53  * this will be the root element of the document */
54  if (xmlTextWriterStartElementNS(d_writer, (const xmlChar*) "hai", (const xmlChar*) "BesAdminCmd", (const xmlChar*) HAI_NS) < 0)
55  throw BESInternalFatalError("Error starting the response element for response ", __FILE__, __LINE__);
56  }
57  catch (BESInternalFatalError &e) {
58  m_cleanup();
59  throw;
60  }
61 }
62 
64 {
65  m_cleanup();
66 }
67 
68 void BESXMLWriter::m_cleanup()
69 {
70  // make sure the buffer and writer are all cleaned up
71  if (d_writer) {
72  xmlFreeTextWriter(d_writer);
73  d_writer = 0;
74  //d_doc_buf = 0;
75  }
76  if (d_doc_buf) {
77  xmlBufferFree(d_doc_buf);
78  d_doc_buf = 0;
79  }
80 
81  d_started = false;
82  d_ended = false;
83 }
84 
85 const char *BESXMLWriter::get_doc()
86 {
87  if (d_writer && d_started) {
88  // this should end the response element
89  if (xmlTextWriterEndElement(d_writer) < 0)
90  throw BESInternalFatalError("Error ending Dataset element.", __FILE__, __LINE__);
91 
92  if (xmlTextWriterEndDocument(d_writer) < 0)
93  throw BESInternalFatalError("Error ending the document", __FILE__, __LINE__);
94 
95  d_ended = true;
96 
97  // must call this before getting the buffer content. Odd, but appears to be true.
98  // jhrg
99  xmlFreeTextWriter(d_writer);
100  d_writer = 0;
101  }
102 
103  // get the xml document as a string and return
104  if (!d_doc_buf->content)
105  throw BESInternalFatalError("Error retrieving response document as string", __FILE__, __LINE__);
106 
107  return (const char *) d_doc_buf->content;
108 }
exception thrown if an internal error is found and is fatal to the BES
const char * HAI_NS
Definition: BESXMLWriter.cc:17
const char * get_doc()
Definition: BESXMLWriter.cc:85
const char * ENCODING
Definition: BESXMLWriter.cc:15
const int XML_BUF_SIZE
Definition: BESXMLWriter.cc:18
virtual ~BESXMLWriter()
Definition: BESXMLWriter.cc:63