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