Tekkotsu Homepage
Demos
Overview
Downloads
Dev. Resources
Reference
Credits

plistBase.cc

Go to the documentation of this file.
00001 #include "plistBase.h"
00002 #include "plistPrimitives.h"
00003 #include <libxml/xmlmemory.h>
00004 #include <libxml/parser.h>
00005 
00006 //better to put this here instead of the header
00007 using namespace std; 
00008 
00009 namespace plist {
00010   
00011   ObjectBase::ObjectBase()
00012   : XMLLoadSave()
00013   {}
00014   
00015   ObjectBase::~ObjectBase() {}
00016   
00017   void ObjectBase::setParseTree(xmlDoc * doc) const {
00018     XMLLoadSave::setParseTree(doc);
00019     if(xmldocument==NULL)
00020       return;
00021     xmlNode* root=XMLLoadSave::FindRootXMLElement(doc);
00022     if(root != NULL && xmlStrcmp(root->name, (const xmlChar *)"plist")==0)
00023       return;
00024     xmlNodePtr cur = xmlNewNode(NULL,(const xmlChar*)"plist");
00025     xmlNewProp(cur,(const xmlChar*)"version",(const xmlChar*)"1.0");
00026     xmlFree(xmlDocSetRootElement(xmldocument,cur));
00027     xmlCreateIntSubset(xmldocument,(const xmlChar*)"plist",(const xmlChar*)"-//Apple//DTD PLIST 1.0//EN",(const xmlChar*)"http://www.apple.com/DTDs/PropertyList-1.0.dtd");
00028   }
00029   
00030   xmlNode* ObjectBase::FindRootXMLElement(xmlDoc* doc) const {
00031     if(doc==NULL)
00032       return NULL;
00033     xmlNode* root=XMLLoadSave::FindRootXMLElement(doc);
00034     if(root == NULL)
00035       throw bad_format(root,"Error: plist read empty document");
00036     if(xmlStrcmp(root->name, (const xmlChar *)"plist"))
00037       throw bad_format(root,"Error: plist read document of the wrong type, root node != plist");
00038     string filename;
00039     if(doc->name!=NULL && doc->name[0]!='\0') {
00040       filename="document '";
00041       filename+=doc->name;
00042       filename+="' ";
00043     }
00044     if(!xmlHasProp(root,(const xmlChar*)"version"))
00045       cerr << "Warning: plist " << filename << "does not carry version number, assuming 1.0" << endl;
00046     else {
00047       xmlChar* strv=xmlGetProp(root,(const xmlChar*)"version");
00048       double version=strtod((const char*)strv,NULL);
00049       if(version>1.0)
00050         cerr << "WARNING: plist " << filename << "is version " << strv << ", this software only knows 1.0.  Trying anyway..." << endl;
00051       if(version==0)
00052         cerr << "WARNING: plist " << filename << "seems to have invalid version '" << strv << "', this software only knows 1.0.  Trying anyway..." << endl;
00053       xmlFree(strv);
00054     }
00055     
00056     // find first element node within the plist
00057     xmlNode* cur=root->children;
00058     while(cur!=NULL && cur->type!=XML_ELEMENT_NODE)
00059       cur=cur->next;
00060     if(cur==NULL) //empty plist
00061       cur = xmlNewChild(root,NULL,(const xmlChar*)"",NULL);
00062     return cur;
00063   }
00064   
00065   bool ObjectBase::xNodeHasName(xmlNode* node, const char* name) {
00066     return xmlStrcasecmp(node->name,(const xmlChar*)name)==0;
00067   }
00068   const xmlChar* ObjectBase::xNodeGetName(xmlNode* node) {
00069     return node->name;
00070   }
00071   xmlChar* ObjectBase::xGetNodePath(xmlNode* node) {
00072     return xmlGetNodePath(node);
00073   }
00074   const xmlChar* ObjectBase::xNodeGetURL(xmlNode* node) {
00075     return node->doc->URL;
00076   }
00077   xmlNode* ObjectBase::xNodeGetChildren(xmlNode* node) {
00078     return node->children;
00079   }
00080   xmlNode* ObjectBase::xNodeGetLastChild(xmlNode* node) {
00081     return node->last;
00082   }
00083   xmlNode* ObjectBase::xNodeGetNextNode(xmlNode* node) {
00084     return node->next;
00085   }
00086   xmlNode* ObjectBase::xNodeGetPrevNode(xmlNode* node) {
00087     return node->prev;
00088   }
00089   xmlNode* ObjectBase::xNodeGetParent(xmlNode* node) {
00090     return node->parent;
00091   }
00092   xmlDoc* ObjectBase::xNodeGetDoc(xmlNode* node) {
00093     return node->doc;
00094   }
00095   bool ObjectBase::xNodeIsText(xmlNode* node) {
00096     return node->type==XML_TEXT_NODE;
00097   }
00098   bool ObjectBase::xNodeIsElement(xmlNode* node) {
00099     return node->type==XML_ELEMENT_NODE;
00100   }
00101   bool ObjectBase::xNodeIsComment(xmlNode* node) {
00102     return node->type==XML_COMMENT_NODE;
00103   }
00104     
00105 
00106   PrimitiveBase& PrimitiveBase::operator=(const Primitive<std::string>& v) { *this = static_cast<const PrimitiveBase&>(v); return *this; }
00107   PrimitiveBase& PrimitiveBase::operator=(const std::string& v) { *this=static_cast<const PrimitiveBase&>(Primitive<std::string>(v)); return *this; }
00108   PrimitiveBase& PrimitiveBase::operator=(long v) { *this=Primitive<long>(v); return *this; }
00109   PrimitiveBase& PrimitiveBase::operator=(unsigned long v) { *this=Primitive<unsigned long>(v); return *this; }
00110   PrimitiveBase& PrimitiveBase::operator=(double v) { *this=Primitive<double>(v); return *this; }
00111   
00112   PrimitiveBase::~PrimitiveBase() {
00113     delete primitiveListeners;
00114     primitiveListeners=NULL;
00115   }
00116   
00117   void PrimitiveBase::addPrimitiveListener(PrimitiveListener* vl) const {
00118     if(vl!=NULL) {
00119       if(primitiveListeners==NULL)
00120         primitiveListeners=new std::set<PrimitiveListener*>;
00121       primitiveListeners->insert(vl);
00122     }
00123   }
00124   void PrimitiveBase::removePrimitiveListener(PrimitiveListener* vl) const {
00125     if(primitiveListeners==NULL)
00126       return;
00127     std::set<PrimitiveListener*>::iterator it=primitiveListeners->find(vl);
00128     if(it!=primitiveListeners->end()) {
00129       primitiveListeners->erase(it);
00130       if(primitiveListeners->empty()) {
00131         delete primitiveListeners;
00132         primitiveListeners=NULL;
00133       }
00134     }
00135   }
00136   bool PrimitiveBase::isPrimitiveListener(PrimitiveListener* vl) const {
00137     if(vl==NULL)
00138       return false;
00139     if(primitiveListeners==NULL)
00140       return false;
00141     std::set<PrimitiveListener*>::iterator it=primitiveListeners->find(vl);
00142     return it!=primitiveListeners->end();
00143   }
00144   void PrimitiveBase::fireValueChanged(bool touchOnly) const {
00145     if(primitiveListeners==NULL)
00146       return;
00147     // copy primitive listeners so we aren't screwed if a listener is removed during processing, particularly if it's the *last* listener
00148     std::set<PrimitiveListener*> pls=*primitiveListeners;
00149     if(touchOnly) {
00150       for(std::set<PrimitiveListener*>::const_iterator it=pls.begin(); primitiveListeners!=NULL && it!=pls.end(); ++it) {
00151         // make sure current listener hasn't been removed
00152         if(primitiveListeners->count(*it)>0)
00153           (*it)->plistValueTouched(*this);
00154       }
00155     } else {
00156       for(std::set<PrimitiveListener*>::const_iterator it=pls.begin(); primitiveListeners!=NULL && it!=pls.end(); ++it) {
00157         // make sure current listener hasn't been removed
00158         if(primitiveListeners->count(*it)>0)
00159           (*it)->plistValueChanged(*this);
00160       }
00161     }
00162   }
00163     
00164 } //namespace plist
00165 
00166 
00167 /*! @file
00168  * @brief 
00169  * @author Ethan Tira-Thompson (ejt) (Creator)
00170  */

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