Coverage Report

Created: 2026-06-07 06:36

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/resiprocate/rutil/XMLCursor.hxx
Line
Count
Source
1
#if !defined(RESIP_XMLCURSOR_HXX)
2
#define RESIP_XMLCURSOR_HXX 
3
4
#include <iosfwd>
5
#include <memory>
6
#include <vector>
7
8
#include "rutil/ParseBuffer.hxx"
9
#include "rutil/HashMap.hxx"
10
11
namespace resip
12
{
13
14
/*
15
// XML tree traversal.
16
// XMLCursor starts at the root.
17
// The attributes and value of the cursor are those of the root.
18
// To descend to the first child of the root, call firstChild().
19
// To traverse the children of root from root, call firstChild();nextSibling();nextSibling();...
20
// To descend into the first child of the current element, call firstChild.
21
// To return to the parent of the current element, call parent.
22
// The traversal state among the siblings of the parent is maintained.
23
//
24
//                          root
25
//                        /     \
26
//                       P1     P2
27
//                      /  \   /  \
28
//                     A1  A2 B1  B2
29
//
30
//  atRoot() == true;
31
//  firstChild(); // P1
32
//  firstChild(); // A1
33
//  nextSibling(); // A2
34
//  parent();   // P1
35
//  nextSibling(); // P2
36
//  firstChild(); // B1
37
//  nextSibling(); // B2
38
//  parent();   // P2
39
//  nextSibling(); // false, stay at P2
40
//  parent();   // root
41
//  nextSibling(); // false, stay at root
42
//  parent();   // false, stay at root
43
//  firstChild(); // P1
44
45
// E.g.: Depth first traversal
46
//
47
// void traverse(XMLCursor& c)
48
// {
49
//    if (c.firstChild())
50
//    {
51
//       traverse(c);
52
//       c.parent();
53
//    }
54
// 
55
//    process(c);
56
//    
57
//    if (c.nextSibling())
58
//    {
59
//       traverse(c);
60
//    }
61
// }
62
//
63
// E.g.: Lexical Order traversal
64
//
65
// void
66
// traverse(XMLCursor& c, int i = 0)
67
// {
68
//    for (int ii = 0; ii < i; ++ii)
69
//    {
70
//       cerr << " ";
71
//    }
72
73
//    cerr << c.getTag();
74
//    if (c.atLeaf())
75
//    {
76
//       cerr << "[" << c.getValue() << "]" << endl;
77
//    }
78
//    else
79
//    {
80
//       cerr << endl;
81
//    }
82
83
//    if (c.firstChild())
84
//    {
85
//       traverse(c, i+2);
86
//       c.parent();
87
//    }
88
   
89
//    if (c.nextSibling())
90
//    {
91
//       traverse(c, i+2);
92
//    }
93
// }
94
95
*/
96
97
class XMLCursor
98
{
99
   public:
100
      // !dlb! should be determined by the document
101
      // see http://www.w3.org/TR/1998/REC-xml-19980210#sec-white-space
102
      enum {WhitespaceSignificant = false};
103
104
      XMLCursor(const ParseBuffer& pb);
105
      ~XMLCursor();
106
107
      bool nextSibling();
108
      bool firstChild();
109
      bool parent();
110
      void reset();
111
112
      bool atRoot() const;
113
      bool atLeaf() const;
114
115
      const Data& getTag() const;
116
      typedef HashMap<Data, Data> AttributeMap;
117
      const AttributeMap& getAttributes() const;
118
      const Data& getValue() const;
119
120
      static EncodeStream& encode(EncodeStream& strm, const AttributeMap& attrs);
121
      class Node;
122
123
      class AttributeValueEqual 
124
      {
125
         Data data_;
126
         public:
127
0
            AttributeValueEqual(const Data& data) : data_(data) {};
128
0
            bool operator()(const std::pair<const Data, Data>& data) { return data.second == data_; }
129
      };
130
131
   private:
132
      static void skipProlog(ParseBuffer& pb);
133
      static void decode(Data&);
134
      static void decodeName(Data&);
135
136
      void parseNextRootChild();
137
138
139
      std::unique_ptr<Node> mRoot;
140
      Node* mCursor;
141
142
      //bool isEmpty;
143
144
      // store for undecoded root tag
145
      Data mTag;
146
147
      // store for copy of input if commented
148
      Data mData;
149
150
      // store date for decoding
151
      mutable Data mValue;
152
      // store attributes for reference
153
      mutable AttributeMap mAttributes;
154
      mutable bool mAttributesSet;
155
156
public:
157
      class Node
158
      {
159
         public:
160
            Node(const ParseBuffer& pb);
161
            ~Node();
162
163
            void addChild(Node*);
164
            // return true if <foo/>
165
            bool extractTag();
166
            void skipToEndTag();
167
            static const char* skipComments(ParseBuffer& pb);
168
169
            ParseBuffer mPb;
170
            Node* mParent;
171
            std::vector<Node*> mChildren;
172
            std::vector<Node*>::const_iterator mNext;
173
174
            bool mIsLeaf;
175
            Data mTag;
176
177
         private:
178
            Node(const Node&);
179
            Node& operator=(const Node&);
180
181
            friend EncodeStream& operator<<(EncodeStream& str, const XMLCursor& cursor);
182
            // friend EncodeStream& operator<<(EncodeStream& str, const XMLCursor::Node& cursor); // this line won't compile in windows 
183
      };
184
   private:
185
      friend EncodeStream& operator<<(EncodeStream&, const XMLCursor&);
186
      friend EncodeStream& operator<<(EncodeStream&, const XMLCursor::Node&);
187
188
      // no value semantics
189
      XMLCursor(const XMLCursor&);
190
      XMLCursor& operator=(const XMLCursor&);
191
      friend class Node;
192
};
193
194
EncodeStream&
195
operator<<(EncodeStream& str, const XMLCursor& cursor);
196
197
EncodeStream&
198
operator<<(EncodeStream& str, const XMLCursor::Node& cursor);
199
200
}
201
202
#endif
203
204
/* ====================================================================
205
 * The Vovida Software License, Version 1.0 
206
 * 
207
 * Copyright (c) 2000 Vovida Networks, Inc.  All rights reserved.
208
 * 
209
 * Redistribution and use in source and binary forms, with or without
210
 * modification, are permitted provided that the following conditions
211
 * are met:
212
 * 
213
 * 1. Redistributions of source code must retain the above copyright
214
 *    notice, this list of conditions and the following disclaimer.
215
 * 
216
 * 2. Redistributions in binary form must reproduce the above copyright
217
 *    notice, this list of conditions and the following disclaimer in
218
 *    the documentation and/or other materials provided with the
219
 *    distribution.
220
 * 
221
 * 3. The names "VOCAL", "Vovida Open Communication Application Library",
222
 *    and "Vovida Open Communication Application Library (VOCAL)" must
223
 *    not be used to endorse or promote products derived from this
224
 *    software without prior written permission. For written
225
 *    permission, please contact vocal@vovida.org.
226
 *
227
 * 4. Products derived from this software may not be called "VOCAL", nor
228
 *    may "VOCAL" appear in their name, without prior written
229
 *    permission of Vovida Networks, Inc.
230
 * 
231
 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
232
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
233
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
234
 * NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL VOVIDA
235
 * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES
236
 * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
237
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
238
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
239
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
240
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
241
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
242
 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
243
 * DAMAGE.
244
 * 
245
 * ====================================================================
246
 * 
247
 * This software consists of voluntary contributions made by Vovida
248
 * Networks, Inc. and many individuals on behalf of Vovida Networks,
249
 * Inc.  For more information on Vovida Networks, Inc., please see
250
 * <http://www.vovida.org/>.
251
 *
252
 */