1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286
|
/*
* Copyright (C) 2020 Linux Studio Plugins Project <https://lsp-plug.in/>
* (C) 2020 Vladimir Sadovnikov <sadko4u@gmail.com>
*
* This file is part of lsp-runtime-lib
* Created on: 24 окт. 2019 г.
*
* lsp-runtime-lib is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* lsp-runtime-lib is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with lsp-runtime-lib. If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef LSP_PLUG_IN_FMT_XML_PULLPARSER_H_
#define LSP_PLUG_IN_FMT_XML_PULLPARSER_H_
#include <lsp-plug.in/runtime/version.h>
#include <lsp-plug.in/common/types.h>
#include <lsp-plug.in/io/IInStream.h>
#include <lsp-plug.in/io/IInSequence.h>
#include <lsp-plug.in/io/Path.h>
#include <lsp-plug.in/fmt/xml/const.h>
#include <lsp-plug.in/lltl/parray.h>
namespace lsp
{
namespace xml
{
class PullParser
{
protected:
enum parse_state_t
{
PS_READ_MISC,
PS_READ_ELEMENTS,
PS_READ_ATTRIBUTES,
PS_READ_ELEMENT_DATA,
PS_READ_REFERENCE,
PS_READ_CHARACTERS,
PS_READ_SQ_ATTRIBUTE,
PS_READ_DQ_ATTRIBUTE,
PS_END_DOCUMENT
};
enum xml_flags_t
{
XF_STANDALONE = 1 << 0,
XF_ENCODING = 1 << 1,
XF_VERSION = 1 << 2,
XF_ROOT = 1 << 3,
XF_HEADER = 1 << 4,
XF_DOCTYPE = 1 << 5,
XF_DOCTYPE_SYS = 1 << 6,
XF_DOCTYPE_PUB = 1 << 7,
};
protected:
io::IInSequence *pIn;
size_t nWFlags;
status_t nToken;
parse_state_t nState;
xml_version_t enVersion;
lsp_swchar_t vUngetch[4];
size_t nUngetch;
parse_state_t vStates[4];
size_t nStates;
// Misc data
size_t nFlags; // Field presence
LSPString sVersion; // Document version
LSPString sEncoding; // Document encoding
LSPString sName; // Property/Tag name
LSPString sValue; // Property value
LSPString sRefName; // Reference name
LSPString sDoctype; // Document type
LSPString sSystem; // System literal
LSPString sPublic; // Public literal
lltl::parray<LSPString> vTags;
lltl::parray<LSPString> vAtts;
protected:
static void drop_list(lltl::parray<LSPString> *list);
inline lsp_swchar_t getch();
inline void ungetch(lsp_swchar_t c);
inline void push_state(parse_state_t override);
inline void pop_state();
bool skip_spaces();
status_t check_duplicate_attribute();
status_t read_version();
status_t read_encoding();
status_t read_standalone();
status_t read_text(const char *text);
status_t read_start_document();
status_t read_end_document();
status_t read_name(LSPString *name);
status_t read_attribute_value(lsp_swchar_t qc);
status_t read_header();
status_t read_misc();
status_t read_comment();
status_t read_doctype();
status_t read_tag_open();
status_t read_tag_close(bool copy);
status_t read_tag_attribute();
status_t read_tag_content();
status_t read_processing_instruction();
status_t read_cdata();
status_t read_characters();
status_t read_entity_reference(LSPString *cdata);
status_t read_system_literal(LSPString *dst);
status_t read_pubid_literal(LSPString *dst);
status_t read_token();
public:
explicit PullParser();
virtual ~PullParser();
public:
/**
* Open parser
* @param path UTF-8 path to the file
* @param charset character set
* @return status of operation
*/
status_t open(const char *path, const char *charset = NULL);
/**
* Open parser
* @param path string representation of path to the file
* @param charset character set
* @return status of operation
*/
status_t open(const LSPString *path, const char *charset = NULL);
/**
* Open parser
* @param path path to the file
* @param charset character set
* @return status of operation
*/
status_t open(const io::Path *path, const char *charset = NULL);
/**
* Wrap string with parser
* @param str string to wrap
* @param charset character set
* @return status of operation
*/
status_t wrap(const char *str, const char *charset = NULL);
/**
* Wrap string with parser
* @param str string to wrap
* @return status of operation
*/
status_t wrap(const LSPString *str);
/**
* Wrap input sequence with parser
* @param seq sequence to use for reads
* @return status of operation
*/
status_t wrap(io::IInSequence *seq, size_t flags = WRAP_NONE);
/**
* Wrap input stream with parser
* @param is input stream
* @param flags wrap flags
* @param charset character set
* @return status of operation
*/
status_t wrap(io::IInStream *is, size_t flags = WRAP_NONE, const char *charset = NULL);
/**
* Close parser
* @return status of operation
*/
status_t close();
public:
/**
* Read next element
* @return XT_ element code or negative status of operation
*/
status_t read_next();
/**
* Get current element
* @return XT_ element code or negative status of operation
*/
status_t get_current();
/**
* Resolve entity with specified value
* @param value value to resolve
* @return status of operation
*/
status_t set_value(const LSPString *value);
/**
* Resolve entity with specified value
* @param value value to resolve
* @param charset character set encoding
* @return status of operation
*/
status_t set_value(const char *value, const char *charset = NULL);
public:
/**
* Check whethere document is standalone
* @return true if document is standalone
*/
inline bool is_standalone() const { return nFlags & XF_STANDALONE; }
/**
* Get version string
* @return version string or NULL is version string is not present in header
*/
inline const LSPString *version() const { return (nFlags & XF_VERSION) ? &sVersion : NULL; }
/**
* Get actual parser version
* @return actual parser version
*/
inline xml_version_t xml_version() const { return enVersion; }
/**
* Get document encoding
* @return document encoding or NULL if encoding string is not present in header
*/
inline const LSPString *encoding() const { return (nFlags & XF_ENCODING) ? &sEncoding : NULL; }
/**
* Return name of current property, tag or processing instruction
* @return name name
*/
const LSPString *name() const;
/**
* Return value of current property, comment or processing instruction
* @return value value
*/
const LSPString *value() const;
/**
* Get current element nesting level
* @return current element nesting level
*/
inline size_t level() const { return vTags.size(); }
/**
* Get document type name
* @return document type name or NULL if not present
*/
inline const LSPString *doctype() const { return (nFlags & XF_DOCTYPE) ? &sDoctype : NULL; }
/**
* Get document type public literal
* @return document type public literal or NULL if not present
*/
inline const LSPString *pub_literal() const { return (nFlags & XF_DOCTYPE_PUB) ? &sPublic: NULL; }
/**
* Get document type system literal
* @return document type system literal or NULL if not present
*/
inline const LSPString *sys_literal() const { return (nFlags & XF_DOCTYPE_SYS) ? &sSystem: NULL; }
};
} /* namespace xml */
} /* namespace lsp */
#endif /* LSP_PLUG_IN_FMT_XML_PULLPARSER_H_ */
|