1 // =================================
 2 // Copyright (c) 2021 Seppo Laakko
 3 // Distributed under the MIT license
 4 // =================================
 5 
 6 #ifndef SNGXML_XML_XML_PROCESSOR
 7 #define SNGXML_XML_XML_PROCESSOR
 8 #include <sngxml/xml/XmlContentHandler.hpp>
 9 #include <soulng/lexer/TrivialLexer.hpp>
10 #include <stack>
11 #include <memory>
12 #include <unordered_map>
13 #include <string>
14 #include <stdexcept>
15 
16 namespace sngxml { namespace xml {
17 
18 class XmlProcessingException public std::runtime_error
19 {
20 public:
21     XmlProcessingException(const std::string& message);
22 };
23 
24 class Entity 
25 {
26 public:
27     virtual ~Entity();
28     virtual bool IsInternalEntity() const { return false; }
29 };
30 
31 class InternalEntity public Entity
32 {
33 public:
34     InternalEntity(const std::u32string& value_);
35     const std::u32string& Value() const { return value; }
36     bool IsInternalEntity() const override { return true; }
37 private:
38     std::u32string value;
39 };
40 
41 class XmlProcessor 
42 {
43 public:
44     XmlProcessor(const XmlProcessor&) = delete;
45     XmlProcessor& operator=(const XmlProcessor&) = delete;
46     XmlProcessor(XmlProcessor&&) = delete;
47     XmlProcessor&& operator=(XmlProcessor&&) = delete;
48     XmlProcessor(TrivialLexer& lexer_XmlContentHandler* contentHandler_);
49     void StartDocument();
50     void EndDocument();
51     void Text(const std::u32string& text);
52     void Comment(const std::u32string& text);
53     void PI(const std::u32string& targetconst std::u32string& data);
54     void CDataSection(const std::u32string& cdata);
55     void Version(const std::u32string& version);
56     void Standalone(bool standalone);
57     void Encoding(const std::u32string& encoding);
58     void BeginStartTag(const std::u32string& tagName);
59     void EndStartTag(const soulng::lexer::Span& spanconst std::string& systemId);
60     void EndTag(const std::u32string& tagNameconst soulng::lexer::Span& spanconst std::string& systemId);
61     void AddAttribute(const std::u32string& attNameconst std::u32string& attValueconst soulng::lexer::Span& spanconst std::string& systemId);
62     void EntityRef(const std::u32string& entityNameconst soulng::lexer::Span& spanconst std::string& systemId);
63     void BeginAttributeValue();
64     void EndAttributeValue();
65     const std::u32string& AttValue() const { return attValue; }
66     std::u32string& AttValue() { return attValue; }
67     TrivialLexer& Lexer() const { return lexer; }
68 private:
69     TrivialLexer& lexer;
70     XmlContentHandler* contentHandler;
71     std::stack<std::u32string> tagStack;
72     std::u32string currentTagName;
73     std::stack<std::u32string> attValueStack;
74     std::u32string attValue;
75     std::stack<std::u32string> namespaceUriStack;
76     std::u32string currentNamespaceUri;
77     std::stack<std::u32string> namespacePrefixStack;
78     std::u32string currentNamespacePrefix;
79     std::unordered_map<std::u32stringstd::u32string> namespacePrefixMap;
80     Attributes attributes;
81     std::unordered_map<std::u32stringstd::std::unique_ptr<Entity>>entityMap;
82     int GetErrorColumn(int index) const;
83     std::string GetErrorLocationStr(const std::string& systemIdconst soulng::lexer::Span& span) const;
84     void ParseQualifiedName(const std::u32string& qualifiedNamestd::u32string& localNamestd::u32string& prefixconst soulng::lexer::Span& spanconst std::string& systemId);
85     std::u32string GetNamespaceUri(const std::u32string& namespacePrefixconst soulng::lexer::Span& spanconst std::string& systemId);
86 };
87 
88 } } // namespace sngxml::xml
89 
90 #endif // SNGXML_XML_XML_PROCESSOR
91