Node.cpp

См. документацию.
00001 /*
00002  * Node.cpp
00003  *
00004  *  Created on: 08.04.2011
00005  *      Author: nick
00006  */
00007 
00008 #include "Node.h"
00009 #include <iostream>
00010 //Маразматическая замена подстроки в строке, блин...
00011 void replace(std::string& text, std::string s, std::string d){
00012   for (int index=text.find(s, 0); index!=-1; index=text.find(s, index) ) {
00013     text.replace(index, s.length(), d);
00014     index+=d.length();
00015   }
00016 }
00017 
00018 string XMLescape(string txt){
00019         replace(txt,"&","&amp;");
00020         replace(txt,">", "&gt;");
00021         replace(txt,"\"", "&quot;");
00022         replace(txt,"\x0C", "");
00023         replace(txt,"\x1B", "");
00024         return txt;
00025 }
00026 
00027 Node::Node(string name,  Node* parent,string xmlns) {
00028         pthread_mutex_init(&add_remove_mutex,NULL);
00029         //isDuplicate=false;
00030         this->name=name;
00031         this->parent=parent;
00032         if(xmlns!=""){
00033                 //attrs["xmlns"]=xmlns;
00034                 setAttribute("xmlns",xmlns);
00035         }
00036         if (parent){
00037                 parent->addChild(this);
00038         }
00039 }
00040 
00041 Node::Node(string name, map <string, string> /*&*/attrs,  Node* parent=NULL) {
00042         pthread_mutex_init(&add_remove_mutex,NULL);
00043         // TODO Auto-generated constructor stub
00044         //isDuplicate=false;
00045         this->name=name;
00046         this->parent=parent;
00047         this->attrs=attrs;
00048         if (parent){
00049                 parent->addChild(this);
00050         }
00051 }
00052 
00053 void Node::deleteByXMLNS(string xmlns){
00054         Node* n=this->getKind(xmlns);
00055         if (n!=NULL){
00056                 cout<<"DELETE NOT UNIQUE NAMESPACE!!!!:"<<xmlns<<endl;
00057                 delete n;
00058         }
00059 }
00060 
00061 void Node::addChild(Node* child){
00062         map <string, string>::iterator ii=child->attrs.find("xmlns");
00063         if (ii!=child->attrs.end()){
00064                 deleteByXMLNS(ii->second);
00065         }
00066         child->parent=this;
00067        pthread_mutex_lock(&add_remove_mutex);
00068         kinds.push_back(child);
00069        pthread_mutex_unlock(&add_remove_mutex);
00070 }
00071 
00072 void Node::setNamespace(string xmlns){
00073         setAttribute("xmlns",xmlns);
00074         //attrs["xmlns"]=xmlns;
00075 }
00076 
00077 string Node::toXMLStringStart(){
00078         string res="";
00079         res+="<"+XMLescape(name);
00080         map <string, string> ::iterator it=attrs.begin();
00081         while (it!=attrs.end()){
00082                 res+=" "+XMLescape((*it).first)+"=\""+XMLescape((*it).second)+"\"";
00083                 it++;
00084         }
00085         res+=">\n";
00086         return res;
00087 }
00088 
00089 string Node::toXMLStringEnd(){
00090         return "</"+name+">\n";
00091 }
00092 
00093 string Node::toXMLString(){
00094         string res="";
00095         #ifdef debug_output
00096         cout<<"-1-"<<endl;
00097         #endif
00098         res+="<"+XMLescape(name);
00099         #ifdef debug_output
00100         cout<<"-2-"<<endl;
00101         #endif
00102         map <string, string> ::iterator it=attrs.begin();
00103         #ifdef debug_output
00104         cout<<"-3-"<<endl;
00105         #endif
00106         while (it!=attrs.end()){
00107             #ifdef debug_output
00108                 cout<<"-4-"<<endl;
00109             #endif
00110                 res+=" "+XMLescape((*it).first)+"=\""+XMLescape((*it).second)+"\"";
00111                 it++;
00112         }
00113         #ifdef debug_output
00114         cout<<"-5-"<<endl;
00115         #endif
00116         pthread_mutex_lock(&add_remove_mutex);
00117         if ((kinds.begin()==kinds.end())&&(xmlBody.length()==0)){
00118                 res+="/>\n";
00119         }else{
00120                 res+=">";
00121                 if (kinds.begin()==kinds.end()){
00122                         res+=XMLescape(xmlBody);
00123                 }else{
00124                         res+="\n";
00125                         list<Node*>::iterator p=kinds.begin();
00126                         while (p!=kinds.end()){
00127                                 res+=(*p)->toXMLString();
00128                                 p++;
00129                         }
00130                 }
00131                 res+="</"+name+">\n";
00132         }
00133         pthread_mutex_unlock(&add_remove_mutex);
00134         #ifdef debug_output
00135         cout<<"-6OK-"<<endl;
00136         #endif
00137         return res;
00138 }
00139 
00140 
00141 void Node::copyKinds(const Node &basedNode){
00142         #ifdef debug_output
00143         cout<<"copy KINDS NODE!"<<endl;
00144         cout<<"============= copy: ============= :"<<basedNode.name<<endl;
00145         #endif
00146         //isDuplicate=true;
00147         this->name=basedNode.name;      
00148         //this->kinds=basedNode->kinds;//
00149         //Первая нода должна ссылаться на тот парент от которого была создана дублируемая
00150         this->parent=basedNode.parent;
00151         this->attrs=basedNode.attrs;
00152         this->xmlBody=basedNode.xmlBody;
00153         pthread_mutex_lock(&add_remove_mutex);
00154         list<Node*>::const_iterator it=basedNode.kinds.begin();
00155         while (it!=basedNode.kinds.end()){
00156                 Node* n=new Node(*(*it));
00157                 //А ноды дети должны ссылаться на себя, и здесь мы ссылку перепишим
00158                 n->parent=this;
00159                 #ifdef debug_output
00160                 cout<<"============= addKinds: ============= :"<<n->name<<endl;
00161                 #endif
00162                 this->kinds.push_back(n);
00163                 #ifdef debug_output
00164                 cout<<"ka "<<n->name<<endl;
00165                 #endif
00166                 ++it;
00167         }
00168         pthread_mutex_unlock(&add_remove_mutex);
00169         #ifdef debug_output
00170         cout<<"============= copyed: ============= :"<<basedNode.name<<endl;
00171         #endif
00172 }
00173 //Мда, но в киндсах останется тот класс который и был, раньше, а не станза, в нод...
00174 Node::Node(const Node &basedNode){
00175         pthread_mutex_init(&add_remove_mutex,NULL);
00176         copyKinds(basedNode);
00177 }
00178 
00179 Node* Node::getKind(string xmlns){
00180         Node* res=NULL;
00181         pthread_mutex_lock(&add_remove_mutex);
00182         list<Node*>::iterator it=kinds.begin();
00183         while (it!=kinds.end()){
00184                 if ((*it)->getNamesapace()==xmlns){
00185                         res= *it;
00186                 }
00187                 ++it;
00188         }
00189         pthread_mutex_unlock(&add_remove_mutex);
00190         return res;
00191 }
00192 
00193 _Kinds_iterator Node::kindsNameBegin(string name){
00194         _Kinds_iterator ki;
00195         ki.beginitem=kinds.begin();
00196         ki.enditem=kinds.end();
00197         ki.curitem=kinds.begin();
00198         ki.name=name;
00199         if ((*ki.curitem)->name!=name){
00200                 ++ki;
00201         }
00202         return ki;
00203 }
00204 
00205 _Kinds_iterator Node::kindsNameEnd(string name){
00206         _Kinds_iterator ki;
00207         ki.beginitem=kinds.begin();
00208         ki.enditem=kinds.end();
00209         ki.curitem=kinds.end();
00210         ki.name=name;
00211         return ki;
00212 }
00213 
00214 void Node::destroyKinds(){
00215         // TODO Auto-generated destructor stub
00216         //list<Node*>::iterator p=kinds.begin();
00217         /*while ((p!=kinds.end())&&(!isDuplicate)){
00218                 delete (*p);
00219                 p++;
00220         }*/
00221         #ifdef debug_output
00222         cout<<"-Node1-"<<endl;
00223         //cout<<"XML "<<this->toXMLString();
00224         cout<<name<<endl;        
00225         cout<<"-Node2-"<<endl;
00226         #endif
00227         while /*(*/(kinds.begin()!=kinds.end())/*&&(!isDuplicate))*/{
00228                 delete (*kinds.begin());
00229                 //Node* nd=kinds.pop_back();
00230                 //delete nd;
00231                         //p++;
00232         }
00233         #ifdef debug_output
00234         cout<<"-Node3-"<<endl;
00235         #endif
00236         if(parent!=NULL){
00237             #ifdef debug_output
00238                 cout<<"pre remove kind"<<endl;
00239             #endif
00240                 this->parent->removeKind(this);
00241             #ifdef debug_output
00242                 cout<<"post remove kind"<<endl;
00243             #endif
00244         }
00245         #ifdef debug_output
00246         cout<<"=============destroyed ===========: "<<name<<endl;
00247         #endif
00248 /*      if((!isDuplicate)&&(parent!=NULL)){
00249                 cout<<"delete parent:"<<parent->name<<" "<<this->name<<endl;
00250                 this->parent->removeKind(this);
00251         }*/
00252         //kinds.clear();
00253 }
00254 
00255 Node &Node::operator=(Node &obj){
00256     #ifdef debug_output
00257         cout<<"operator = Node"<<endl;
00258     #endif
00259         destroyKinds();
00260         copyKinds(obj);
00261         return *this;
00262 }
00263 
00264 void Node::setXMLBody(long body){
00265         stringstream res;
00266         res<<body;
00267         xmlBody=res.str();
00268 }
00269 
00270 long Node::getXMLBodyInt(){
00271         istringstream res(xmlBody);
00272         long r=0;
00273         res>>r;
00274         return r;
00275 }
00276 
00277 long Node::getAttributeInt(string name){
00278         istringstream res(attrs[name]);
00279         long r=0;
00280         res>>r;
00281         return r;
00282 }
00283 
00284 bool Node::parentContainSelf(){
00285         pthread_mutex_lock(&(this->parent->add_remove_mutex));
00286         bool b=(this->parent!=NULL)&&(find(this->parent->kinds.begin(),
00287                 this->parent->kinds.end(),this)!=this->parent->kinds.end());
00288         pthread_mutex_unlock(&(this->parent->add_remove_mutex));
00289         return b;
00290 }
00291 
00292 void Node::setAttribute(string name, string value){
00293         if (name=="xmlns"){
00294                 //Бывает ситуация когда родитель не сорежит потомка в своих детях,
00295                 //когда это копия, от потомка верхнего уровня, тогда смысла заменять себя
00296                 //в нем нету
00297                 if(parentContainSelf()){
00298                         this->parent->deleteByXMLNS(value);
00299                 }
00300         }
00301         attrs[name]=value;
00302 }
00303 
00304 void Node::setAttribute(string name, long value){
00305         stringstream res;
00306         res<<value;
00307         setAttribute(name,res.str());
00308 }
00309 
00310 Node::~Node() {
00311         destroyKinds();
00312         pthread_mutex_destroy(&add_remove_mutex);
00313 }
00314 void Node::removeKind(Node* node){
00315     pthread_mutex_lock(&add_remove_mutex);
00316     kinds.remove(node); /*delete node;*/
00317     pthread_mutex_unlock(&add_remove_mutex);
00318 }