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
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
00057 xmlNode* cur=root->children;
00058 while(cur!=NULL && cur->type!=XML_ELEMENT_NODE)
00059 cur=cur->next;
00060 if(cur==NULL)
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
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
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
00158 if(primitiveListeners->count(*it)>0)
00159 (*it)->plistValueChanged(*this);
00160 }
00161 }
00162 }
00163
00164 }
00165
00166
00167
00168
00169
00170