InputSource.h
1 /*
2  * Copyright (C) 2012 Marc Boris Duerner
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * As a special exception, you may use this file as part of a free
10  * software library without restriction. Specifically, if other files
11  * instantiate templates or use macros or inline functions from this
12  * file, or you compile this file and link it with other files to
13  * produce an executable, this file does not by itself cause the
14  * resulting executable to be covered by the GNU General Public
15  * License. This exception does not however invalidate any other
16  * reasons why the executable file might be covered by the GNU Library
17  * General Public License.
18  *
19  * This library is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22  * Lesser General Public License for more details.
23  *
24  * You should have received a copy of the GNU Lesser General Public
25  * License along with this library; if not, write to the Free Software
26  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
27  */
28 
29 #ifndef Pt_Xml_InputSource_h
30 #define Pt_Xml_InputSource_h
31 
32 #include <Pt/Xml/Api.h>
33 #include <Pt/Xml/ByteorderMark.h>
34 #include <Pt/Xml/XmlDeclaration.h>
35 #include <Pt/NonCopyable.h>
36 #include <Pt/TextBuffer.h>
37 #include <Pt/TextStream.h>
38 #include <Pt/Utf8Codec.h>
39 #include <Pt/StringStream.h>
40 #include <Pt/String.h>
41 #include <streambuf>
42 #include <iostream>
43 #include <string>
44 #include <cstddef>
45 
46 namespace Pt {
47 
48 namespace Xml {
49 
50 class XmlResolver;
51 
60 class InputSource : private NonCopyable
61 {
62  public:
63  typedef std::char_traits<Char>::int_type int_type;
64 
65  public:
69  : _rdbuf(0)
70  , _line(1)
71  , _decl(0)
72  {}
73 
76  virtual ~InputSource()
77  {}
78 
81  std::size_t line() const
82  { return _line; }
83 
86  void setLine(std::size_t n)
87  { _line = n; }
88 
96  inline std::streamsize import()
97  {
98  std::streamsize r = 0;
99  return (_rdbuf && (r =_rdbuf->in_avail()) > 0) ? r
100  : onImport();
101  }
102 
105  inline int_type get()
106  {
107  return _rdbuf ? _rdbuf->sbumpc()
108  : onGet();
109  }
110 
114  { return _decl; }
115 
118  const Pt::String& id() const
119  { return onId(); }
120 
121  protected:
131  void init(std::basic_streambuf<Char>* rdbuf = 0, XmlDeclaration* decl = 0)
132  {
133  _line = 0;
134  _rdbuf = rdbuf;
135  _decl = decl;
136  }
137 
140  virtual std::streamsize onImport() = 0;
141 
144  virtual int_type onGet() = 0;
145 
146  // NOTE: EntityStream returns a reference to the entity name
149  virtual const Pt::String& onId() const = 0;
150 
151  private:
152  std::basic_streambuf<Char>* _rdbuf;
153  std::size_t _line;
154  XmlDeclaration* _decl;
155 };
156 
162 class PT_XML_API TextInputSource : public InputSource
163 {
164  public:
167  TextInputSource();
168 
171  explicit TextInputSource(std::basic_istream<Char>& is);
172 
175  ~TextInputSource();
176 
179  void reset();
180 
183  void reset(std::basic_istream<Char>& ios);
184 
187  void setId(const Pt::String& id);
188 
189  protected:
190  // inherit docs
191  virtual std::streamsize onImport();
192 
193  // inherit docs
194  virtual int_type onGet();
195 
196  // inherit docs
197  const Pt::String& onId() const;
198 
201  virtual bool onImportText();
202 
203  private:
205  bool onParseXml(int_type c);
206 
207  private:
208  std::basic_istream<Char>* _ios;
209  XmlDeclaration _xmlDecl;
210  Pt::String _id;
211  unsigned char _xmlState;
212  const char* _pbBegin;
213  const char* _pbEnd;
214 };
215 
221 class PT_XML_API StringInputSource : public TextInputSource
222 {
223  public:
226  StringInputSource(const String& str);
227 
231 
232  protected:
233  // inherit docs
234  virtual bool onImportText();
235 
236  private:
237  StringStream _ss;
238 };
239 
248 class PT_XML_API BinaryInputSource : public InputSource
249 {
250  public:
254 
257  explicit BinaryInputSource(std::istream& is);
258 
261  explicit BinaryInputSource(XmlResolver& resolver);
262 
265  BinaryInputSource(XmlResolver& resolver, std::istream& is);
266 
270 
273  void reset();
274 
277  void reset(std::istream& is);
278 
281  void setId(const Pt::String& id);
282 
283  protected:
284  // inherit docs
285  virtual std::streamsize onImport();
286 
287  // inherit docs
288  virtual int_type onGet();
289 
290  // inherit docs
291  const Pt::String& onId() const;
292 
295  virtual bool onImportData();
296 
297  private:
299  bool onParseBom(unsigned char c);
300 
302  bool onParseXml(int c);
303 
305  void onDeclaration();
306 
307  private:
308  XmlResolver* _resolver;
309  std::istream* _is;
310  Utf8Codec _utf8Codec;
311  MBState _mbState;
312  TextBuffer _tbuf;
313  Pt::String _id;
314  ByteorderMark _bom;
315  XmlDeclaration _xmlDecl;
316  unsigned char _bomState;
317  unsigned char _xmlState;
318  const char* _pbBegin;
319  const char* _pbEnd;
320 };
321 
324 class NullInputSource : public InputSource
325 {
326  public:
327  explicit NullInputSource()
328  : InputSource()
329  { }
330 
331  protected:
332  virtual std::streamsize onImport()
333  { return -1; }
334 
335  virtual int_type onGet()
336  { return std::char_traits<Char>::eof(); }
337 
338  const Pt::String& onId() const
339  { return _id; }
340 
341  private:
342  Pt::String _id;
343 };
344 
345 } // namespace Xml
346 
347 } // namespace Pt
348 
349 #endif // Pt_Xml_InputSource_h
XML byte order mark.
Definition: ByteorderMark.h:40
Converts character sequences with different encodings.
Input source for the XML reader.
Definition: InputSource.h:60
const Pt::String & id() const
Returns the ID of the input stream.
Definition: InputSource.h:118
Protects derived classes from being copied.
Definition: NonCopyable.h:54
const XmlDeclaration * declaration() const
Returns the XML declaration or a nullptr if none was read.
Definition: InputSource.h:113
virtual const Pt::String & onId() const =0
Returns the ID of the input stream.
XML declaration of an XML document.
Definition: XmlDeclaration.h:42
virtual std::streamsize onImport()=0
Refills the stream buffer.
Unicode string stream.
Text input source for the XML reader.
Definition: InputSource.h:162
virtual int_type onGet()=0
Returns the next character or EOF.
void setLine(std::size_t n)
Sets the current line count.
Definition: InputSource.h:86
void init(std::basic_streambuf< Char > *rdbuf=0, XmlDeclaration *decl=0)
Initialize to use an input buffer and XML declaration.
Definition: InputSource.h:131
Binary input source for the XML reader.
Definition: InputSource.h:248
std::size_t line() const
Current line count.
Definition: InputSource.h:81
Unicode capable basic_string.
Definition: String.h:42
Resolves external entities and DTDs.
Definition: XmlResolver.h:53
InputSource()
Construct an empty InputSource.
Definition: InputSource.h:68
virtual ~InputSource()
Destructor.
Definition: InputSource.h:76
String input source for the XML reader.
Definition: InputSource.h:221
Convert between unicode and UTF-8.
Definition: Utf8Codec.h:43