SimpleXML.h
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #ifndef ADCHPP_SIMPLEXML_H
00020 #define ADCHPP_SIMPLEXML_H
00021
00022 #include "Exception.h"
00023 #include "Util.h"
00024
00025 namespace adchpp {
00026
00027 STANDARD_EXCEPTION(SimpleXMLException);
00028
00033 class SimpleXML : private boost::noncopyable
00034 {
00035 public:
00036 ADCHPP_DLL SimpleXML(int numAttribs = 0);
00037 ADCHPP_DLL ~SimpleXML();
00038
00039 ADCHPP_DLL void addTag(const std::string& aName, const std::string& aData = Util::emptyString) throw(SimpleXMLException);
00040 void addTag(const std::string& aName, int aData) throw(SimpleXMLException) {
00041 addTag(aName, Util::toString(aData));
00042 }
00043 void addTag(const std::string& aName, int64_t aData) throw(SimpleXMLException) {
00044 addTag(aName, Util::toString(aData));
00045 }
00046
00047 template<typename T>
00048 void addAttrib(const std::string& aName, const T& aData) throw(SimpleXMLException) {
00049 addAttrib(aName, Util::toString(aData));
00050 }
00051
00052 ADCHPP_DLL void addAttrib(const std::string& aName, const std::string& aData) throw(SimpleXMLException);
00053
00054 template <typename T>
00055 void addChildAttrib(const std::string& aName, const T& aData) throw(SimpleXMLException) {
00056 addChildAttrib(aName, Util::toString(aData));
00057 }
00058 ADCHPP_DLL void addChildAttrib(const std::string& aName, const std::string& aData) throw(SimpleXMLException);
00059
00060 const std::string& getData() const {
00061 dcassert(current != NULL);
00062 return current->data;
00063 }
00064
00065 ADCHPP_DLL void stepIn() const throw(SimpleXMLException);
00066 ADCHPP_DLL void stepOut() const throw(SimpleXMLException);
00067
00068 void resetCurrentChild() const throw() {
00069 found = false;
00070 dcassert(current != NULL);
00071 currentChild = current->children.begin();
00072 }
00073
00074 ADCHPP_DLL bool findChild(const std::string& aName) const throw();
00075
00076 const std::string& getChildName() const {
00077 checkChildSelected();
00078 return (*currentChild)->name;
00079 }
00080
00081 const std::string& getChildData() const {
00082 checkChildSelected();
00083 return (*currentChild)->data;
00084 }
00085
00086 const std::string& getChildAttrib(const std::string& aName, const std::string& aDefault = Util::emptyString) const {
00087 checkChildSelected();
00088 return (*currentChild)->getAttrib(aName, aDefault);
00089 }
00090
00091 int getIntChildAttrib(const std::string& aName) const {
00092 checkChildSelected();
00093 return Util::toInt(getChildAttrib(aName));
00094 }
00095 int64_t getLongLongChildAttrib(const std::string& aName) const {
00096 checkChildSelected();
00097 return Util::toInt64(getChildAttrib(aName));
00098 }
00099 bool getBoolChildAttrib(const std::string& aName) const {
00100 checkChildSelected();
00101 const std::string& tmp = getChildAttrib(aName);
00102
00103 return (tmp.size() > 0) && tmp[0] == '1';
00104 }
00105
00106 ADCHPP_DLL void fromXML(const std::string& aXML) throw(SimpleXMLException);
00107 std::string toXML() { return (!root->children.empty()) ? root->children[0]->toXML(0) : Util::emptyString; }
00108
00109 ADCHPP_DLL static void escape(std::string& aString, bool aAttrib, bool aLoading = false);
00115 static bool needsEscape(const std::string& aString, bool aAttrib, bool aLoading = false) {
00116 return ((aLoading) ? aString.find('&') : aString.find_first_of(aAttrib ? "<&>'\"" : "<&>")) != std::string::npos;
00117 }
00118 private:
00119 class Tag {
00120 public:
00121 typedef Tag* Ptr;
00122 typedef std::vector<Ptr> List;
00123 typedef List::iterator Iter;
00124 typedef std::pair<std::string, std::string> StringPair;
00125 typedef std::vector<StringPair> AttribMap;
00126 typedef AttribMap::iterator AttribIter;
00127
00131 List children;
00138 AttribMap attribs;
00139
00141 std::string name;
00142
00144 std::string data;
00145
00147 Ptr parent;
00148
00149 Tag(const std::string& aName, const std::string& aData, Ptr aParent, int numAttribs = 0) : name(aName), data(aData), parent(aParent) {
00150 if(numAttribs > 0)
00151 attribs.reserve(numAttribs);
00152 }
00153
00154 const std::string& getAttrib(const std::string& aName, const std::string& aDefault = Util::emptyString) {
00155 AttribIter i = find_if(attribs.begin(), attribs.end(), CompareFirst<std::string, std::string>(aName));
00156 return (i == attribs.end()) ? aDefault : i->second;
00157 }
00158 ADCHPP_DLL std::string toXML(int indent);
00159
00160 std::string::size_type fromXML(const std::string& tmp, std::string::size_type start, int aa, bool isRoot = false) throw(SimpleXMLException);
00161 std::string::size_type loadAttribs(const std::string& tmp, std::string::size_type start) throw(SimpleXMLException);
00162
00163 void appendAttribString(std::string& tmp);
00165 ~Tag() {
00166 for(Iter i = children.begin(); i != children.end(); ++i) {
00167 delete *i;
00168 }
00169 }
00170 };
00171
00173 Tag::Ptr root;
00174
00176 mutable Tag::Ptr current;
00177
00178 mutable Tag::Iter currentChild;
00179
00180 void checkChildSelected() const throw() {
00181 dcassert(current != NULL);
00182 dcassert(currentChild != current->children.end());
00183 }
00184
00185 int attribs;
00186 mutable bool found;
00187 };
00188
00189 }
00190
00191 #endif // SIMPLEXML_H