00001
00002
00003
00004
00005
00006
00007 #ifndef _XMLSTACK_H
00008 #define _XMLSTACK_H
00009
00010 #include <string>
00011 #include <vector>
00012 #include <map>
00013 #include <exception>
00014 #include <algorithm>
00015 #include <sstream>
00016 #include <iomanip>
00017 #include "ConvertEncoding.h"
00018
00019
00020
00021
00022 #define _CE ConvertEncoding
00023
00024
00025 template<class _E, class _Tr, class _A> class XMLStackDocument;
00026 template<class _E, class _Tr, class _A> class XMLStackAttribute;
00027
00028
00029
00031 class XMLStackException : public std::exception
00032 {
00033 public:
00035 XMLStackException(const std::string & Text) : m_Msg(Text) {}
00036
00038 virtual ~XMLStackException() {}
00039
00041 virtual const char *what() const { return m_Msg.c_str(); }
00042 private:
00043 std::string m_Msg;
00044 };
00045
00046
00047
00048
00050 template<class _E, class _Tr = std::char_traits<_E>, class _A = std::allocator<_E> >
00051 class XMLStackNode
00052 {
00053 public:
00054 typedef XMLStackNode<_E, _Tr, _A> _XMLStackNode;
00055 typedef XMLStackDocument<_E, _Tr, _A> _XMLStackDocument;
00056 typedef XMLStackAttribute<_E, _Tr, _A> _XMLStackAttribute;
00057 typedef std::basic_string<_E, _Tr, _A> _XMLStackString;
00058
00068 XMLStackNode(_XMLStackDocument * Doc,
00069 const _XMLStackString & Name) : m_Doc(Doc), m_Name(Name) {}
00070
00072 virtual ~XMLStackNode() {}
00073
00075 const _XMLStackString & getNodeName(void) const { return m_Name; }
00076
00078 _XMLStackString getPrefix(void) const
00079 {
00080 _XMLStackString::size_type Pos;
00081 _XMLStackString Prefix;
00082
00083 Pos = m_Name.find(':');
00084 if (Pos != _XMLStackString::npos)
00085 {
00086 Prefix.assign(m_Name.begin(), m_Name.begin() + Pos);
00087 }
00088 return Prefix;
00089 }
00090
00092 _XMLStackString getLocalName(void) const
00093 {
00094 _XMLStackString::size_type Pos;
00095 _XMLStackString Name;
00096
00097 Pos = m_Name.find(':');
00098 if (Pos != _XMLStackString::npos)
00099 {
00100 Name.assign(m_Name, Pos + 1, _XMLStackString::npos);
00101 }
00102 else
00103 {
00104 return m_Name;
00105 }
00106 return Name;
00107 }
00108
00110 virtual _XMLStackAttribute & createAttribute
00111 (const _XMLStackString & Name,
00112 const _XMLStackString & NamespaceURI = _XMLStackString())
00113 {
00114 throw XMLStackException("ERROR: Node type does not support attributes.");
00115 }
00116
00118 virtual _XMLStackAttribute & getAttribute(const _XMLStackString & Name)
00119 {
00120 throw XMLStackException("ERROR: Node type does not support attributes.");
00121 }
00122
00124 virtual bool hasAttribute(const _XMLStackString & Name) const
00125 {
00126 throw XMLStackException("ERROR: Node type does not support attributes.");
00127 }
00128
00140 virtual void setValue(const _XMLStackString & Value)
00141 {
00142 throw XMLStackException("ERROR: setValue() not implemented for this"
00143 " node type");
00144 }
00145 virtual void setValue(unsigned long Value)
00146 {
00147 throw XMLStackException("ERROR: setValue() not implemented for this"
00148 " node type");
00149 }
00150 virtual void setValue(long Value)
00151 {
00152 throw XMLStackException("ERROR: setValue() not implemented for this"
00153 " node type");
00154 }
00155 virtual void setValue(unsigned int Value)
00156 {
00157 throw XMLStackException("ERROR: setValue() not implemented for this"
00158 " node type");
00159 }
00160 virtual void setValue(int Value)
00161 {
00162 throw XMLStackException("ERROR: setValue() not implemented for this"
00163 " node type");
00164 }
00165 virtual void setValue(unsigned short Value)
00166 {
00167 throw XMLStackException("ERROR: setValue() not implemented for this"
00168 " node type");
00169 }
00170 virtual void setValue(short Value)
00171 {
00172 throw XMLStackException("ERROR: setValue() not implemented for this"
00173 " node type");
00174 }
00175 virtual void setValue(signed char Value)
00176 {
00177 throw XMLStackException("ERROR: setValue() not implemented for this"
00178 " node type");
00179 }
00180 virtual void setValue(char Value)
00181 {
00182 throw XMLStackException("ERROR: setValue() not implemented for this"
00183 " node type");
00184 }
00185 virtual void setValue(unsigned char Value)
00186 {
00187 throw XMLStackException("ERROR: setValue() not implemented for this"
00188 " node type");
00189 }
00190 virtual void setValue(double Value, int Scale = 6)
00191 {
00192 throw XMLStackException("ERROR: setValue() not implemented for this"
00193 " node type");
00194 }
00195 virtual void setValue(float Value, int Scale = 6)
00196 {
00197 throw XMLStackException("ERROR: setValue() not implemented for this"
00198 " node type");
00199 }
00200
00202 _XMLStackNode & operator=(const _XMLStackString & Value)
00203 {
00204 setValue(Value);
00205 return *this;
00206 }
00208 _XMLStackNode & operator=(unsigned long & Value)
00209 {
00210 setValue(Value);
00211 return *this;
00212 }
00214 _XMLStackNode & operator=(long Value)
00215 {
00216 setValue(Value);
00217 return *this;
00218 }
00220 _XMLStackNode & operator=(unsigned int Value)
00221 {
00222 setValue(Value);
00223 return *this;
00224 }
00226 _XMLStackNode & operator=(int Value)
00227 {
00228 setValue(Value);
00229 return *this;
00230 }
00232 _XMLStackNode & operator=(unsigned short Value)
00233 {
00234 setValue(Value);
00235 return *this;
00236 }
00238 _XMLStackNode & operator=(short Value)
00239 {
00240 setValue(Value);
00241 return *this;
00242 }
00244 _XMLStackNode & operator=(signed char Value)
00245 {
00246 setValue(Value);
00247 return *this;
00248 }
00250 _XMLStackNode & operator=(char Value)
00251 {
00252 setValue(Value);
00253 return *this;
00254 }
00256 _XMLStackNode & operator=(unsigned char Value)
00257 {
00258 setValue(Value);
00259 return *this;
00260 }
00262 _XMLStackNode & operator=(double Value)
00263 {
00264 setValue(Value);
00265 return *this;
00266 }
00268 _XMLStackNode & operator=(float Value)
00269 {
00270 setValue(Value);
00271 return *this;
00272 }
00273 protected:
00274 virtual bool childNodePushed(void) { return false; }
00275 virtual void popped(void) { }
00276 virtual _XMLStackNode * clone(void) const = 0;
00277
00278 typedef std::basic_stringstream<_E, _Tr, _A> _XMLStackStringStream;
00279
00280 _XMLStackString convertValue(unsigned long Value)
00281 {
00282 _XMLStackStringStream Stream;
00283 Stream << Value;
00284 return Stream.str();
00285 }
00286
00287 _XMLStackString convertValue(long Value)
00288 {
00289 _XMLStackStringStream Stream;
00290 Stream << Value;
00291 return Stream.str();
00292 }
00293
00294 _XMLStackString convertValue(unsigned int Value)
00295 {
00296 _XMLStackStringStream Stream;
00297 Stream << Value;
00298 return Stream.str();
00299 }
00300
00301 _XMLStackString convertValue(int Value)
00302 {
00303 _XMLStackStringStream Stream;
00304 Stream << Value;
00305 return Stream.str();
00306 }
00307
00308 _XMLStackString convertValue(unsigned short Value)
00309 {
00310 _XMLStackStringStream Stream;
00311 Stream << Value;
00312 return Stream.str();
00313 }
00314
00315 _XMLStackString convertValue(short Value)
00316 {
00317 _XMLStackStringStream Stream;
00318 Stream << Value;
00319 return Stream.str();
00320 }
00321
00322 _XMLStackString convertValue(signed char Value)
00323 {
00324 _XMLStackStringStream Stream;
00325 Stream << Value;
00326 return Stream.str();
00327 }
00328
00329 _XMLStackString convertValue(char Value)
00330 {
00331 _XMLStackStringStream Stream;
00332 Stream << Value;
00333 return Stream.str();
00334 }
00335
00336 _XMLStackString convertValue(unsigned char Value)
00337 {
00338 _XMLStackStringStream Stream;
00339 Stream << Value;
00340 return Stream.str();
00341 }
00342
00343 _XMLStackString convertValue(double Value, int Scale)
00344 {
00345 _XMLStackStringStream Stream;
00346 Stream << std::fixed << std::setprecision(Scale) << Value;
00347 return Stream.str();
00348 }
00349
00350 _XMLStackString convertValue(float Value, int Scale)
00351 {
00352 _XMLStackStringStream Stream;
00353 Stream << std::fixed << std::setprecision(Scale) << Value;
00354 return Stream.str();
00355 }
00356
00357
00358
00359
00360
00361
00362 void appendXML(const _XMLStackString & XML)
00363 {
00364 m_Doc->appendXML(XML);
00365 }
00366
00367
00368 inline _XMLStackString & getBuffer(void) { return m_Doc->m_XML; }
00369
00370 _XMLStackDocument * m_Doc;
00371 _XMLStackString m_Name;
00372
00373 private:
00374
00375 friend class XMLStackDocument<_E, _Tr, _A>;
00376 };
00377
00378
00384 template<class _E, class _Tr = std::char_traits<_E>, class _A = std::allocator<_E> >
00385 class XMLStackElement : public XMLStackNode<_E, _Tr, _A>
00386 {
00387 public:
00388 typedef XMLStackElement<_E, _Tr, _A> _XMLStackElement;
00389
00402 XMLStackElement(_XMLStackDocument * Doc,
00403 const _XMLStackString & Name)
00404 : _XMLStackNode(Doc, Name)
00405 {
00406 m_StartTagBegin = 0;
00407 m_StartTagEnd = 0;
00408 m_Dirty = false;
00409 m_NSDefined = false;
00410
00411 #ifdef _DEBUG
00412 checkName();
00413 #endif
00414 }
00415
00440 XMLStackElement(_XMLStackDocument * Doc,
00441 const _XMLStackString & Name,
00442 const _XMLStackString & NamespaceURI)
00443 : _XMLStackNode(Doc, Name), m_NamespaceURI(NamespaceURI)
00444 {
00445 m_StartTagBegin = 0;
00446 m_StartTagEnd = 0;
00447 m_Dirty = false;
00448 m_NSDefined = true;
00449
00450 #ifdef _DEBUG
00451 checkName();
00452 #endif
00453 }
00454
00456 virtual ~XMLStackElement()
00457 {
00458
00459 for (AttributesVec::iterator Iter = m_AttributesVec.begin();
00460 Iter != m_AttributesVec.end(); ++Iter)
00461 {
00462 delete (*Iter);
00463 }
00464 }
00465
00467 const _XMLStackString & getNamespaceURI(void) const
00468 {
00469 return m_NamespaceURI;
00470 }
00471
00485 virtual void setValue(const _XMLStackString & Value)
00486 {
00487 m_Doc->pushText(Value);
00488 m_Doc->pop();
00489 }
00490 virtual void setValue(unsigned long Value) { setValue(convertValue(Value)); }
00491 virtual void setValue(long Value) { setValue(convertValue(Value)); }
00492 virtual void setValue(unsigned int Value) { setValue(convertValue(Value)); }
00493 virtual void setValue(int Value) { setValue(convertValue(Value)); }
00494 virtual void setValue(unsigned short Value) { setValue(convertValue(Value)); }
00495 virtual void setValue(short Value) { setValue(convertValue(Value)); }
00496 virtual void setValue(signed char Value) { setValue(convertValue(Value)); }
00497 virtual void setValue(char Value) { setValue(convertValue(Value)); }
00498 virtual void setValue(unsigned char Value) { setValue(convertValue(Value)); }
00499 virtual void setValue(double Value, int Scale = 6)
00500 {
00501 setValue(convertValue(Value, Scale));
00502 }
00503 virtual void setValue(float Value, int Scale = 6)
00504 {
00505 setValue(convertValue(Value, Scale));
00506 }
00507
00528 virtual _XMLStackAttribute & createAttribute
00529 (const _XMLStackString & Name,
00530 const _XMLStackString & NamespaceURI = _XMLStackString())
00531 {
00532 if (m_Attributes.find(Name) == m_Attributes.end())
00533 {
00534
00535
00536 m_AttributesVec.push_back
00537 (new _XMLStackAttribute(m_Doc, Name, NamespaceURI));
00538
00539
00540 m_Attributes[Name] = m_AttributesVec.back();
00541 m_Dirty = true;
00542 return *m_AttributesVec.back();
00543 }
00544 std::string Msg;
00545
00546 Msg = "ERROR: Element node ";
00547 Msg += _CE(m_Name.c_str());
00548 Msg += " already has an Attribute node named ";
00549 Msg += _CE(Name.c_str());
00550 Msg += ".";
00551 throw XMLStackException(Msg);
00552 }
00553
00560 virtual _XMLStackAttribute & getAttribute(const _XMLStackString & Name)
00561 {
00562 Attributes::iterator Iter = m_Attributes.find(Name);
00563
00564 if (Iter != m_Attributes.end())
00565 {
00566 return *(*Iter).second;
00567 }
00568 std::string Msg;
00569
00570 Msg = "ERROR: Element node ";
00571 Msg += _CE(m_Name.c_str());
00572 Msg += " does not have an Attribute node named ";
00573 Msg += _CE(Name.c_str());
00574 Msg += ".";
00575 throw XMLStackException(Msg);
00576 }
00577
00582 virtual bool hasAttribute(const _XMLStackString & Name) const
00583 {
00584 if (m_Attributes.find(Name) != m_Attributes.end())
00585 {
00586 return true;
00587 }
00588 return false;
00589 }
00590
00592 _XMLStackElement & operator=(const _XMLStackString & Value)
00593 {
00594 setValue(Value);
00595 return *this;
00596 }
00597
00599 _XMLStackElement & operator=(unsigned long & Value)
00600 {
00601 setValue(Value);
00602 return *this;
00603 }
00604
00606 _XMLStackElement & operator=(long Value)
00607 {
00608 setValue(Value);
00609 return *this;
00610 }
00611
00613 _XMLStackElement & operator=(unsigned int Value)
00614 {
00615 setValue(Value);
00616 return *this;
00617 }
00618
00620 _XMLStackElement & operator=(int Value)
00621 {
00622 setValue(Value);
00623 return *this;
00624 }
00625
00627 _XMLStackElement & operator=(unsigned short Value)
00628 {
00629 setValue(Value);
00630 return *this;
00631 }
00632
00634 _XMLStackElement & operator=(short Value)
00635 {
00636 setValue(Value);
00637 return *this;
00638 }
00639
00641 _XMLStackElement & operator=(signed char Value)
00642 {
00643 setValue(Value);
00644 return *this;
00645 }
00646
00648 _XMLStackElement & operator=(char Value)
00649 {
00650 setValue(Value);
00651 return *this;
00652 }
00653
00655 _XMLStackElement & operator=(unsigned char Value)
00656 {
00657 setValue(Value);
00658 return *this;
00659 }
00660
00662 _XMLStackElement & operator=(double Value)
00663 {
00664 setValue(Value);
00665 return *this;
00666 }
00667
00669 _XMLStackElement & operator=(float Value)
00670 {
00671 setValue(Value);
00672 return *this;
00673 }
00674
00675
00676 protected:
00677 virtual bool childNodePushed(void)
00678 {
00679 writeStartTag();
00680 return true;
00681 }
00682
00683 typedef std::map<_XMLStackString, _XMLStackAttribute *> Attributes;
00684 typedef std::vector<_XMLStackAttribute *> AttributesVec;
00685
00686 _XMLStackString m_NamespaceURI;
00687 Attributes m_Attributes;
00688 AttributesVec m_AttributesVec;
00689 size_t m_StartTagBegin;
00690 size_t m_StartTagEnd;
00691 bool m_Dirty;
00692 bool m_NSDefined;
00693
00694 void writeStartTag(bool EndTag = false)
00695 {
00696 if ((m_StartTagBegin + m_StartTagEnd) == 0 || m_Dirty)
00697 {
00698 _XMLStackString Tag;
00699
00700 Tag = m_Doc->VALS.LT;
00701 Tag += m_Name;
00702
00703
00704 if (m_NSDefined)
00705 {
00706 _XMLStackString Prefix = getPrefix();
00707
00708 if (Prefix.length() > 0)
00709 {
00710 Tag += m_Doc->VALS.S_XMLNS_C;
00711 Tag += Prefix;
00712 Tag += m_Doc->VALS.EQUAL + m_Doc->VALS.QUOTE;
00713 Tag += m_NamespaceURI + m_Doc->VALS.QUOTE;
00714 }
00715 else
00716 {
00717 Tag += m_Doc->VALS.SPACE + m_Doc->VALS.XMLNS + m_Doc->VALS.EQUAL;
00718 Tag += m_Doc->VALS.QUOTE + m_NamespaceURI + m_Doc->VALS.QUOTE;
00719 }
00720 }
00721
00722
00723 for (AttributesVec::iterator Iter = m_AttributesVec.begin();
00724 Iter != m_AttributesVec.end(); ++Iter)
00725 {
00726 Tag += m_Doc->VALS.SPACE;
00727 Tag += (*Iter)->xml();
00728 (*Iter)->setDirty(false);
00729 }
00730
00731 if (EndTag)
00732 {
00733 Tag += m_Doc->VALS.SLASH + m_Doc->VALS.GT;
00734 }
00735 else
00736 {
00737 Tag += m_Doc->VALS.GT;
00738 }
00739
00740 if ((m_StartTagBegin + m_StartTagEnd) == 0)
00741 {
00742
00743 m_StartTagBegin = getBuffer().size();
00744 appendXML(Tag);
00745 m_StartTagEnd = getBuffer().size();
00746 }
00747 else
00748 {
00749
00750
00751
00752 getBuffer().replace(m_StartTagBegin, m_StartTagEnd - m_StartTagBegin, Tag);
00753 m_StartTagEnd = m_StartTagBegin + Tag.size() - 1;
00754 }
00755 m_Dirty = false;
00756 }
00757 }
00758
00759 virtual void popped(void)
00760 {
00761 _XMLStackString Tag;
00762
00763 if ((m_StartTagBegin + m_StartTagEnd) == 0)
00764 {
00765 writeStartTag(true);
00766 }
00767 else
00768 {
00769 if (!m_Dirty)
00770 {
00771
00772 for (AttributesVec::iterator Iter = m_AttributesVec.begin();
00773 Iter != m_AttributesVec.end(); ++Iter)
00774 {
00775 if ((*Iter)->isDirty())
00776 {
00777 m_Dirty = true;
00778 break;
00779 }
00780 }
00781 }
00782
00783 if (m_Dirty)
00784 {
00785
00786
00787
00788 writeStartTag(false);
00789 }
00790 Tag += m_Doc->VALS.LT + m_Doc->VALS.SLASH;
00791 Tag += m_Name;
00792 Tag += m_Doc->VALS.GT;
00793 appendXML(Tag);
00794 }
00795 }
00796
00797 virtual _XMLStackNode * clone(void) const
00798 {
00799 return new _XMLStackElement(*this);
00800 }
00801
00802 void checkName(void) const
00803 {
00804
00805
00806
00807
00808 const wchar_t * IllegalChars = L"/;<=>?@[\\]^`\173\174\175\176";
00809 bool Illegal = false;
00810
00811 if (m_Name.size() == 0)
00812 {
00813 throw XMLStackException("ERROR: Element nodes must have a defined"
00814 " name.");
00815 }
00816
00817
00818
00819
00820
00821 int j;
00822 for (int i = 0; i < m_Name.size(); ++i)
00823 {
00824 if (m_Name[i] <= 44)
00825 {
00826
00827 Illegal = true;
00828 }
00829
00830 j = 0;
00831 while (!Illegal && IllegalChars[j] != 0)
00832 {
00833 if (m_Name[i] == IllegalChars[j])
00834 {
00835 Illegal = true;
00836 }
00837 j++;
00838 }
00839
00840 if (Illegal)
00841 {
00842 std::stringstream Msg;
00843 Msg << "ERROR: Invalid character found in node name";
00844 if (m_Name[i] < L' ' || m_Name[i] > L'z')
00845 {
00846 Msg << ". Decimal value of illegal character is " << (int) m_Name[i];
00847 }
00848 else
00849 {
00850 Msg << " -->" << (char) m_Name[i] << "<--";
00851 }
00852 throw XMLStackException(Msg.str());
00853 }
00854 }
00855 }
00856
00857 };
00858
00859
00861 template<class _E, class _Tr = std::char_traits<_E>, class _A = std::allocator<_E> >
00862 class XMLStackAttribute : public XMLStackNode<_E, _Tr, _A>
00863 {
00864 public:
00888 XMLStackAttribute(_XMLStackDocument * Doc,
00889 const _XMLStackString & Name,
00890 const _XMLStackString & NamespaceURI = _XMLStackString())
00891 : _XMLStackNode(Doc, Name), m_NamespaceURI(NamespaceURI)
00892 {
00893 m_Dirty = false;
00894
00895
00896 #ifdef _DEBUG
00897
00898
00899
00900
00901 const wchar_t * IllegalChars = L"/;<=>?@[\\]^`\173\174\175\176";
00902 bool Illegal = false;
00903
00904 if (Name.size() == 0)
00905 {
00906 throw XMLStackException("ERROR: Attribute nodes must have a defined"
00907 " name.");
00908 }
00909
00910
00911
00912
00913 int j;
00914 for (int i = 0; i < Name.size(); ++i)
00915 {
00916 if (Name[i] <= 44)
00917 {
00918
00919 Illegal = true;
00920 }
00921
00922 j = 0;
00923 while (!Illegal && IllegalChars[j] != L'\0')
00924 {
00925 if (Name[i] == IllegalChars[j])
00926 {
00927 Illegal = true;
00928 }
00929 j++;
00930 }
00931
00932 if (Illegal)
00933 {
00934 std::stringstream Msg;
00935 Msg << "ERROR: Invalid character found in node name";
00936 if (Name[i] < L' ' || Name[i] > L'z')
00937 {
00938 Msg << ". Decimal value of illegal character is " << (int) Name[i];
00939 }
00940 else
00941 {
00942 Msg << " -->" << (char) Name[i] << "<--";
00943 }
00944 throw XMLStackException(Msg.str());
00945 }
00946 }
00947 #endif
00948 }
00949
00951 virtual ~XMLStackAttribute() {}
00952
00954 const _XMLStackString & getNamespaceURI(void) const
00955 {
00956 return m_NamespaceURI;
00957 }
00958
00963 virtual void setValue(const _XMLStackString & Value)
00964 {
00965 m_Value = Value;
00966 m_Dirty = true;
00967 }
00968 virtual void setValue(unsigned long Value) { setValue(convertValue(Value)); }
00969 virtual void setValue(long Value) { setValue(convertValue(Value)); }
00970 virtual void setValue(unsigned int Value) { setValue(convertValue(Value)); }
00971 virtual void setValue(int Value) { setValue(convertValue(Value)); }
00972 virtual void setValue(unsigned short Value) { setValue(convertValue(Value)); }
00973 virtual void setValue(short Value) { setValue(convertValue(Value)); }
00974 virtual void setValue(signed char Value) { setValue(convertValue(Value)); }
00975 virtual void setValue(char Value) { setValue(convertValue(Value)); }
00976 virtual void setValue(unsigned char Value) { setValue(convertValue(Value)); }
00977 virtual void setValue(double Value, int Scale = 6)
00978 {
00979 setValue(convertValue(Value, Scale));
00980 }
00981 virtual void setValue(float Value, int Scale = 6)
00982 {
00983 setValue(convertValue(Value, Scale));
00984 }
00985
00986
00988 _XMLStackString xml(void) const
00989 {
00990 _XMLStackString Value;
00991
00992 if (m_NamespaceURI.length() > 0)
00993 {
00994 _XMLStackString Prefix = getPrefix();
00995
00996 if (Prefix.length() > 0)
00997 {
00998 Value += m_Doc->VALS.XMLNS + m_Doc->VALS.COLON;
00999 Value += Prefix + m_Doc->VALS.EQUAL + m_Doc->VALS.QUOTE;
01000 Value += m_NamespaceURI + m_Doc->VALS.QUOTE + m_Doc->VALS.SPACE;
01001 }
01002 }
01003
01004 Value += m_Name + m_Doc->VALS.EQUAL + m_Doc->VALS.QUOTE;
01005
01006 if (m_Value.size() > 0)
01007 {
01008 _XMLStackString::size_type Pos = 0;
01009
01010 Pos = Value.size();
01011 Value += m_Value;
01012
01013 while (Pos < Value.size())
01014 {
01015 if (Value[Pos] == '&')
01016 {
01017 Value.replace(Pos, 1, m_Doc->VALS.AMP_REF);
01018 Pos += m_Doc->VALS.AMP_REF.size();
01019 }
01020 else if (Value[Pos] == '<')
01021 {
01022 Value.replace(Pos, 1, m_Doc->VALS.LT_REF);
01023 Pos += m_Doc->VALS.LT_REF.size();
01024 }
01025 else if (Value[Pos] == '"')
01026 {
01027 Value.replace(Pos, 1, m_Doc->VALS.QUOTE_REF);
01028 Pos += m_Doc->VALS.QUOTE_REF.size();
01029 }
01030 else
01031 {
01032 Pos++;
01033 }
01034 }
01035 }
01036 Value += m_Doc->VALS.QUOTE;
01037
01038 return Value;
01039 }
01040
01042 bool isDirty(void) const { return m_Dirty; }
01043
01045 void setDirty(bool Dirty) { m_Dirty = Dirty; }
01046
01048 _XMLStackAttribute & operator=(const _XMLStackString & Value)
01049 {
01050 setValue(Value);
01051 return *this;
01052 }
01053
01055 _XMLStackAttribute & operator=(unsigned long & Value)
01056 {
01057 setValue(Value);
01058 return *this;
01059 }
01060
01062 _XMLStackAttribute & operator=(long Value)
01063 {
01064 setValue(Value);
01065 return *this;
01066 }
01067
01069 _XMLStackAttribute & operator=(unsigned int Value)
01070 {
01071 setValue(Value);
01072 return *this;
01073 }
01074
01076 _XMLStackAttribute & operator=(int Value)
01077 {
01078 setValue(Value);
01079 return *this;
01080 }
01081
01083 _XMLStackAttribute & operator=(unsigned short Value)
01084 {
01085 setValue(Value);
01086 return *this;
01087 }
01088
01090 _XMLStackAttribute & operator=(short Value)
01091 {
01092 setValue(Value);
01093 return *this;
01094 }
01095
01097 _XMLStackAttribute & operator=(signed char Value)
01098 {
01099 setValue(Value);
01100 return *this;
01101 }
01102
01104 _XMLStackAttribute & operator=(char Value)
01105 {
01106 setValue(Value);
01107 return *this;
01108 }
01109
01111 _XMLStackAttribute & operator=(unsigned char Value)
01112 {
01113 setValue(Value);
01114 return *this;
01115 }
01116
01118 _XMLStackAttribute & operator=(double Value)
01119 {
01120 setValue(Value);
01121 return *this;
01122 }
01123
01125 _XMLStackAttribute & operator=(float Value)
01126 {
01127 setValue(Value);
01128 return *this;
01129 }
01130
01131
01132 protected:
01133
01134 _XMLStackString m_NamespaceURI;
01135 _XMLStackString m_Value;
01136 bool m_Dirty;
01137
01138 virtual _XMLStackNode * clone(void) const
01139 {
01140 return new _XMLStackAttribute(*this);
01141 }
01142 friend class XMLStackElement<_E, _Tr, _A>;
01143 };
01144
01145
01152 template<class _E, class _Tr = std::char_traits<_E>, class _A = std::allocator<_E> >
01153 class XMLStackText : public XMLStackNode<_E, _Tr, _A>
01154 {
01155 public:
01156 typedef XMLStackText<_E, _Tr, _A> _XMLStackText;
01157
01165 XMLStackText(_XMLStackDocument * Doc,
01166 const _XMLStackString & Data)
01167 : _XMLStackNode(Doc, _XMLStackString()), m_Value(Data)
01168 {
01169 }
01170
01172 virtual ~XMLStackText() {}
01173
01175 virtual void setValue(const _XMLStackString & Value) { m_Value = Value; }
01176 virtual void setValue(unsigned long Value) { setValue(convertValue(Value)); }
01177 virtual void setValue(long Value) { setValue(convertValue(Value)); }
01178 virtual void setValue(unsigned int Value) { setValue(convertValue(Value)); }
01179 virtual void setValue(int Value) { setValue(convertValue(Value)); }
01180 virtual void setValue(unsigned short Value) { setValue(convertValue(Value)); }
01181 virtual void setValue(short Value) { setValue(convertValue(Value)); }
01182 virtual void setValue(signed char Value) { setValue(convertValue(Value)); }
01183 virtual void setValue(char Value) { setValue(convertValue(Value)); }
01184 virtual void setValue(unsigned char Value) { setValue(convertValue(Value)); }
01185 virtual void setValue(double Value, int Scale = 6)
01186 {
01187 setValue(convertValue(Value, Scale));
01188 }
01189 virtual void setValue(float Value, int Scale = 6)
01190 {
01191 setValue(convertValue(Value, Scale));
01192 }
01193
01195 _XMLStackText & operator=(const _XMLStackString & Value)
01196 {
01197 setValue(Value);
01198 return *this;
01199 }
01200
01202 _XMLStackText & operator=(unsigned long & Value)
01203 {
01204 setValue(Value);
01205 return *this;
01206 }
01207
01209 _XMLStackText & operator=(long Value)
01210 {
01211 setValue(Value);
01212 return *this;
01213 }
01214
01216 _XMLStackText & operator=(unsigned int Value)
01217 {
01218 setValue(Value);
01219 return *this;
01220 }
01221
01223 _XMLStackText & operator=(int Value)
01224 {
01225 setValue(Value);
01226 return *this;
01227 }
01228
01230 _XMLStackText & operator=(unsigned short Value)
01231 {
01232 setValue(Value);
01233 return *this;
01234 }
01235
01237 _XMLStackText & operator=(short Value)
01238 {
01239 setValue(Value);
01240 return *this;
01241 }
01242
01244 _XMLStackText & operator=(signed char Value)
01245 {
01246 setValue(Value);
01247 return *this;
01248 }
01249
01251 _XMLStackText & operator=(char Value)
01252 {
01253 setValue(Value);
01254 return *this;
01255 }
01256
01258 _XMLStackText & operator=(unsigned char Value)
01259 {
01260 setValue(Value);
01261 return *this;
01262 }
01263
01265 _XMLStackText & operator=(double Value)
01266 {
01267 setValue(Value);
01268 return *this;
01269 }
01270
01272 _XMLStackText & operator=(float Value)
01273 {
01274 setValue(Value);
01275 return *this;
01276 }
01277
01278 protected:
01279 _XMLStackString m_Value;
01280
01281 virtual void popped(void)
01282 {
01283 if (m_Value.size() == 0)
01284 {
01285 return;
01286 }
01287 _XMLStackString::size_type Pos = 0;
01288
01289 while (Pos < m_Value.size())
01290 {
01291 if (m_Value[Pos] == '&')
01292 {
01293 m_Value.replace(Pos, 1, m_Doc->VALS.AMP_REF);
01294 Pos += m_Doc->VALS.AMP_REF.size();
01295 }
01296 else if (m_Value[Pos] == '<')
01297 {
01298 m_Value.replace(Pos, 1, m_Doc->VALS.LT_REF);
01299 Pos += m_Doc->VALS.LT_REF.size();
01300 }
01301 else
01302 {
01303 Pos++;
01304 }
01305 }
01306 appendXML(m_Value);
01307 }
01308
01309 virtual _XMLStackNode * clone(void) const
01310 {
01311 return new _XMLStackText(*this);
01312 }
01313 };
01314
01326 template<class _E, class _Tr = std::char_traits<_E>, class _A = std::allocator<_E> >
01327 class XMLStackCDATASection : public XMLStackNode<_E, _Tr, _A>
01328 {
01329 public:
01330 typedef XMLStackCDATASection<_E, _Tr, _A> _XMLStackCDATASection;
01331
01341 XMLStackCDATASection(_XMLStackDocument * Doc,
01342 const _XMLStackString & Data)
01343 : _XMLStackNode(Doc, _XMLStackString()), m_Value(Data)
01344 {
01345 }
01346
01348 virtual ~XMLStackCDATASection() {}
01349
01351 virtual void setValue(const _XMLStackString & Value) { m_Value = Value; }
01352 virtual void setValue(unsigned long Value) { setValue(convertValue(Value)); }
01353 virtual void setValue(long Value) { setValue(convertValue(Value)); }
01354 virtual void setValue(unsigned int Value) { setValue(convertValue(Value)); }
01355 virtual void setValue(int Value) { setValue(convertValue(Value)); }
01356 virtual void setValue(unsigned short Value) { setValue(convertValue(Value)); }
01357 virtual void setValue(short Value) { setValue(convertValue(Value)); }
01358 virtual void setValue(signed char Value) { setValue(convertValue(Value)); }
01359 virtual void setValue(char Value) { setValue(convertValue(Value)); }
01360 virtual void setValue(unsigned char Value) { setValue(convertValue(Value)); }
01361 virtual void setValue(double Value, int Scale = 6)
01362 {
01363 setValue(convertValue(Value, Scale));
01364 }
01365 virtual void setValue(float Value, int Scale = 6)
01366 {
01367 setValue(convertValue(Value, Scale));
01368 }
01369
01371 _XMLStackCDATASection & operator=(const _XMLStackString & Value)
01372 {
01373 setValue(Value);
01374 return *this;
01375 }
01376
01378 _XMLStackCDATASection & operator=(unsigned long & Value)
01379 {
01380 setValue(Value);
01381 return *this;
01382 }
01383
01385 _XMLStackCDATASection & operator=(long Value)
01386 {
01387 setValue(Value);
01388 return *this;
01389 }
01390
01392 _XMLStackCDATASection & operator=(unsigned int Value)
01393 {
01394 setValue(Value);
01395 return *this;
01396 }
01397
01399 _XMLStackCDATASection & operator=(int Value)
01400 {
01401 setValue(Value);
01402 return *this;
01403 }
01404
01406 _XMLStackCDATASection & operator=(unsigned short Value)
01407 {
01408 setValue(Value);
01409 return *this;
01410 }
01411
01413 _XMLStackCDATASection & operator=(short Value)
01414 {
01415 setValue(Value);
01416 return *this;
01417 }
01418
01420 _XMLStackCDATASection & operator=(signed char Value)
01421 {
01422 setValue(Value);
01423 return *this;
01424 }
01425
01427 _XMLStackCDATASection & operator=(char Value)
01428 {
01429 setValue(Value);
01430 return *this;
01431 }
01432
01434 _XMLStackCDATASection & operator=(unsigned char Value)
01435 {
01436 setValue(Value);
01437 return *this;
01438 }
01439
01441 _XMLStackCDATASection & operator=(double Value)
01442 {
01443 setValue(Value);
01444 return *this;
01445 }
01446
01448 _XMLStackCDATASection & operator=(float Value)
01449 {
01450 setValue(Value);
01451 return *this;
01452 }
01453
01454 protected:
01455 _XMLStackString m_Value;
01456
01457 virtual void popped(void)
01458 {
01459 #ifdef _DEBUG
01460 if (m_Value.find(m_Doc->CDATA_END) != _XMLStackString::npos)
01461 {
01462
01463
01464 throw XMLStackException("ERROR: CDATASection node contains the reserved"
01465 " delimiter \"]]>\", which cannot be escaped.");
01466 }
01467 #endif
01468 _XMLStackString Value;
01469
01470 Value = m_Doc->CDATA_START;
01471 Value += m_Value;
01472 Value += m_Doc->CDATA_END;
01473 appendXML(Value);
01474 }
01475
01476 virtual _XMLStackNode * clone(void) const
01477 {
01478 return new _XMLStackCDATASection(*this);
01479 }
01480 };
01481
01482
01491 template<class _E, class _Tr = std::char_traits<_E>, class _A = std::allocator<_E> >
01492 class XMLStackComment : public XMLStackNode<_E, _Tr, _A>
01493 {
01494 public:
01495 typedef XMLStackComment<_E, _Tr, _A> _XMLStackComment;
01496
01507 XMLStackComment(_XMLStackDocument * Doc,
01508 const _XMLStackString & Data)
01509 : _XMLStackNode(Doc, _XMLStackString()), m_Text(Data)
01510 {
01511 }
01512
01514 virtual ~XMLStackComment() {}
01515
01517 virtual void setValue(const _XMLStackString & Value) { m_Text = Value; }
01518 virtual void setValue(unsigned long Value) { setValue(convertValue(Value)); }
01519 virtual void setValue(long Value) { setValue(convertValue(Value)); }
01520 virtual void setValue(unsigned int Value) { setValue(convertValue(Value)); }
01521 virtual void setValue(int Value) { setValue(convertValue(Value)); }
01522 virtual void setValue(unsigned short Value) { setValue(convertValue(Value)); }
01523 virtual void setValue(short Value) { setValue(convertValue(Value)); }
01524 virtual void setValue(signed char Value) { setValue(convertValue(Value)); }
01525 virtual void setValue(char Value) { setValue(convertValue(Value)); }
01526 virtual void setValue(unsigned char Value) { setValue(convertValue(Value)); }
01527 virtual void setValue(double Value, int Scale = 6)
01528 {
01529 setValue(convertValue(Value, Scale));
01530 }
01531 virtual void setValue(float Value, int Scale = 6)
01532 {
01533 setValue(convertValue(Value, Scale));
01534 }
01535
01537 _XMLStackComment & operator=(const _XMLStackString & Value)
01538 {
01539 setValue(Value);
01540 return *this;
01541 }
01542
01544 _XMLStackComment & operator=(unsigned long & Value)
01545 {
01546 setValue(Value);
01547 return *this;
01548 }
01549
01551 _XMLStackComment & operator=(long Value)
01552 {
01553 setValue(Value);
01554 return *this;
01555 }
01556
01558 _XMLStackComment & operator=(unsigned int Value)
01559 {
01560 setValue(Value);
01561 return *this;
01562 }
01563
01565 _XMLStackComment & operator=(int Value)
01566 {
01567 setValue(Value);
01568 return *this;
01569 }
01570
01572 _XMLStackComment & operator=(unsigned short Value)
01573 {
01574 setValue(Value);
01575 return *this;
01576 }
01577
01579 _XMLStackComment & operator=(short Value)
01580 {
01581 setValue(Value);
01582 return *this;
01583 }
01584
01586 _XMLStackComment & operator=(signed char Value)
01587 {
01588 setValue(Value);
01589 return *this;
01590 }
01591
01593 _XMLStackComment & operator=(char Value)
01594 {
01595 setValue(Value);
01596 return *this;
01597 }
01598
01600 _XMLStackComment & operator=(unsigned char Value)
01601 {
01602 setValue(Value);
01603 return *this;
01604 }
01605
01607 _XMLStackComment & operator=(double Value)
01608 {
01609 setValue(Value);
01610 return *this;
01611 }
01612
01614 _XMLStackComment & operator=(float Value)
01615 {
01616 setValue(Value);
01617 return *this;
01618 }
01619
01620 protected:
01621 _XMLStackString m_Text;
01622
01623 virtual void popped(void)
01624 {
01625 #ifdef _DEBUG
01626 if (m_Text.find(m_Doc->VALS.DASH2) != _XMLStackString::npos
01627 || (m_Text.size() > 0 && m_Text[m_Text.size() - 1] == '-'))
01628 {
01629 throw XMLStackException("ERROR: Comment nodes cannot contain the"
01630 " character sequence \"--\" or end with a single dash '-'");
01631 }
01632 #endif
01633 _XMLStackString Value(m_Doc->VALS.COMMENT_START);
01634 Value += m_Text + m_Doc->VALS.COMMENT_END;
01635 appendXML(Value);
01636 }
01637 virtual _XMLStackNode * clone(void) const
01638 {
01639 return new _XMLStackComment(*this);
01640 }
01641 };
01642
01643
01645 template<class _E, class _Tr = std::char_traits<_E>, class _A = std::allocator<_E> >
01646 class XMLStackProcessingInstruction : public XMLStackNode<_E, _Tr, _A>
01647 {
01648 public:
01649 typedef XMLStackProcessingInstruction<_E, _Tr, _A>
01650 _XMLStackProcessingInstruction;
01651
01660 XMLStackProcessingInstruction(_XMLStackDocument * Doc,
01661 const _XMLStackString & Target)
01662 : _XMLStackNode(Doc, Target)
01663 {
01664 #ifdef _DEBUG
01665 if (Target.size() == 0)
01666 {
01667 throw XMLStackException("ERROR: Processing Instruction nodes must"
01668 " have a defined name.");
01669 }
01670 #endif
01671 }
01672
01674 virtual ~XMLStackProcessingInstruction() {}
01675
01677 virtual void setValue(const _XMLStackString & Value) { m_Value = Value; }
01678 virtual void setValue(unsigned long Value) { setValue(convertValue(Value)); }
01679 virtual void setValue(long Value) { setValue(convertValue(Value)); }
01680 virtual void setValue(unsigned int Value) { setValue(convertValue(Value)); }
01681 virtual void setValue(int Value) { setValue(convertValue(Value)); }
01682 virtual void setValue(unsigned short Value) { setValue(convertValue(Value)); }
01683 virtual void setValue(short Value) { setValue(convertValue(Value)); }
01684 virtual void setValue(signed char Value) { setValue(convertValue(Value)); }
01685 virtual void setValue(char Value) { setValue(convertValue(Value)); }
01686 virtual void setValue(unsigned char Value) { setValue(convertValue(Value)); }
01687 virtual void setValue(double Value, int Scale = 6)
01688 {
01689 setValue(convertValue(Value, Scale));
01690 }
01691 virtual void setValue(float Value, int Scale = 6)
01692 {
01693 setValue(convertValue(Value, Scale));
01694 }
01695
01697 _XMLStackProcessingInstruction & operator=(const _XMLStackString & Value)
01698 {
01699 setValue(Value);
01700 return *this;
01701 }
01702
01704 _XMLStackProcessingInstruction & operator=(unsigned long & Value)
01705 {
01706 setValue(Value);
01707 return *this;
01708 }
01709
01711 _XMLStackProcessingInstruction & operator=(long Value)
01712 {
01713 setValue(Value);
01714 return *this;
01715 }
01716
01718 _XMLStackProcessingInstruction & operator=(unsigned int Value)
01719 {
01720 setValue(Value);
01721 return *this;
01722 }
01723
01725 _XMLStackProcessingInstruction & operator=(int Value)
01726 {
01727 setValue(Value);
01728 return *this;
01729 }
01730
01732 _XMLStackProcessingInstruction & operator=(unsigned short Value)
01733 {
01734 setValue(Value);
01735 return *this;
01736 }
01737
01739 _XMLStackProcessingInstruction & operator=(short Value)
01740 {
01741 setValue(Value);
01742 return *this;
01743 }
01744
01746 _XMLStackProcessingInstruction & operator=(signed char Value)
01747 {
01748 setValue(Value);
01749 return *this;
01750 }
01751
01753 _XMLStackProcessingInstruction & operator=(char Value)
01754 {
01755 setValue(Value);
01756 return *this;
01757 }
01758
01760 _XMLStackProcessingInstruction & operator=(unsigned char Value)
01761 {
01762 setValue(Value);
01763 return *this;
01764 }
01765
01767 _XMLStackProcessingInstruction & operator=(double Value)
01768 {
01769 setValue(Value);
01770 return *this;
01771 }
01772
01774 _XMLStackProcessingInstruction & operator=(float Value)
01775 {
01776 setValue(Value);
01777 return *this;
01778 }
01779
01780 protected:
01781 _XMLStackString m_Value;
01782
01783 virtual void popped(void)
01784 {
01785 _XMLStackString Value(m_Doc->VALS.PI_START);
01786 Value += m_Name + m_Doc->VALS.SPACE + m_Value + m_Doc->VALS.PI_END;
01787 appendXML(Value);
01788 }
01789
01790 virtual _XMLStackNode * clone(void) const
01791 {
01792 return new _XMLStackProcessingInstruction(*this);
01793 }
01794 };
01795
01796
01809 template<class _E, class _Tr = std::char_traits<_E>, class _A = std::allocator<_E> >
01810 class XMLStackRawXML : public XMLStackNode<_E, _Tr, _A>
01811 {
01812 public:
01813 typedef XMLStackRawXML<_E, _Tr, _A> _XMLStackRawXML;
01814
01822 XMLStackRawXML(_XMLStackDocument * Doc,
01823 const _XMLStackString & PushXML,
01824 const _XMLStackString & PopXML)
01825 : _XMLStackNode(Doc, _XMLStackString()), m_PopXML(PopXML)
01826 {
01827 appendXML(PushXML);
01828 }
01829
01831 virtual ~XMLStackRawXML() {}
01832
01833 protected:
01834 _XMLStackString m_PopXML;
01835
01836 virtual bool childNodePushed(void)
01837 {
01838 return true;
01839 }
01840
01841 virtual void popped(void)
01842 {
01843 appendXML(m_PopXML);
01844 }
01845
01846 virtual _XMLStackNode * clone(void) const
01847 {
01848 return new _XMLStackRawXML(*this);
01849 }
01850 };
01851
01852
01854 template<class _E, class _Tr = std::char_traits<_E>, class _A = std::allocator<_E> >
01855 struct XMLStringConstants
01856 {
01857 typedef std::basic_string<_E, _Tr, _A> _XMLStackString;
01858
01859 XMLStringConstants()
01860 : LT(_CE(L"<")),
01861 GT(_CE(L">")),
01862 SPACE(_CE(L" ")),
01863 XMLNS(_CE(L"xmlns")),
01864 S_XMLNS_C(_CE(L" xmlns:")),
01865 COLON(_CE(L":")),
01866 EQUAL(_CE(L"=")),
01867 QUOTE(_CE(L"\"")),
01868 AMP_REF(_CE(L"&")),
01869 QUOTE_REF(_CE(L""")),
01870 LT_REF(_CE(L"<")),
01871 SLASH(_CE(L"/")),
01872 CDATA_START(_CE(L"<![CDATA[")),
01873 CDATA_END(_CE(L"]]>")),
01874 COMMENT_START(_CE(L"<!--")),
01875 COMMENT_END(_CE(L"-->")),
01876 DASH2(_CE(L"--")),
01877 PI_START(_CE(L"<?")),
01878 PI_END(_CE(L"?>"))
01879 {
01880 }
01881
01882
01883
01884 const _XMLStackString LT;
01885 const _XMLStackString GT;
01886 const _XMLStackString SPACE;
01887 const _XMLStackString XMLNS;
01888 const _XMLStackString S_XMLNS_C;
01889 const _XMLStackString COLON;
01890 const _XMLStackString EQUAL;
01891 const _XMLStackString QUOTE;
01892 const _XMLStackString AMP_REF;
01893 const _XMLStackString QUOTE_REF;
01894 const _XMLStackString LT_REF;
01895 const _XMLStackString SLASH;
01896 const _XMLStackString CDATA_START;
01897 const _XMLStackString CDATA_END;
01898 const _XMLStackString COMMENT_START;
01899 const _XMLStackString COMMENT_END;
01900 const _XMLStackString DASH2;
01901 const _XMLStackString PI_START;
01902 const _XMLStackString PI_END;
01903 };
01904
01999 template<class _E, class _Tr = std::char_traits<_E>, class _A = std::allocator<_E> >
02000 class XMLStackDocument
02001 {
02002 public:
02003 typedef std::basic_string<_E, _Tr, _A> _XMLStackString;
02004 typedef XMLStackDocument<_E, _Tr, _A> _XMLStackDocument;
02005 typedef XMLStackNode<_E, _Tr, _A> _XMLStackNode;
02006 typedef XMLStackElement<_E, _Tr, _A> _XMLStackElement;
02007 typedef XMLStackText<_E, _Tr, _A> _XMLStackText;
02008 typedef XMLStackCDATASection<_E, _Tr, _A> _XMLStackCDATASection;
02009 typedef XMLStackComment<_E, _Tr, _A> _XMLStackComment;
02010 typedef XMLStackProcessingInstruction<_E, _Tr, _A> _XMLStackProcessingInstruction;
02011 typedef XMLStackRawXML<_E, _Tr, _A> _XMLStackRawXML;
02012
02019 XMLStackDocument(unsigned long InitialBufferSize = 1024)
02020 {
02021
02022
02023 m_XML.reserve(InitialBufferSize);
02024 }
02025
02027 XMLStackDocument(const _XMLStackDocument & Instance)
02028 {
02029 *this = Instance;
02030 }
02031
02033 ~XMLStackDocument()
02034 {
02035 freeStack();
02036 }
02037
02045 void pop(void)
02046 {
02047 if (m_Stack.size() == 0)
02048 {
02049 throw XMLStackException("ERROR: Pop() - XMLStackDocument is empty.");
02050 }
02051 m_Stack.back()->popped();
02052 delete m_Stack.back();
02053 m_Stack.pop_back();
02054 }
02055
02060 void popAll(void)
02061 {
02062 while (m_Stack.size() > 0)
02063 {
02064 pop();
02065 }
02066 }
02067
02083 _XMLStackElement & pushElement(const _XMLStackString & Name)
02084 {
02085 if (m_Stack.size() > 0)
02086 {
02087 if (!m_Stack.back()->childNodePushed())
02088 {
02089 throw XMLStackException("ERROR: Cannot create a child XMLStackElement"
02090 " node of the given parent node.");
02091 }
02092 }
02093 _XMLStackElement * Element = new _XMLStackElement(this, Name);
02094
02095 m_Stack.push_back(Element);
02096 return *Element;
02097 }
02098
02127 _XMLStackElement & pushElement(const _XMLStackString & Name,
02128 const _XMLStackString & NamespaceURI)
02129 {
02130 if (m_Stack.size() > 0)
02131 {
02132 if (!m_Stack.back()->childNodePushed())
02133 {
02134 throw XMLStackException("ERROR: Cannot create a child XMLStackElement"
02135 " node of the given parent node.");
02136 }
02137 }
02138 _XMLStackElement * Element = new _XMLStackElement(this, Name, NamespaceURI);
02139
02140 m_Stack.push_back(Element);
02141 return *Element;
02142 }
02143
02158 _XMLStackText & pushText(const _XMLStackString & Data)
02159 {
02160 if (m_Stack.size() > 0)
02161 {
02162 if (!m_Stack.back()->childNodePushed())
02163 {
02164 throw XMLStackException("ERROR: Cannot create a child XMLStackText"
02165 " node of the given parent node.");
02166 }
02167 }
02168 _XMLStackText * Text = new _XMLStackText(this, Data);
02169
02170 m_Stack.push_back(Text);
02171 return *Text;
02172 }
02173
02193 _XMLStackCDATASection & pushCDATASection(const _XMLStackString & Data)
02194 {
02195 if (m_Stack.size() > 0)
02196 {
02197 if (!m_Stack.back()->childNodePushed())
02198 {
02199 throw XMLStackException("ERROR: Cannot create a child XMLStackCDATASection"
02200 " node of the given parent node.");
02201 }
02202 }
02203 _XMLStackCDATASection * Text = new _XMLStackCDATASection(this, Data);
02204
02205 m_Stack.push_back(Text);
02206 return *Text;
02207 }
02208
02222 _XMLStackComment & pushComment(const _XMLStackString & Data)
02223 {
02224 if (m_Stack.size() > 0)
02225 {
02226 if (!m_Stack.back()->childNodePushed())
02227 {
02228 throw XMLStackException("ERROR: Cannot create a child XMLStackComment"
02229 " node of the given parent node.");
02230 }
02231 }
02232 _XMLStackComment * Comment = new _XMLStackComment(this, Data);
02233
02234 m_Stack.push_back(Comment);
02235 return *Comment;
02236 }
02237
02252 _XMLStackProcessingInstruction & pushProcessingInstruction
02253 (const _XMLStackString & Target)
02254 {
02255 if (m_Stack.size() > 0)
02256 {
02257 if (!m_Stack.back()->childNodePushed())
02258 {
02259 throw XMLStackException("ERROR: Cannot create a child XMLStackProcessingInstruction"
02260 " node of the given parent node.");
02261 }
02262 }
02263 _XMLStackProcessingInstruction * PI =
02264 new _XMLStackProcessingInstruction(this, Target);
02265
02266 m_Stack.push_back(PI);
02267 return *PI;
02268 }
02269
02287 _XMLStackRawXML & pushRawXML(const _XMLStackString & PushXML,
02288 const _XMLStackString & PopXML)
02289 {
02290 if (m_Stack.size() > 0)
02291 {
02292 if (!m_Stack.back()->childNodePushed())
02293 {
02294 throw XMLStackException("ERROR: Cannot create a child XMLStackRawXML"
02295 " node of the given parent node.");
02296 }
02297 }
02298 _XMLStackRawXML * Node = new _XMLStackRawXML(this, PushXML, PopXML);
02299
02300 m_Stack.push_back(Node);
02301 return *Node;
02302 }
02303
02308 _XMLStackNode & top(void)
02309 {
02310 if (stackSize() > 0)
02311 {
02312 return *m_Stack.back();
02313 }
02314 throw XMLStackException("ERROR: top() called on empty stack.");
02315 }
02316
02321 const _XMLStackNode & top(void) const
02322 {
02323 if (stackSize() > 0)
02324 {
02325 return *m_Stack.back();
02326 }
02327 throw XMLStackException("ERROR: top() called on empty stack.");
02328 }
02329
02335 const _XMLStackString & xml(void) const { return m_XML; }
02336
02343 void clear(void)
02344 {
02345 freeStack();
02346 m_XML.erase();
02347 }
02348
02350 unsigned long stackSize(void) const { return m_Stack.size(); }
02351
02362 void reserveXMLBufferSize(unsigned long Capacity)
02363 {
02364 if (m_XML.capacity() < Capacity)
02365 {
02366 m_XML.reserve(Capacity);
02367 }
02368 }
02369
02371 _XMLStackDocument & operator=(const _XMLStackDocument & Instance)
02372 {
02373 m_XML = Instance.m_XML;
02374 freeStack();
02375
02376 for (int i = 0; i < Instance.m_Stack.size(); ++i)
02377 {
02378 m_Stack.push_back(Instance.m_Stack[i]->clone());
02379 m_Stack.back()->m_Doc = this;
02380 }
02381 return *this;
02382 }
02383
02384 private:
02385 typedef std::vector<_XMLStackNode *> NodeStack;
02386
02387 _XMLStackString m_XML;
02388 NodeStack m_Stack;
02389 const XMLStringConstants<_E, _Tr, _A> VALS;
02390
02391 void appendXML(const _XMLStackString & XML)
02392 {
02393 if (XML.size() + m_XML.size() > m_XML.capacity())
02394 {
02395
02396
02397
02398 m_XML.reserve(m_XML.capacity() * 2 + XML.size());
02399 }
02400 m_XML += XML;
02401 }
02402
02403 void freeStack(void)
02404 {
02405 for (int i = 0; i < m_Stack.size(); ++i)
02406 {
02407 delete m_Stack[i];
02408 }
02409 m_Stack.clear();
02410 }
02411
02412 friend class XMLStackNode<_E, _Tr, _A>;
02413 friend class XMLStackElement<_E, _Tr, _A>;
02414 friend class XMLStackAttribute<_E, _Tr, _A>;
02415 friend class XMLStackProcessingInstruction<_E, _Tr, _A>;
02416 friend class XMLStackText<_E, _Tr, _A>;
02417 friend class XMLStackCDATASection<_E, _Tr, _A>;
02418 friend class XMLStackRawXML<_E, _Tr, _A>;
02419 friend class XMLStackComment<_E, _Tr, _A>;
02420 };
02421
02422
02424 template<>
02425 struct XMLStringConstants<char, std::char_traits<char>, std::allocator<char> >
02426 {
02427 typedef std::basic_string<char, std::char_traits<char>, std::allocator<char> > _XMLStackString;
02428
02429 XMLStringConstants()
02430 : LT("<"),
02431 GT(">"),
02432 SPACE(" "),
02433 XMLNS("xmlns"),
02434 S_XMLNS_C(" xmlns:"),
02435 COLON(":"),
02436 EQUAL("="),
02437 QUOTE("\""),
02438 AMP_REF("&"),
02439 QUOTE_REF("""),
02440 LT_REF("<"),
02441 SLASH("/"),
02442 CDATA_START("<![CDATA["),
02443 CDATA_END("]]>"),
02444 COMMENT_START("<!--"),
02445 COMMENT_END("-->"),
02446 DASH2("--"),
02447 PI_START("<?"),
02448 PI_END("?>")
02449 {
02450 }
02451
02452
02453
02454 const _XMLStackString LT;
02455 const _XMLStackString GT;
02456 const _XMLStackString SPACE;
02457 const _XMLStackString XMLNS;
02458 const _XMLStackString S_XMLNS_C;
02459 const _XMLStackString COLON;
02460 const _XMLStackString EQUAL;
02461 const _XMLStackString QUOTE;
02462 const _XMLStackString AMP_REF;
02463 const _XMLStackString QUOTE_REF;
02464 const _XMLStackString LT_REF;
02465 const _XMLStackString SLASH;
02466 const _XMLStackString CDATA_START;
02467 const _XMLStackString CDATA_END;
02468 const _XMLStackString COMMENT_START;
02469 const _XMLStackString COMMENT_END;
02470 const _XMLStackString DASH2;
02471 const _XMLStackString PI_START;
02472 const _XMLStackString PI_END;
02473 };
02474
02475
02477 template<>
02478 struct XMLStringConstants<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >
02479 {
02480 typedef std::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> > _XMLStackString;
02481
02482 XMLStringConstants()
02483 : LT(L"<"),
02484 GT(L">"),
02485 SPACE(L" "),
02486 XMLNS(L"xmlns"),
02487 S_XMLNS_C(L" xmlns:"),
02488 COLON(L":"),
02489 EQUAL(L"="),
02490 QUOTE(L"\""),
02491 AMP_REF(L"&"),
02492 QUOTE_REF(L"""),
02493 LT_REF(L"<"),
02494 SLASH(L"/"),
02495 CDATA_START(L"<![CDATA["),
02496 CDATA_END(L"]]>"),
02497 COMMENT_START(L"<!--"),
02498 COMMENT_END(L"-->"),
02499 DASH2(L"--"),
02500 PI_START(L"<?"),
02501 PI_END(L"?>")
02502 {
02503 }
02504
02505
02506
02507 const _XMLStackString LT;
02508 const _XMLStackString GT;
02509 const _XMLStackString SPACE;
02510 const _XMLStackString XMLNS;
02511 const _XMLStackString S_XMLNS_C;
02512 const _XMLStackString COLON;
02513 const _XMLStackString EQUAL;
02514 const _XMLStackString QUOTE;
02515 const _XMLStackString AMP_REF;
02516 const _XMLStackString QUOTE_REF;
02517 const _XMLStackString LT_REF;
02518 const _XMLStackString SLASH;
02519 const _XMLStackString CDATA_START;
02520 const _XMLStackString CDATA_END;
02521 const _XMLStackString COMMENT_START;
02522 const _XMLStackString COMMENT_END;
02523 const _XMLStackString DASH2;
02524 const _XMLStackString PI_START;
02525 const _XMLStackString PI_END;
02526 };
02527
02528
02529 typedef XMLStackDocument<wchar_t, std::char_traits<wchar_t>,
02530 std::allocator<wchar_t> > WXMLStackDocument;
02531 typedef XMLStackDocument<char, std::char_traits<char>,
02532 std::allocator<char> > AXMLStackDocument;
02533
02534 #endif // _XMLSTACK_H