add new sigc++2 directory
[ardour.git] / libs / glibmm2 / glib / glibmm / markup.h
1 // -*- c++ -*-
2 // Generated by gtkmmproc -- DO NOT MODIFY!
3 #ifndef _GLIBMM_MARKUP_H
4 #define _GLIBMM_MARKUP_H
5
6
7 /* $Id: markup.hg,v 1.5 2005/01/21 12:48:05 murrayc Exp $ */
8
9 /* Copyright (C) 2002 The gtkmm Development Team
10  *
11  * This library is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU Library General Public
13  * License as published by the Free Software Foundation; either
14  * version 2 of the License, or (at your option) any later version.
15  *
16  * This library is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
19  * Library General Public License for more details.
20  *
21  * You should have received a copy of the GNU Library General Public
22  * License along with this library; if not, write to the Free
23  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24  */
25
26
27 #include <glibmm/error.h>
28 #include <sigc++/sigc++.h>
29
30 #include <map>
31 #include <glibmmconfig.h>
32
33 GLIBMM_USING_STD(map)
34
35 #ifndef DOXYGEN_SHOULD_SKIP_THIS
36 extern "C" { typedef struct _GMarkupParseContext GMarkupParseContext; }
37 #endif
38
39
40 namespace Glib
41 {
42
43 /** @defgroup Markup Simple XML Subset Parser
44  *
45  * The Glib::Markup parser is intended to parse a simple markup format that's a
46  * subset of XML. This is a small, efficient, easy-to-use parser. It should not
47  * be used if you expect to interoperate with other applications generating
48  * full-scale XML. However, it's very useful for application data files, config
49  * files, etc. where you know your application will be the only one writing the
50  * file. Full-scale XML parsers should be able to parse the subset used by
51  * Glib::Markup parser, so you can easily migrate to full-scale XML at a later
52  * time if the need arises.
53  *
54  * Glib::Markup is not guaranteed to signal an error on all invalid XML;
55  * the parser may accept documents that an XML parser would not. However,
56  * invalid XML documents are not considered valid Glib::Markup documents.
57  *
58  * @par Simplifications to XML include:
59  *
60  * - Only UTF-8 encoding is allowed.
61  * - No user-defined entities.
62  * - Processing instructions, comments and the doctype declaration are "passed
63  *   through" but are not interpreted in any way.
64  * - No DTD or validation.
65  *
66  * @par The markup format does support:
67  *
68  * - Elements
69  * - Attributes
70  * - 5 standard entities: <tt>\&amp; \&lt; \&gt; \&quot; \&apos;</tt>
71  * - Character references
72  * - Sections marked as <tt>CDATA</tt>
73  *
74  * @{
75  */
76
77 /** %Exception class for markup parsing errors.
78  */
79 class MarkupError : public Glib::Error
80 {
81 public:
82   enum Code
83   {
84     BAD_UTF8,
85     EMPTY,
86     PARSE,
87     UNKNOWN_ELEMENT,
88     UNKNOWN_ATTRIBUTE,
89     INVALID_CONTENT
90   };
91
92   MarkupError(Code error_code, const Glib::ustring& error_message);
93   explicit MarkupError(GError* gobject);
94   Code code() const;
95
96 #ifndef DOXYGEN_SHOULD_SKIP_THIS
97 private:
98
99 #ifdef GLIBMM_EXCEPTIONS_ENABLED
100   static void throw_func(GError* gobject);
101 #else
102   //When not using exceptions, we just pass the Exception object around without throwing it:
103   static std::auto_ptr<Glib::Error> throw_func(GError* gobject);
104 #endif //GLIBMM_EXCEPTIONS_ENABLED
105
106   friend void wrap_init(); // uses throw_func()
107 #endif
108 };
109
110
111 /*! @var MarkupError::Code MarkupError::BAD_UTF8
112  * Text being parsed was not valid UTF-8.
113  */
114 /*! @var MarkupError::Code MarkupError::EMPTY
115  * Document contained nothing, or only whitespace.
116  */
117 /*! @var MarkupError::Code MarkupError::PARSE
118  * Document was ill-formed.
119  */
120 /*! @var MarkupError::Code MarkupError::UNKNOWN_ELEMENT
121  * This error should be set by Glib::Markup::Parser virtual methods;
122  * element wasn't known.
123  */
124 /*! @var MarkupError::Code MarkupError::UNKNOWN_ATTRIBUTE
125  * This error should be set by Glib::Markup::Parser virtual methods;
126  * attribute wasn't known.
127  */
128 /*! @var MarkupError::Code MarkupError::INVALID_CONTENT
129  * This error should be set by Glib::Markup::Parser virtual methods;
130  * something was wrong with contents of the document, e.g. invalid attribute value.
131  */
132
133 /** @} group Markup */
134
135
136 namespace Markup
137 {
138
139 class ParseContext;
140
141 /** @ingroup Markup */
142 typedef Glib::MarkupError Error;
143
144
145 /** Escapes text so that the markup parser will parse it verbatim.
146  * Less than, greater than, ampersand, etc. are replaced with the corresponding
147  * entities.  This function would typically be used when writing out a file to
148  * be parsed with the markup parser.
149  * @ingroup Markup
150  * @param text Some valid UTF-8 text.
151  * @return Escaped text.
152  */
153 Glib::ustring escape_text(const Glib::ustring& text);
154
155
156 /** There are no flags right now. Pass <tt>Glib::Markup::ParseFlags(0)</tt> for
157  * the flags argument to all functions (this should be the default argument
158  * anyway).
159  */
160 /** @addtogroup glibmmEnums Enums and Flags */
161
162 /**
163  * @ingroup glibmmEnums
164  * @par Bitwise operators:
165  * <tt>%ParseFlags operator|(ParseFlags, ParseFlags)</tt><br>
166  * <tt>%ParseFlags operator&(ParseFlags, ParseFlags)</tt><br>
167  * <tt>%ParseFlags operator^(ParseFlags, ParseFlags)</tt><br>
168  * <tt>%ParseFlags operator~(ParseFlags)</tt><br>
169  * <tt>%ParseFlags& operator|=(ParseFlags&, ParseFlags)</tt><br>
170  * <tt>%ParseFlags& operator&=(ParseFlags&, ParseFlags)</tt><br>
171  * <tt>%ParseFlags& operator^=(ParseFlags&, ParseFlags)</tt><br>
172  */
173 enum ParseFlags
174 {
175   DO_NOT_USE_THIS_UNSUPPORTED_FLAG = 1 << 0,
176   TREAT_CDATA_AS_TEXT = 1 << 1
177 };
178
179 /** @ingroup glibmmEnums */
180 inline ParseFlags operator|(ParseFlags lhs, ParseFlags rhs)
181   { return static_cast<ParseFlags>(static_cast<unsigned>(lhs) | static_cast<unsigned>(rhs)); }
182
183 /** @ingroup glibmmEnums */
184 inline ParseFlags operator&(ParseFlags lhs, ParseFlags rhs)
185   { return static_cast<ParseFlags>(static_cast<unsigned>(lhs) & static_cast<unsigned>(rhs)); }
186
187 /** @ingroup glibmmEnums */
188 inline ParseFlags operator^(ParseFlags lhs, ParseFlags rhs)
189   { return static_cast<ParseFlags>(static_cast<unsigned>(lhs) ^ static_cast<unsigned>(rhs)); }
190
191 /** @ingroup glibmmEnums */
192 inline ParseFlags operator~(ParseFlags flags)
193   { return static_cast<ParseFlags>(~static_cast<unsigned>(flags)); }
194
195 /** @ingroup glibmmEnums */
196 inline ParseFlags& operator|=(ParseFlags& lhs, ParseFlags rhs)
197   { return (lhs = static_cast<ParseFlags>(static_cast<unsigned>(lhs) | static_cast<unsigned>(rhs))); }
198
199 /** @ingroup glibmmEnums */
200 inline ParseFlags& operator&=(ParseFlags& lhs, ParseFlags rhs)
201   { return (lhs = static_cast<ParseFlags>(static_cast<unsigned>(lhs) & static_cast<unsigned>(rhs))); }
202
203 /** @ingroup glibmmEnums */
204 inline ParseFlags& operator^=(ParseFlags& lhs, ParseFlags rhs)
205   { return (lhs = static_cast<ParseFlags>(static_cast<unsigned>(lhs) ^ static_cast<unsigned>(rhs))); }
206
207
208 /*! @var Markup::ParseFlags DO_NOT_USE_THIS_UNSUPPORTED_FLAG
209  * Flag you should not use.
210  */
211
212
213 /** Binary predicate used by Markup::Parser::AttributeMap.
214  * @ingroup Markup
215  * Unlike <tt>operator<(const ustring& lhs, const ustring& rhs)</tt>
216  * which would be used by the default <tt>std::less<></tt> predicate,
217  * the AttributeKeyLess predicate is locale-independent.  This is both
218  * more correct and much more efficient.
219  */
220 class AttributeKeyLess
221 {
222 public:
223   typedef Glib::ustring first_argument_type;
224   typedef Glib::ustring second_argument_type;
225   typedef bool          result_type;
226
227   bool operator()(const Glib::ustring& lhs, const Glib::ustring& rhs) const;
228 };
229
230
231 #ifndef DOXYGEN_SHOULD_SKIP_THIS
232 class ParserCallbacks;
233 #endif
234
235 /** The abstract markup parser base class.
236  * @ingroup Markup
237  * To implement a parser for your markup format, derive from
238  * Glib::Markup::Parser and implement the virtual methods.
239  *
240  * You don't have to override all of the virtual methods.  If a particular
241  * method is not implement the data passed to it will be ignored.  Except for
242  * the error method, any of these callbacks can throw an error exception; in
243  * particular the MarkupError::UNKNOWN_ELEMENT,
244  * MarkupError::UNKNOWN_ATTRIBUTE, and MarkupError::INVALID_CONTENT errors
245  * are intended to be thrown from these overridden methods. If you throw an
246  * error from a method, Glib::Markup::ParseContext::parse() will report that
247  * error back to its caller.
248  */
249 class Parser : public sigc::trackable
250 {
251 public:
252   typedef std::map<Glib::ustring, Glib::ustring, Glib::Markup::AttributeKeyLess> AttributeMap;
253
254   virtual ~Parser() = 0;
255
256 protected:
257   /** Constructs a Parser object.
258    * Note that Markup::Parser is an abstract class which can't be instantiated
259    * directly.  To implement the parser for your markup format, derive from
260    * Markup::Parser and implement the virtual methods.
261    */
262   Parser();
263
264   /** Called for open tags <tt>\<foo bar="baz"\></tt>.
265    * This virtual method is invoked when the opening tag of an element is seen.
266    * @param context The Markup::ParseContext object the parsed data belongs to.
267    * @param element_name The name of the element.
268    * @param attributes A map of attribute name/value pairs.
269    * @throw Glib::MarkupError An exception <em>you</em> should throw if
270    * something went wrong, for instance if an unknown attribute name was
271    * encountered.  In particular the MarkupError::UNKNOWN_ELEMENT,
272    * MarkupError::UNKNOWN_ATTRIBUTE, and MarkupError::INVALID_CONTENT
273    * errors are intended to be thrown from user-implemented methods.
274    */
275   virtual void on_start_element(ParseContext&        context,
276                                 const Glib::ustring& element_name,
277                                 const AttributeMap&  attributes);
278
279   /** Called for close tags <tt>\</foo\></tt>.
280    * This virtual method is invoked when the closing tag of an element is seen.
281    * @param context The Markup::ParseContext object the parsed data belongs to.
282    * @param element_name The name of the element.
283    * @throw Glib::MarkupError An exception <em>you</em> should throw if
284    * something went wrong, for instance if an unknown attribute name was
285    * encountered.  In particular the MarkupError::UNKNOWN_ELEMENT,
286    * MarkupError::UNKNOWN_ATTRIBUTE, and MarkupError::INVALID_CONTENT
287    * errors are intended to be thrown from user-implemented methods.
288    */
289   virtual void on_end_element(ParseContext& context, const Glib::ustring& element_name);
290
291   /** Called for character data.
292    * This virtual method is invoked when some text is seen (text is always
293    * inside an element).
294    * @param context The Markup::ParseContext object the parsed data belongs to.
295    * @param text The parsed text in UTF-8 encoding.
296    * @throw Glib::MarkupError An exception <em>you</em> should throw if
297    * something went wrong, for instance if an unknown attribute name was
298    * encountered.  In particular the MarkupError::UNKNOWN_ELEMENT,
299    * MarkupError::UNKNOWN_ATTRIBUTE, and MarkupError::INVALID_CONTENT
300    * errors are intended to be thrown from user-implemented methods.
301    */
302   virtual void on_text(ParseContext& context, const Glib::ustring& text);
303
304   /** Called for strings that should be re-saved verbatim in this same
305    * position, but are not otherwise interpretable.
306    * This virtual method is invoked for comments, processing instructions and
307    * doctype declarations; if you're re-writing the parsed document, write the
308    * passthrough text back out in the same position.
309    * @param context The Markup::ParseContext object the parsed data belongs to.
310    * @param passthrough_text The text that should be passed through.
311    * @throw Glib::MarkupError An exception <em>you</em> should throw if
312    * something went wrong, for instance if an unknown attribute name was
313    * encountered.  In particular the MarkupError::UNKNOWN_ELEMENT,
314    * MarkupError::UNKNOWN_ATTRIBUTE, and MarkupError::INVALID_CONTENT
315    * errors are intended to be thrown from user-implemented methods.
316    */
317   virtual void on_passthrough(ParseContext& context, const Glib::ustring& passthrough_text);
318
319   /** Called on error, including one thrown by an overridden virtual method.
320    * @param context The Markup::ParseContext object the parsed data belongs to.
321    * @param error A MarkupError object with detailed information about the error.
322    */
323   virtual void on_error(ParseContext& context, const MarkupError& error);
324
325 private:
326   // noncopyable
327   Parser(const Parser&);
328   Parser& operator=(const Parser&);
329
330 #ifndef DOXYGEN_SHOULD_SKIP_THIS
331   friend class Glib::Markup::ParserCallbacks;
332 #endif
333 };
334
335
336 /** A parse context is used to parse marked-up documents.
337  * @ingroup Markup
338  * You can feed any number of documents into a context, as long as no errors
339  * occur; once an error occurs, the parse context can't continue to parse text
340  * (you have to destroy it and create a new parse context).
341  */
342 class ParseContext : public sigc::trackable
343 {
344 public:
345   /** Creates a new parse context.
346    * @param parser A Markup::Parser instance.
347    * @param flags Bitwise combination of Markup::ParseFlags.
348    */
349   explicit ParseContext(Parser& parser, ParseFlags flags = ParseFlags(0));
350   virtual ~ParseContext();
351
352   /** Feed some data to the ParseContext.
353    * The data need not be valid UTF-8; an error will be signalled if it's
354    * invalid. The data need not be an entire document; you can feed a document
355    * into the parser incrementally, via multiple calls to this function.
356    * Typically, as you receive data from a network connection or file, you feed
357    * each received chunk of data into this function, aborting the process if an
358    * error occurs. Once an error is reported, no further data may be fed to the
359    * ParseContext; all errors are fatal.
360    * @param text Chunk of text to parse.
361    * @throw Glib::MarkupError
362    */
363   void parse(const Glib::ustring& text);
364
365   /** Feed some data to the ParseContext.
366    * The data need not be valid UTF-8; an error will be signalled if it's
367    * invalid. The data need not be an entire document; you can feed a document
368    * into the parser incrementally, via multiple calls to this function.
369    * Typically, as you receive data from a network connection or file, you feed
370    * each received chunk of data into this function, aborting the process if an
371    * error occurs. Once an error is reported, no further data may be fed to the
372    * ParseContext; all errors are fatal.
373    * @param text_begin Begin of chunk of text to parse.
374    * @param text_end End of chunk of text to parse.
375    * @throw Glib::MarkupError
376    */
377   void parse(const char* text_begin, const char* text_end);
378
379   /** Signals to the ParseContext that all data has been fed into the parse
380    * context with parse(). This method reports an error if the document isn't
381    * complete, for example if elements are still open.
382    * @throw Glib::MarkupError
383    */
384   void end_parse();
385
386   /** Retrieves the name of the currently open element.
387    * @return The name of the currently open element, or <tt>""</tt>.
388    */
389   Glib::ustring get_element() const;
390
391   /** Retrieves the current line number.
392    * Intended for use in error messages; there are no strict semantics for what
393    * constitutes the "current" line number other than "the best number we could
394    * come up with for error messages."
395    */
396   int get_line_number() const;
397
398   /** Retrieves the number of the current character on the current line.
399    * Intended for use in error messages; there are no strict semantics for what
400    * constitutes the "current" character number other than "the best number we
401    * could come up with for error messages."
402    */
403   int get_char_number() const;
404
405   Parser*       get_parser()       { return parser_; }
406   const Parser* get_parser() const { return parser_; }
407
408 #ifndef DOXYGEN_SHOULD_SKIP_THIS
409   GMarkupParseContext*       gobj()       { return gobject_; }
410   const GMarkupParseContext* gobj() const { return gobject_; }
411 #endif
412
413 private:
414   Markup::Parser*       parser_;
415   GMarkupParseContext*  gobject_;
416
417   // noncopyable
418   ParseContext(const ParseContext&);
419   ParseContext& operator=(const ParseContext&);
420
421   static void destroy_notify_callback(void* data);
422 };
423
424 } // namespace Markup
425
426 } // namespace Glib
427
428
429 #endif /* _GLIBMM_MARKUP_H */
430