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
|
// 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 <libxml/encoding.h>
#include <libxml/xmlwriter.h>
#include "XMLWriter.h"
#include "InternalErr.h"
// TODO - Bite the bullet and make the encoding UTF-8 as required by dap4. This will break a lot of tests but the baselines could be amended using a bash script and sed.
const char *ENCODING = "ISO-8859-1";
const int XML_BUF_SIZE = 2000000;
using namespace libdap;
XMLWriter::XMLWriter(const string &pad) {
// LEAK The LIBXML_TEST_VERSION macro leaks 40 bytes according to valgrind
// on centos7. jhrg 6/19/19
// 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");
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");
// how much of the buffer is in use?
return d_doc_buf->use;
}
|