xmlnode.cpp

00001 // --*-c++-*-- 00002 /* 00003 $Id: xmlnode_8cpp-source.html,v 1.1 2004/10/05 21:12:03 mentat Exp $ 00004 00005 GNU Messenger - The secure instant messenger 00006 Copyright (C) 2001-2002 Henrik Abelsson <henrik@abelsson.com> 00007 00008 This program is free software; you can redistribute it and/or modify 00009 it under the terms of the GNU General Public License as published by 00010 the Free Software Foundati 00011 on; either version 2 of the License, or 00012 (at your option) any later version. 00013 00014 This program is distributed in the hope that it will be useful, 00015 but WITHOUT ANY WARRANTY; without even the implied warranty of 00016 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00017 GNU General Public License for more details. 00018 00019 You should have received a copy of the GNU General Public License 00020 along with this program; if not, write to the Free Software 00021 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00022 00023 */ 00024 00025 #include <map> 00026 #include <string> 00027 #include <sstream> 00028 00029 #include "gm/exception.h" 00030 #include "gm/xmlnode.h" 00031 #include "gm/contact.h" 00032 #include "gm/xml.h" 00033 00034 namespace GNUMessenger { 00035 00036 #if 0 00037 #ifdef _UNICODE 00038 #undef string 00039 #define string basic_string<wchar_t> 00040 #endif 00041 #endif 00042 00043 using namespace std; 00044 00045 XMLNode::XMLNode() 00046 { 00047 m_xmlData=new XMLNodeData(); 00048 m_xmlData->data_is_cdata=false; 00049 m_xmlData->oneline=false; 00050 } 00051 00052 XMLNode::XMLNode(const XMLNode &other) 00053 { 00054 other.m_xmlData->ref(); 00055 m_xmlData=other.m_xmlData; 00056 } 00057 00058 XMLNode::XMLNode(const Contact &other) 00059 { 00060 other.m_xmlData->ref(); 00061 m_xmlData=other.m_xmlData; 00062 } 00063 00064 XMLNode::~XMLNode() 00065 { 00066 00067 if ((m_xmlData) && m_xmlData->deref()) 00068 { 00069 delete m_xmlData; 00070 m_xmlData=0; 00071 } 00072 00073 } 00074 00075 bool XMLNode::hasChild(const string &name, int n) const 00076 { 00077 00078 vector<XMLNode>::const_iterator it; 00079 00080 for(it=m_xmlData->m_children.begin(); it!=m_xmlData->m_children.end(); it++) 00081 { 00082 if (it->m_xmlData->m_name == name) 00083 n--; 00084 if (n == 0) 00085 return true; 00086 } 00087 00088 return false; 00089 } 00090 #if 0 00091 void XMLNode::destroy() throw(NodeDestroyed) 00092 { 00093 00094 if (!m_xmlData) { 00095 LOG_THROW("This node has been destroyed and cannot be destroyed again.", NodeDestroyed); 00096 } 00097 else 00098 { 00099 // TODO: gain mutex! Also may need to 'try' so do not throw something weird 00100 while (!m_xmlData->deref()) 00101 {} 00102 00103 delete m_xmlData; 00107 m_xmlData = 0; 00108 00109 } 00110 } 00111 #endif 00112 00113 unsigned int XMLNode::numChildren(const string &name) const 00114 { 00115 00116 vector<XMLNode>::const_iterator it; 00117 unsigned int n=0; 00118 00119 for(it = m_xmlData->m_children.begin(); it!=m_xmlData->m_children.end(); it++) 00120 { 00121 if (it->m_xmlData->m_name == name) 00122 n++; 00123 } 00124 return n; 00125 } 00126 00127 const string XMLNode::property(const string &name) const 00128 { 00129 map<string,string>::const_iterator it=m_xmlData->m_properties.find(name); 00130 00131 00132 if (it==m_xmlData->m_properties.end()) 00133 return ""; 00134 else 00135 return it->second; 00136 } 00137 00138 int XMLNode::intProperty(const string &name) const 00139 { 00140 map<string,string>::const_iterator it=m_xmlData->m_properties.find(name); 00141 00142 00143 if (it==m_xmlData->m_properties.end()) 00144 return 0; 00145 else 00146 return atoi(it->second.c_str()); 00147 } 00148 00149 00150 XMLNode& XMLNode::child(const string &name, int n) 00151 { 00152 vector<XMLNode>::iterator it; 00153 00154 for(it=m_xmlData->m_children.begin(); it!=m_xmlData->m_children.end(); it++) 00155 { 00156 if (it->m_xmlData->m_name == name) 00157 n--; 00158 if (n == 0) { 00159 // LOG_DEBUG("Found child"); 00160 return *it; 00161 } 00162 } 00163 00164 LOG_DEBUG("Adding new child, child not found."); 00165 00166 XMLNode newNode; 00167 00168 newNode.setName(name); 00169 00170 return *(m_xmlData->m_children.insert(m_xmlData->m_children.end(), newNode)); 00171 00172 } 00173 00174 00175 XMLNode XMLNode::child(const string& name, int n) const 00176 { 00177 vector<XMLNode>::const_iterator it; 00178 00179 for(it=m_xmlData->m_children.begin(); it!=m_xmlData->m_children.end(); it++) 00180 { 00181 if (it->m_xmlData->m_name == name) 00182 n--; 00183 if (n == 0) 00184 return *it; 00185 } 00186 LOG_THROW(string("Child: ") + name + string(" could not be found in: ") + this->name(), InvalidChild); 00187 00188 return XMLNode(); 00189 } 00190 00191 XMLNode& XMLNode::setProperty(const string &name, const string &value) 00192 { 00193 m_xmlData->m_properties[name] = value; 00194 00195 return *this; 00196 } 00197 00198 XMLNode& XMLNode::setProperty(const string &name, int value) 00199 { 00200 00201 stringstream foo; 00202 foo << value; 00203 return setProperty(name, foo.str()); 00204 } 00205 00206 XMLNode& XMLNode::addChild(const string &name, const string &data) 00207 { 00208 00209 XMLNode tmp; 00210 tmp.m_xmlData->m_name = name; 00211 tmp.m_xmlData->m_data = data; 00212 00213 return *m_xmlData->m_children.insert(m_xmlData->m_children.end(), tmp); 00214 } 00215 00216 XMLNode& XMLNode::delChild(const string &name, int n) 00217 { 00218 00219 vector<XMLNode>::iterator it; 00220 00221 for(it=m_xmlData->m_children.begin(); it!=m_xmlData->m_children.end(); it++) 00222 { 00223 if (it->m_xmlData->m_name == name) 00224 n--; 00225 00226 if (n == 0) 00227 { 00228 m_xmlData->m_children.erase(it); 00229 return *this; 00230 } 00231 } 00232 00233 LOG_THROW("delChild: InvalidChild", InvalidChild); 00234 00235 return *this; //To get rid of warning 00236 } 00237 00238 XMLNode& XMLNode::moveChild(unsigned int index, unsigned int newIndex) 00239 { 00240 00241 if ( (index >= m_xmlData->m_children.size()) || (newIndex > m_xmlData->m_children.size()) ) 00242 LOG_THROW("Array out of bounds", ArrayOutOfBounds); 00243 00244 // account for idiots moving to same place 00245 if (index == newIndex) 00246 return m_xmlData->m_children[index]; 00247 00248 00249 vector<XMLNode>::iterator it = m_xmlData->m_children.begin(); 00250 00251 // account for index before newIndex 00252 if (index < newIndex) 00253 newIndex--; 00254 00255 while(index-- != 0) 00256 it++; 00257 00258 XMLNode tmp(*it); 00259 00260 m_xmlData->m_children.erase(it); 00261 00262 it = m_xmlData->m_children.begin(); 00263 00264 while (newIndex-- != 0) 00265 it++; 00266 00267 return *(m_xmlData->m_children.insert(it, tmp)); 00268 } 00269 00270 XMLNode::operator string() const 00271 { 00272 string str; 00273 00274 XMLParser::printTag(*this,str); 00275 00276 return str; 00277 } 00278 00279 00280 string& XMLNode::operator[](const string &name) 00281 { 00282 00283 return m_xmlData->m_properties[name]; 00284 00285 } 00286 00287 string XMLNode::operator[](const string &name) const 00288 { 00289 00290 map<string,string>::const_iterator it=m_xmlData->m_properties.find(name); 00291 00292 if (it==m_xmlData->m_properties.end()) 00293 return ""; 00294 else 00295 return it->second; 00296 00297 LOG_THROW("The specified child does not exist.", InvalidChild); 00298 } 00299 00300 ostream &operator<<(ostream &o, XMLNode &n) 00301 { 00302 00303 string str; 00304 00305 XMLParser::printTag(n,str); 00306 o << str; 00307 00308 return o; 00309 } 00310 00311 XMLNode &XMLNode::operator<<(const string &str) throw (ParseFailure) 00312 { 00313 00314 try 00315 { 00316 XMLParser p(str); 00317 *this = p.get_root(); 00318 } 00319 catch(XMLParser::ParseFailure &e) 00320 { 00321 LOG_THROW(e.what(), ParseFailure); 00322 } 00323 catch(...) 00324 { 00325 LOG_THROW("Unexpected exception from parse failure.", ParseFailure); 00326 } 00327 00328 return *this; 00329 } 00330 00331 XMLNode &XMLNode::operator=(const XMLNode &other) 00332 { 00333 if (!other.m_xmlData) 00334 return *this; 00335 00336 if (other.m_xmlData == m_xmlData) 00337 return *this; 00338 00339 00342 if (other.m_xmlData) 00343 other.m_xmlData->ref(); 00344 00345 00346 if (m_xmlData && m_xmlData->deref()) 00347 { 00348 delete m_xmlData; 00349 m_xmlData=0; 00350 } 00351 00352 00353 00354 m_xmlData=other.m_xmlData; 00355 return *this; 00356 } 00357 00358 00359 } // !GNUMessenger

Generated on Tue Oct 5 14:41:47 2004 for GNU Messenger by doxygen 1.3.8