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