bes Updated for version 3.20.10
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
34const char *ENCODING = "ISO-8859-1";
35// Hack
36const char *HAI_NS = "http://xml.opendap.org/ns/bes/admin/1.0#";
37const int XML_BUF_SIZE = 2000000;
38
39BESXMLWriter::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
82BESXMLWriter::~BESXMLWriter()
83{
84 m_cleanup();
85}
86
87void 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
104const 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}
exception thrown if an internal error is found and is fatal to the BES