1 /* document.h
2  * this file is part of libxml++
3  *
4  * copyright (C) 2003 by libxml++ developer's team
5  *
6  * this file is covered by the GNU Lesser General Public License,
7  * which should be included with libxml++ as the file COPYING.
8  */
9 
10 #include <libxml++/io/outputbuffer.h>
11 #include <libxml++/exceptions/internal_error.h>
12 
13 #include <libxml/globals.h> //Needed by libxml/xmlIO.h
14 #include <libxml/xmlIO.h>
15 
16 namespace xmlpp
17 {
18   struct OutputBufferCallback
19   {
on_writexmlpp::OutputBufferCallback20     static int on_write(void * context, const char * buffer, int len)
21     {
22       auto tmp = static_cast<OutputBuffer*>(context);
23       return tmp->on_write(buffer, len)?len:-1;
24     }
25 
on_closexmlpp::OutputBufferCallback26     static int on_close(void * context)
27     {
28       auto tmp = static_cast<OutputBuffer*>(context);
29       return tmp->on_close()?0:-1;
30     }
31   };
32 
33 
OutputBuffer(const Glib::ustring & encoding)34   OutputBuffer::OutputBuffer(
35       const Glib::ustring& encoding)
36   {
37     // we got to initialise the char encoding handler
38     // The code is almost cut/paste from xmlSaveFormatFileEnc
39     // TODO wrap the handler ? I don't think so but...
40 
41     xmlCharEncodingHandlerPtr handler = nullptr;
42     if( ! encoding.empty() )
43     {
44       auto enc = xmlParseCharEncoding(encoding.c_str());
45 
46       // TODO we assume that the source will be UTF-8 encoded. Any user of the class
47       // should pay attention to this.
48 
49       if( enc != XML_CHAR_ENCODING_UTF8 )
50       {
51         handler = xmlFindCharEncodingHandler(encoding.c_str());
52         if(handler == nullptr)
53         {
54           throw internal_error("Cannot initialise an encoder to " + encoding);
55         }
56       }
57     }
58 
59     impl_ = xmlOutputBufferCreateIO(
60         &OutputBufferCallback::on_write,
61         &OutputBufferCallback::on_close,
62         static_cast<void*>(this),
63         handler);
64     if(impl_ == nullptr)
65     {
66       throw internal_error("Cannot initialise underlying xmlOutputBuffer");
67     }
68   }
69 
~OutputBuffer()70   OutputBuffer::~OutputBuffer()
71   {
72   }
73 
on_close()74   bool OutputBuffer::on_close()
75   {
76     bool result = do_close();
77     // the underlying structure is being freed by libxml, the pointer will soon be
78     // invalid.
79     impl_ = nullptr;
80 
81     return result;
82   }
83 
on_write(const char * buffer,int len)84   bool OutputBuffer::on_write(
85       const char * buffer,
86       int len)
87   {
88     return do_write(buffer, len);
89   }
90 
do_close()91   bool OutputBuffer::do_close()
92   {
93     return true;
94   }
95 
cobj()96   _xmlOutputBuffer* OutputBuffer::cobj()
97   {
98     return impl_;
99   }
100 
cobj() const101   const _xmlOutputBuffer* OutputBuffer::cobj() const
102   {
103     return impl_;
104   }
105 
106 }
107