См. документацию.00001
00002
00003
00004
00005
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,"&","&");
00020 replace(txt,">", ">");
00021 replace(txt,"\"", """);
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
00030 this->name=name;
00031 this->parent=parent;
00032 if(xmlns!=""){
00033
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
00044
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
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
00147 this->name=basedNode.name;
00148
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
00216
00217
00218
00219
00220
00221 #ifdef debug_output
00222 cout<<"-Node1-"<<endl;
00223
00224 cout<<name<<endl;
00225 cout<<"-Node2-"<<endl;
00226 #endif
00227 while (kinds.begin()!=kinds.end()){
00228 delete (*kinds.begin());
00229
00230
00231
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
00249
00250
00251
00252
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);
00317 pthread_mutex_unlock(&add_remove_mutex);
00318 }