Coverage Report

Created: 2026-08-25 06:40

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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__