libdap Updated for version 3.21.1
libdap4 is an implementation of OPeNDAP's DAP protocol.
XMLWriter.cc
Go to the documentation of this file.
1
2// This file is part of libdap, A C++ implementation of the OPeNDAP Data
3// Access Protocol.
4
5// Copyright (c) 2010 OPeNDAP, Inc.
6// Author: James Gallagher <jgallagher@opendap.org>
7//
8// This library is free software; you can redistribute it and/or
9// modify it under the terms of the GNU Lesser General Public
10// License as published by the Free Software Foundation; either
11// version 2.1 of the License, or (at your option) any later version.
12//
13// This library is distributed in the hope that it will be useful,
14// but WITHOUT ANY WARRANTY; without even the implied warranty of
15// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16// Lesser General Public License for more details.
17//
18// You should have received a copy of the GNU Lesser General Public
19// License along with this library; if not, write to the Free Software
20// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21//
22// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
23
24/*
25 * XMLWriter.cpp
26 *
27 * Created on: Jul 28, 2010
28 * Author: jimg
29 */
30
31#include "config.h"
32
33#include <libxml/encoding.h>
34#include <libxml/xmlwriter.h>
35
36#include "InternalErr.h"
37#include "XMLWriter.h"
38
39// TODO - Bite the bullet and make the encoding UTF-8 as required by dap4. This will break a lot of tests but the
40// baselines could be amended using a bash script and sed.
41
42const int XML_BUF_SIZE = 2000000;
43
44using namespace libdap;
45
46XMLWriter::XMLWriter(const string &pad, const string &ENCODING) {
47 // LEAK The LIBXML_TEST_VERSION macro leaks 40 bytes according to valgrind
48 // on centos7. jhrg 6/19/19
49 // LIBXML_TEST_VERSION;
50
51 /* Create a new XML buffer, to which the XML document will be
52 * written */
53 try {
54 if (!(d_doc_buf = xmlBufferCreateSize(XML_BUF_SIZE)))
55 throw InternalErr(__FILE__, __LINE__, "Error allocating the xml buffer");
56
57 xmlBufferSetAllocationScheme(d_doc_buf, XML_BUFFER_ALLOC_DOUBLEIT);
58
59 /* Create a new XmlWriter for memory, with no compression.
60 * Remark: there is no compression for this kind of xmlTextWriter */
61 if (!(d_writer = xmlNewTextWriterMemory(d_doc_buf, 0)))
62 throw InternalErr(__FILE__, __LINE__, "Error allocating memory for xml writer");
63
64 if (xmlTextWriterSetIndent(d_writer, pad.length()) < 0)
65 throw InternalErr(__FILE__, __LINE__, "Error starting indentation for response document ");
66
67 if (xmlTextWriterSetIndentString(d_writer, (const xmlChar *)pad.c_str()) < 0)
68 throw InternalErr(__FILE__, __LINE__, "Error setting indentation for response document ");
69
70 d_started = true;
71 d_ended = false;
72
73 /* Start the document with the xml default for the version,
74 * encoding ISO 8859-1 and the default for the standalone
75 * declaration. MY_ENCODING defined at top of this file*/
76 if (xmlTextWriterStartDocument(d_writer, NULL, ENCODING.c_str(), NULL) < 0)
77 throw InternalErr(__FILE__, __LINE__, "Error starting xml response document");
78 } catch (InternalErr &e) {
79 m_cleanup();
80 throw;
81 }
82}
83
84XMLWriter::~XMLWriter() { m_cleanup(); }
85
86void XMLWriter::m_cleanup() {
87 // make sure the buffer and writer are all cleaned up
88 if (d_writer) {
89 xmlFreeTextWriter(d_writer); // This frees both d_writer and d_doc_buf
90 d_writer = 0;
91 // d_doc_buf = 0;
92 }
93
94 // We could be here because of an exception and d_writer might be zero
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 *XMLWriter::get_doc() {
105 if (d_writer && d_started) {
106 if (xmlTextWriterEndDocument(d_writer) < 0)
107 throw InternalErr(__FILE__, __LINE__, "Error ending the document");
108
109 d_ended = true;
110
111 // must call this before getting the buffer content. Odd, but appears to be true.
112 // jhrg
113 xmlFreeTextWriter(d_writer);
114 d_writer = 0;
115 }
116
117 if (!d_doc_buf->content)
118 throw InternalErr(__FILE__, __LINE__, "Error retrieving response document as string");
119
120 return (const char *)d_doc_buf->content;
121}
122
124 if (d_writer && d_started) {
125 if (xmlTextWriterEndDocument(d_writer) < 0)
126 throw InternalErr(__FILE__, __LINE__, "Error ending the document");
127
128 d_ended = true;
129
130 // must call this before getting the buffer content. Odd, but appears to be true.
131 // jhrg
132 xmlFreeTextWriter(d_writer);
133 d_writer = 0;
134 }
135
136 if (!d_doc_buf->content)
137 throw InternalErr(__FILE__, __LINE__, "Error retrieving response document as string");
138
139 // how much of the buffer is in use?
140 return d_doc_buf->use;
141}
const int XML_BUF_SIZE
Definition XMLWriter.cc:42
A class for software fault reporting.
Definition InternalErr.h:61
unsigned int get_doc_size()
Definition XMLWriter.cc:123
const char * get_doc()
Definition XMLWriter.cc:104
virtual ~XMLWriter()
Definition XMLWriter.cc:84
XMLWriter(const std::string &pad=" ", const std::string &ENCODING="ISO-8859-1")
Definition XMLWriter.cc:46
top level DAP object to house generic methods
Definition AISConnect.cc:30