|
reSIProcate/stack
9373
|
00001 #if !defined(RESIP_XMLCURSOR_HXX) 00002 #define RESIP_XMLCURSOR_HXX 00003 00004 #include <iosfwd> 00005 #include <vector> 00006 00007 #include "rutil/ParseBuffer.hxx" 00008 #include "rutil/HashMap.hxx" 00009 00010 namespace resip 00011 { 00012 00013 /* 00014 // XML tree traversal. 00015 // XMLCursor starts at the root. 00016 // The attributes and value of the cursor are those of the root. 00017 // To descend to the first child of the root, call firstChild(). 00018 // To traverse the children of root from root, call firstChild();nextSibling();nextSibling();... 00019 // To descend into the first child of the current element, call firstChild. 00020 // To return to the parent of the current element, call parent. 00021 // The traversal state among the siblings of the parent is maintained. 00022 // 00023 // root 00024 // / \ 00025 // P1 P2 00026 // / \ / \ 00027 // A1 A2 B1 B2 00028 // 00029 // atRoot() == true; 00030 // firstChild(); // P1 00031 // firstChild(); // A1 00032 // nextSibling(); // A2 00033 // parent(); // P1 00034 // nextSibling(); // P2 00035 // firstChild(); // B1 00036 // nextSibling(); // B2 00037 // parent(); // P2 00038 // nextSibling(); // false, stay at P2 00039 // parent(); // root 00040 // nextSibling(); // false, stay at root 00041 // parent(); // false, stay at root 00042 // firstChild(); // P1 00043 00044 // E.g.: Depth first traversal 00045 // 00046 // void traverse(XMLCursor& c) 00047 // { 00048 // if (c.firstChild()) 00049 // { 00050 // traverse(c); 00051 // c.parent(); 00052 // } 00053 // 00054 // process(c); 00055 // 00056 // if (c.nextSibling()) 00057 // { 00058 // traverse(c); 00059 // } 00060 // } 00061 // 00062 // E.g.: Lexical Order traversal 00063 // 00064 // void 00065 // traverse(XMLCursor& c, int i = 0) 00066 // { 00067 // for (int ii = 0; ii < i; ++ii) 00068 // { 00069 // cerr << " "; 00070 // } 00071 00072 // cerr << c.getTag(); 00073 // if (c.atLeaf()) 00074 // { 00075 // cerr << "[" << c.getValue() << "]" << endl; 00076 // } 00077 // else 00078 // { 00079 // cerr << endl; 00080 // } 00081 00082 // if (c.firstChild()) 00083 // { 00084 // traverse(c, i+2); 00085 // c.parent(); 00086 // } 00087 00088 // if (c.nextSibling()) 00089 // { 00090 // traverse(c, i+2); 00091 // } 00092 // } 00093 00094 */ 00095 00096 class XMLCursor 00097 { 00098 public: 00099 // !dlb! should be determined by the document 00100 // see http://www.w3.org/TR/1998/REC-xml-19980210#sec-white-space 00101 enum {WhitespaceSignificant = false}; 00102 00103 XMLCursor(const ParseBuffer& pb); 00104 ~XMLCursor(); 00105 00106 bool nextSibling(); 00107 bool firstChild(); 00108 bool parent(); 00109 void reset(); 00110 00111 bool atRoot() const; 00112 bool atLeaf() const; 00113 00114 const Data& getTag() const; 00115 typedef HashMap<Data, Data> AttributeMap; 00116 const AttributeMap& getAttributes() const; 00117 const Data& getValue() const; 00118 00119 static EncodeStream& encode(EncodeStream& strm, const AttributeMap& attrs); 00120 class Node; 00121 00122 class AttributeValueEqual { 00123 Data data_; 00124 public: 00125 AttributeValueEqual(const Data& data) : data_(data) {}; 00126 bool operator()(const std::pair<Data, Data>& data) { return data.second == data_; } 00127 }; 00128 00129 private: 00130 static void skipProlog(ParseBuffer& pb); 00131 static void decode(Data&); 00132 static void decodeName(Data&); 00133 00134 void parseNextRootChild(); 00135 00136 00137 Node* mRoot; 00138 Node* mCursor; 00139 00140 //bool isEmpty; 00141 00142 // store for undecoded root tag 00143 Data mTag; 00144 00145 // store for copy of input if commented 00146 Data mData; 00147 00148 // store date for decoding 00149 mutable Data mValue; 00150 // store attributes for reference 00151 mutable AttributeMap mAttributes; 00152 mutable bool mAttributesSet; 00153 00154 public: 00155 class Node 00156 { 00157 public: 00158 Node(const ParseBuffer& pb); 00159 ~Node(); 00160 00161 void addChild(Node*); 00162 // return true if <foo/> 00163 bool extractTag(); 00164 void skipToEndTag(); 00165 static const char* skipComments(ParseBuffer& pb); 00166 00167 ParseBuffer mPb; 00168 Node* mParent; 00169 std::vector<Node*> mChildren; 00170 std::vector<Node*>::const_iterator mNext; 00171 00172 bool mIsLeaf; 00173 Data mTag; 00174 00175 private: 00176 Node(const Node&); 00177 Node& operator=(const Node&); 00178 00179 friend EncodeStream& operator<<(EncodeStream& str, const XMLCursor& cursor); 00180 // friend EncodeStream& operator<<(EncodeStream& str, const XMLCursor::Node& cursor); // this line won't compile in windows 00181 }; 00182 private: 00183 friend EncodeStream& operator<<(EncodeStream&, const XMLCursor&); 00184 friend EncodeStream& operator<<(EncodeStream&, const XMLCursor::Node&); 00185 00186 // no value semantics 00187 XMLCursor(const XMLCursor&); 00188 XMLCursor& operator=(const XMLCursor&); 00189 friend class Node; 00190 }; 00191 00192 EncodeStream& 00193 operator<<(EncodeStream& str, const XMLCursor& cursor); 00194 00195 EncodeStream& 00196 operator<<(EncodeStream& str, const XMLCursor::Node& cursor); 00197 00198 } 00199 00200 #endif 00201 00202 /* ==================================================================== 00203 * The Vovida Software License, Version 1.0 00204 * 00205 * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. 00206 * 00207 * Redistribution and use in source and binary forms, with or without 00208 * modification, are permitted provided that the following conditions 00209 * are met: 00210 * 00211 * 1. Redistributions of source code must retain the above copyright 00212 * notice, this list of conditions and the following disclaimer. 00213 * 00214 * 2. Redistributions in binary form must reproduce the above copyright 00215 * notice, this list of conditions and the following disclaimer in 00216 * the documentation and/or other materials provided with the 00217 * distribution. 00218 * 00219 * 3. The names "VOCAL", "Vovida Open Communication Application Library", 00220 * and "Vovida Open Communication Application Library (VOCAL)" must 00221 * not be used to endorse or promote products derived from this 00222 * software without prior written permission. For written 00223 * permission, please contact vocal@vovida.org. 00224 * 00225 * 4. Products derived from this software may not be called "VOCAL", nor 00226 * may "VOCAL" appear in their name, without prior written 00227 * permission of Vovida Networks, Inc. 00228 * 00229 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED 00230 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 00231 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND 00232 * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA 00233 * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES 00234 * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, 00235 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 00236 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 00237 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 00238 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00239 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE 00240 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 00241 * DAMAGE. 00242 * 00243 * ==================================================================== 00244 * 00245 * This software consists of voluntary contributions made by Vovida 00246 * Networks, Inc. and many individuals on behalf of Vovida Networks, 00247 * Inc. For more information on Vovida Networks, Inc., please see 00248 * <http://www.vovida.org/>. 00249 * 00250 */
1.7.5.1