/src/exiv2/xmpsdk/src/XMLParserAdapter.hpp
Line | Count | Source |
1 | | #ifndef __XMLParserAdapter_hpp__ |
2 | | #define __XMLParserAdapter_hpp__ |
3 | | |
4 | | // ================================================================================================= |
5 | | // Copyright 2005-2007 Adobe Systems Incorporated |
6 | | // All Rights Reserved. |
7 | | // |
8 | | // NOTICE: Adobe permits you to use, modify, and distribute this file in accordance with the terms |
9 | | // of the Adobe license agreement accompanying it. |
10 | | // ================================================================================================= |
11 | | |
12 | | #include "XMP_Environment.h" // ! Must be the first #include! |
13 | | #include "XMP_Const.h" |
14 | | |
15 | | #include <string> |
16 | | #include <vector> |
17 | | |
18 | | // ================================================================================================= |
19 | | // XML_Node details |
20 | | // |
21 | | // The XML_Nodes are used only during the XML/RDF parsing process. This presently uses an XML parser |
22 | | // to create an XML tree, then a recursive descent RDF recognizer to build the corresponding XMP. |
23 | | // This makes it easier to swap XML parsers and provides a clean separation of XML and RDF issues. |
24 | | // The overall parsing would be faster and use less memory if the RDF recognition were done on the |
25 | | // fly using a state machine. But it was much easier to write the recursive descent version. The |
26 | | // current implementation is pretty fast in absolute terms, so being faster might not be crucial. |
27 | | // |
28 | | // Like the XMP tree, the XML tree contains vectors of pointers for down links, and offspring have |
29 | | // a pointer to their parent. Unlike the XMP tree, this is an exact XML document tree. There are no |
30 | | // introduced top level namespace nodes or rearrangement of the nodes.. |
31 | | // |
32 | | // The exact state of namespaces can vary during the XML parsing, depending on the parser in use. |
33 | | // By the time the RDF recognition is done though, the namespaces must be normalized. All of the |
34 | | // used namespaces must be registered, this is done automatically if necessary. All of the "live" |
35 | | // namespace prefixes will be unique. The ns field of an XML_Node is the namespace URI, the name |
36 | | // field contains a qualified name (prefix:local). This includes default namespace mapping, the |
37 | | // URI and prefix will be missing only for elements and attributes in no namespace. |
38 | | |
39 | | class XML_Node; |
40 | | |
41 | | typedef XML_Node * XML_NodePtr; // Handy for things like: XML_Node * a, b; - b is XML_Node, not XML_Node*! |
42 | | |
43 | | enum { kRootNode = 0, kElemNode = 1, kAttrNode = 2, kCDataNode = 3, kPINode = 4 }; |
44 | | |
45 | 17.8k | #define IsWhitespaceChar(ch) ( ((ch) == ' ') || ((ch) == 0x09) || ((ch) == 0x0A) || ((ch) == 0x0D) ) |
46 | | |
47 | | typedef std::vector<XML_NodePtr> XML_NodeVector; |
48 | | typedef XML_NodeVector::iterator XML_NodePos; |
49 | | typedef XML_NodeVector::const_iterator XML_cNodePos; |
50 | | |
51 | | #if 0 // Pattern for iterating over the children or attributes: |
52 | | for ( size_t xxNum = 0, xxLim = _node_->_offspring_.size(); xxNum < xxLim; ++xxNum ) { |
53 | | const XML_NodePtr _curr_ = _node_->_offspring_[xxNum]; |
54 | | } |
55 | | #endif |
56 | | |
57 | | class XML_Node { |
58 | | public: |
59 | | |
60 | | // Intended for lightweight internal use. Clients are expected to use the data directly. |
61 | | |
62 | | XMP_Uns8 kind; |
63 | | std::string ns, name, value; |
64 | | size_t nsPrefixLen; |
65 | | XML_NodePtr parent; |
66 | | XML_NodeVector attrs; |
67 | | XML_NodeVector content; |
68 | | |
69 | | bool IsWhitespaceNode() const; |
70 | | bool IsLeafContentNode() const; // An empty element or one with a single character data child node. |
71 | | bool IsEmptyLeafNode() const; |
72 | | |
73 | | XMP_StringPtr GetAttrValue ( XMP_StringPtr attrName ) const; |
74 | | void SetAttrValue ( XMP_StringPtr attrName, XMP_StringPtr attrValue ); |
75 | | |
76 | | XMP_StringPtr GetLeafContentValue() const; |
77 | | void SetLeafContentValue ( XMP_StringPtr value ); |
78 | | |
79 | | size_t CountNamedElements ( XMP_StringPtr nsURI, XMP_StringPtr localName ) const; // Number of child elements with this name. |
80 | | XML_NodePtr GetNamedElement ( XMP_StringPtr nsURI, XMP_StringPtr localName, size_t which = 0 ); |
81 | | |
82 | | void Dump ( std::string * buffer ); |
83 | | void Serialize ( std::string * buffer ); |
84 | | |
85 | | void RemoveAttrs(); |
86 | | void RemoveContent(); |
87 | | void ClearNode(); |
88 | | |
89 | | XML_Node ( XML_NodePtr _parent, XMP_StringPtr _name, XMP_Uns8 _kind ) |
90 | 53.6k | : kind(_kind), name(_name), nsPrefixLen(0), parent(_parent) {}; |
91 | | |
92 | | XML_Node ( XML_NodePtr _parent, const std::string & _name, XMP_Uns8 _kind ) |
93 | 0 | : kind(_kind), name(_name), nsPrefixLen(0), parent(_parent) {}; |
94 | | |
95 | 53.6k | virtual ~XML_Node() { RemoveAttrs(); RemoveContent(); }; |
96 | | |
97 | | private: |
98 | | |
99 | 0 | XML_Node() : kind(0), parent(0) {}; // ! Hidden to make sure parent pointer is always set. |
100 | | |
101 | | }; |
102 | | |
103 | | // ================================================================================================= |
104 | | // Abstract base class for XML parser adapters used by the XMP toolkit. |
105 | | |
106 | | enum { kXMLPendingInputMax = 16 }; |
107 | | |
108 | | class XMLParserAdapter { |
109 | | public: |
110 | | |
111 | | XMLParserAdapter() |
112 | 1.89k | : tree(0,"",kRootNode), rootNode(0), rootCount(0), charEncoding(XMP_OptionBits(-1)), pendingCount(0) |
113 | 1.89k | { |
114 | | #if XMP_DebugBuild |
115 | | parseLog = 0; |
116 | | #endif |
117 | 1.89k | }; |
118 | | |
119 | 1.89k | virtual ~XMLParserAdapter() {}; |
120 | | |
121 | | virtual void ParseBuffer ( const void * buffer, size_t length, bool last ) = 0; |
122 | | |
123 | | XML_Node tree; |
124 | | XML_NodeVector parseStack; |
125 | | XML_NodePtr rootNode; |
126 | | size_t rootCount; |
127 | | |
128 | | XMP_OptionBits charEncoding; |
129 | | size_t pendingCount; |
130 | | unsigned char pendingInput[kXMLPendingInputMax]; // Buffered input for character encoding checks. |
131 | | |
132 | | #if XMP_DebugBuild |
133 | | FILE * parseLog; |
134 | | #endif |
135 | | |
136 | | }; |
137 | | |
138 | | // ================================================================================================= |
139 | | |
140 | | #endif // __XMLParserAdapter_hpp__ |