libdap++  Updated for version 3.11.7
XMLWriter.cc
Go to the documentation of this file.
1 /*
2  * XMLWriter.cpp
3  *
4  * Created on: Jul 28, 2010
5  * Author: jimg
6  */
7 
8 #include "XMLWriter.h"
9 
10 #include <libxml/encoding.h>
11 #include <libxml/xmlwriter.h>
12 
13 #include <InternalErr.h>
14 
15 const char *ENCODING = "ISO-8859-1";
16 const int XML_BUF_SIZE = 2000000;
17 
18 using namespace libdap;
19 
20 XMLWriter::XMLWriter(const string &pad) {
21  LIBXML_TEST_VERSION;
22 
23  /* Create a new XML buffer, to which the XML document will be
24  * written */
25  try {
26  if (!(d_doc_buf = xmlBufferCreateSize(XML_BUF_SIZE)))
27  throw InternalErr(__FILE__, __LINE__, "Error allocating the xml buffer");
28 
29  xmlBufferSetAllocationScheme(d_doc_buf, XML_BUFFER_ALLOC_DOUBLEIT);
30 
31  /* Create a new XmlWriter for memory, with no compression.
32  * Remark: there is no compression for this kind of xmlTextWriter */
33  if (!(d_writer = xmlNewTextWriterMemory(d_doc_buf, 0)))
34  throw InternalErr(__FILE__, __LINE__, "Error allocating memory for xml writer");
35 
36  if (xmlTextWriterSetIndent(d_writer, pad.length()) < 0)
37  throw InternalErr(__FILE__, __LINE__, "Error starting indentation for response document ");
38 
39  if (xmlTextWriterSetIndentString(d_writer, (const xmlChar*)pad.c_str()) < 0)
40  throw InternalErr(__FILE__, __LINE__, "Error setting indentation for response document ");
41 
42  d_started = true;
43  d_ended = false;
44 
45  /* Start the document with the xml default for the version,
46  * encoding ISO 8859-1 and the default for the standalone
47  * declaration. MY_ENCODING defined at top of this file*/
48  if (xmlTextWriterStartDocument(d_writer, NULL, ENCODING, NULL) < 0)
49  throw InternalErr(__FILE__, __LINE__, "Error starting xml response document");
50  }
51  catch (InternalErr &e) {
52  m_cleanup();
53  throw;
54  }
55 
56 }
57 
59  m_cleanup();
60 }
61 
62 void XMLWriter::m_cleanup() {
63  // make sure the buffer and writer are all cleaned up
64  if (d_writer) {
65  xmlFreeTextWriter(d_writer); // This frees both d_writer and d_doc_buf
66  d_writer = 0;
67  // d_doc_buf = 0;
68  }
69 
70  // We could be here because of an exception and d_writer might be zero
71  if (d_doc_buf) {
72  xmlBufferFree(d_doc_buf);
73  d_doc_buf = 0;
74  }
75 
76  d_started = false;
77  d_ended = false;
78 }
79 
80 const char *XMLWriter::get_doc() {
81  if (d_writer && d_started) {
82  if (xmlTextWriterEndDocument(d_writer) < 0)
83  throw InternalErr(__FILE__, __LINE__, "Error ending the document");
84 
85  d_ended = true;
86 
87  // must call this before getting the buffer content. Odd, but appears to be true.
88  // jhrg
89  xmlFreeTextWriter(d_writer);
90  d_writer = 0;
91  }
92 
93  if (!d_doc_buf->content)
94  throw InternalErr(__FILE__, __LINE__, "Error retrieving response document as string");
95 #if 0
96  // This is not needed when the TextWriter is freed before getting buffer content.
97  if (xmlTextWriterFlush(d_writer) < 0)
98  throw InternalErr(__FILE__, __LINE__, "Error flushing the xml writer buffer");
99 #endif
100 
101  return (const char *)d_doc_buf->content;
102 }