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

Tekkotsu v4.0
Generated Thu Nov 22 00:54:55 2007 by Doxygen 1.5.4