Tekkotsu Homepage
Demos
Overview
Downloads
Dev. Resources
Reference
Credits

plistPrimitives.cc

Go to the documentation of this file.
00001 #include "plistPrimitives.h"
00002 
00003 namespace plist {
00004   template class Primitive<short>;
00005   template class Primitive<unsigned short>;
00006   template class Primitive<int>;
00007   template class Primitive<unsigned int>;
00008   template class Primitive<long>;
00009   template class Primitive<unsigned long>;
00010   template class Primitive<float>;
00011   template class Primitive<double>;
00012   
00013   void Primitive<bool>::loadXML(xmlNode* node) {
00014     if(node==NULL)
00015       return;
00016     if(xNodeHasName(node,"true")) {
00017       prevVal=val; 
00018       val=true;
00019       fireValueChanged((prevVal && val) || (!prevVal && !val)); 
00020     } else if(xNodeHasName(node,"false")) {
00021       prevVal=val; 
00022       val=false;
00023       fireValueChanged((prevVal && val) || (!prevVal && !val)); 
00024     } else if(xNodeHasName(node,"integer") || xNodeHasName(node,"real")) {
00025       prevVal=val; 
00026       xmlChar * cont=xmlNodeGetContent(node);
00027       std::stringstream str((char*)cont);
00028       str >> val;
00029       xmlFree(cont);
00030       fireValueChanged((prevVal && val) || (!prevVal && !val));
00031     } else if(xNodeHasName(node,"string")) {
00032       xmlChar * cont=xmlNodeGetContent(node);
00033       try {
00034         set((char*)cont);
00035         std::cerr << "Warning: plist boolean expects value of '<true/>', '<false/>', or numeric.  String value of '" << (char*)cont << "' is not recommended." << std::endl;
00036       } catch(const bad_format& err) {
00037         xmlFree(cont);
00038         throw bad_format(node,err.what());
00039       } catch(...) {
00040         xmlFree(cont);
00041         throw;
00042       }
00043       xmlFree(cont);
00044     } else
00045       throw bad_format(node,"Error: plist boolean must be 'true', 'false', or numeric type");
00046   }
00047   void Primitive<bool>::saveXML(xmlNode* node) const {
00048     if(node==NULL)
00049       return;
00050     xmlNodeSetName(node,(const xmlChar*)(val?"true":"false"));
00051     xmlNodeSetContent(node,NULL);
00052   }
00053   void Primitive<bool>::set(const std::string& str) {
00054     prevVal=val;
00055     if(matchTrue(str))
00056       val=true;
00057     else if(matchFalse(str))
00058       val=false;
00059     else {
00060       float t;
00061       if(sscanf(str.c_str(),"%g",&t)==0)
00062         throw bad_format(NULL,"Error: plist boolean must be 'true', 'false', or numeric type");
00063       val=t;
00064     }
00065     fireValueChanged((prevVal && val) || (!prevVal && !val));
00066   }
00067   //! implements the clone function for Primitive<bool>
00068   PLIST_CLONE_IMP(Primitive<bool>,new Primitive<bool>(val));
00069 
00070   
00071   void Primitive<char>::loadXML(xmlNode* node) {
00072     if(node==NULL)
00073       return;
00074     xmlChar* cont=xmlNodeGetContent(node);
00075     try {
00076       if(xNodeHasName(node,"string")) {
00077         set((char*)cont);
00078       } else if(xNodeHasName(node,"integer")) {
00079         prevVal=val;
00080         val=strtol((const char*)cont,NULL,0);
00081         fireValueChanged(prevVal==val); 
00082       } else if(xNodeHasName(node,"real")) {
00083         prevVal=val;
00084         val=(char)strtod((const char*)cont,NULL);
00085         fireValueChanged(prevVal==val); 
00086       } else if(xNodeHasName(node,"true")) {
00087         prevVal=val;
00088         val=true;
00089         fireValueChanged(prevVal==val); 
00090       } else if(xNodeHasName(node,"false")) {
00091         prevVal=val;
00092         val=false;
00093         fireValueChanged(prevVal==val); 
00094       } else {
00095         throw bad_format(node,"Error: plist char must be either a string or integer");
00096       } 
00097     } catch(const bad_format& err) {
00098       xmlFree(cont);
00099       throw bad_format(node,err.what());
00100     } catch(...) {
00101       xmlFree(cont);
00102       throw;
00103     }
00104     xmlFree(cont);
00105   }
00106   void Primitive<char>::saveXML(xmlNode* node) const {
00107     if(node==NULL)
00108       return;
00109     if(numeric) {
00110       xmlNodeSetName(node,(const xmlChar*)"integer");
00111       std::stringstream str;
00112       str << (int)val;
00113       xmlNodeSetContent(node,(const xmlChar*)str.str().c_str());
00114     } else {
00115       xmlNodeSetName(node,(const xmlChar*)"string");
00116       char str[2] = {val,'\0'};
00117       xmlNodeSetContent(node,(const xmlChar*)str);
00118     }
00119   }
00120   void Primitive<char>::set(const std::string& str) {
00121     prevVal=val;
00122     if(str.size()==0)
00123       throw bad_format(NULL,"Error: plist char must have non-empty content");
00124     val=str[0];
00125     if(str.size()>1) {
00126       std::cerr << "Warning: plist expected single char, found multi-char string '" << str << "'";
00127       if(matchTrue(str))
00128         val=true;
00129       else if(matchFalse(str))
00130         val=false;
00131       else {
00132         std::cerr << " (using first character '" << val << "')" << std::endl;
00133         return;
00134       }
00135       std::cerr << " (interpreted as boolean " << (bool)val << ")" << std::endl;
00136     }
00137     fireValueChanged(prevVal==val);
00138   }
00139   //! implements the clone function for Primitive<char>
00140   PLIST_CLONE_IMP(Primitive<char>,new Primitive<char>(val));
00141   
00142   
00143   void Primitive<unsigned char>::loadXML(xmlNode* node) {
00144     if(node==NULL)
00145       return;
00146     xmlChar* cont=xmlNodeGetContent(node);
00147     try {
00148       if(xNodeHasName(node,"string")) {
00149         set((char*)cont);
00150       } else if(xNodeHasName(node,"integer")) {
00151         prevVal=val;
00152         val=strtol((const char*)cont,NULL,0);
00153         fireValueChanged(prevVal==val); 
00154       } else if(xNodeHasName(node,"real")) {
00155         prevVal=val;
00156         val=(char)strtod((const char*)cont,NULL);
00157         fireValueChanged(prevVal==val); 
00158       } else if(xNodeHasName(node,"true")) {
00159         prevVal=val;
00160         val=true;
00161         fireValueChanged(prevVal==val); 
00162       } else if(xNodeHasName(node,"false")) {
00163         prevVal=val;
00164         val=false;
00165         fireValueChanged(prevVal==val); 
00166       } else {
00167         throw bad_format(node,"Error: plist unsigned char must be either a string or integer");
00168       } 
00169     } catch(const bad_format& err) {
00170       xmlFree(cont);
00171       throw bad_format(node,err.what());
00172     } catch(...) {
00173       xmlFree(cont);
00174       throw;
00175     }
00176     xmlFree(cont);
00177   }
00178   void Primitive<unsigned char>::saveXML(xmlNode* node) const {
00179     if(node==NULL)
00180       return;
00181     if(numeric) {
00182       xmlNodeSetName(node,(const xmlChar*)"integer");
00183       std::stringstream str;
00184       str << (int)val;
00185       xmlNodeSetContent(node,(const xmlChar*)str.str().c_str());
00186     } else {
00187       xmlNodeSetName(node,(const xmlChar*)"string");
00188       xmlChar str[2] = {val,'\0'};
00189       xmlNodeSetContent(node,(const xmlChar*)str);
00190     }
00191   }
00192   void Primitive<unsigned char>::set(const std::string& str) {
00193     prevVal=val;
00194     if(str.size()==0)
00195       throw bad_format(NULL,"Error: plist char must have non-empty content");
00196     val=str[0];
00197     if(str.size()>1) {
00198       std::cerr << "Warning: plist expected single char, found multi-char string '" << str << "'";
00199       if(matchTrue(str))
00200         val=true;
00201       else if(matchFalse(str))
00202         val=false;
00203       else {
00204         std::cerr << " (using first character '" << val << "')" << std::endl;
00205         return;
00206       }
00207       std::cerr << " (interpreted as boolean " << (bool)val << ")" << std::endl;
00208     }
00209     fireValueChanged(prevVal==val); 
00210   }
00211   //! implements the clone function for Primitive<unsigned char>
00212   PLIST_CLONE_IMP(Primitive<unsigned char>,new Primitive<unsigned char>(val));
00213   
00214   
00215   void Primitive<std::string>::loadXML(xmlNode* node) {
00216     // operator= will call fireValueChanged, so no direct calls to fire here...
00217     if(node==NULL)
00218       return;
00219     if(xNodeHasName(node,"string")) {
00220       xmlChar * cont=xmlNodeGetContent(node);
00221       *this=(char*)cont;
00222       xmlFree(cont);
00223     } else {
00224       if(xNodeHasName(node,"integer") || xNodeHasName(node,"real")) {
00225         xmlChar * cont=xmlNodeGetContent(node);
00226         *this=(char*)cont;
00227         xmlFree(cont);
00228       } else if(xNodeHasName(node,"true"))
00229         *this="true";
00230       else if(xNodeHasName(node,"false"))
00231         *this="false";
00232       else
00233         throw bad_format(node,"Error: plist string must be 'true', 'false', or numeric type");
00234       std::cerr << "Warning: plist string expected, found " << (const char*)xNodeGetName(node) << " on line " << xmlGetLineNo(node) << std::endl;
00235     }
00236   }
00237   void Primitive<std::string>::saveXML(xmlNode* node) const {
00238     if(node==NULL)
00239       return;
00240     xmlNodeSetName(node,(const xmlChar*)"string");
00241     xmlNodeSetContent(node,(const xmlChar*)c_str());
00242   }
00243   bool Primitive<std::string>::toBool() const { if(matchTrue(*this)) return true; else if(matchFalse(*this)) return false; else return toLong(); }
00244   char Primitive<std::string>::toChar() const { return std::isdigit((*this)[0]) ? toLong() : (*this)[0]; }
00245   long Primitive<std::string>::toLong() const { std::stringstream s(*this); long v; s >> v; return v; }
00246   double Primitive<std::string>::toDouble() const { std::stringstream s(*this); double v; s >> v; return v; }
00247   //! implements the clone function for Primitive<std::string>
00248   PLIST_CLONE_IMP(Primitive<std::string>,new Primitive<std::string>(get()));
00249   
00250 
00251   std::string NamedEnumerationBase::getDescription(bool preferredOnly/*=true*/) {
00252     if(preferredOnly) {
00253       std::map<int,std::string> valsToNames;
00254       getPreferredNames(valsToNames);
00255       if(valsToNames.size()==0) return "";
00256       std::string ans="Value is one of: { ";
00257       std::map<int,std::string>::const_iterator it=valsToNames.begin();
00258       ans+=it->second;
00259       for(++it; it!=valsToNames.end(); ++it) {
00260         ans+=" | ";
00261         ans+=it->second;
00262       }
00263       if(!strictValue)
00264         ans+=" | <integer_value>";
00265       ans+=" } ";
00266       return ans;
00267     } else {
00268       std::map<std::string,int> namesToVals;
00269       getAllNames(namesToVals);
00270       if(namesToVals.size()==0) return "";
00271       std::string ans="Value is one of: { ";
00272       std::map<std::string,int>::const_iterator it=namesToVals.begin();
00273       ans+=it->first;
00274       for(++it; it!=namesToVals.end(); ++it) {
00275         ans+=" | ";
00276         ans+=it->first;
00277       }
00278       if(!strictValue)
00279         ans+=" | <integer_value>";
00280       ans+=" } ";
00281       return ans;
00282     }
00283   }
00284 } //namespace plist
00285 
00286 /*! @file
00287 * @brief 
00288 * @author Ethan Tira-Thompson (ejt) (Creator)
00289 */
00290 

Tekkotsu v5.1CVS
Generated Mon May 9 04:58:48 2016 by Doxygen 1.6.3