csutil/documenthelper.h
Go to the documentation of this file.00001 /* 00002 Copyright (C) 2005,2007 by Marten Svanfeldt 00003 00004 This library is free software; you can redistribute it and/or 00005 modify it under the terms of the GNU Library General Public 00006 License as published by the Free Software Foundation; either 00007 version 2 of the License, or (at your option) any later version. 00008 00009 This library is distributed in the hope that it will be useful, 00010 but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00012 Library General Public License for more details. 00013 00014 You should have received a copy of the GNU Library General Public 00015 License along with this library; if not, write to the Free 00016 Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 00017 */ 00018 00019 #ifndef __CSUTIL_DOCUMENTHELPER_H__ 00020 #define __CSUTIL_DOCUMENTHELPER_H__ 00021 00027 #include "csutil/csstring.h" 00028 #include "csutil/refarr.h" 00029 #include "csutil/regexp.h" 00030 #include "csutil/scf_implementation.h" 00031 #include "csutil/util.h" 00032 00033 #include "iutil/document.h" 00034 00035 namespace CS 00036 { 00037 namespace DocSystem 00038 { 00039 namespace Implementation 00040 { 00045 template<class T> 00046 class FilterDocumentNodeIterator : public 00047 scfImplementation1 <FilterDocumentNodeIterator<T>, 00048 iDocumentNodeIterator> 00049 { 00050 public: 00051 FilterDocumentNodeIterator (csRef<iDocumentNodeIterator> parent, 00052 T filter) : scfImplementation1<FilterDocumentNodeIterator<T>, 00053 iDocumentNodeIterator> (this), parent (parent), filter (filter) 00054 { 00055 ForwardIterator (); 00056 } 00057 00058 // -- iDocumentNodeIterator 00060 virtual bool HasNext () 00061 { 00062 return nextElement.IsValid (); 00063 } 00064 00066 virtual csRef<iDocumentNode> Next () 00067 { 00068 csRef<iDocumentNode> current = nextElement; 00069 ForwardIterator (); 00070 return current; 00071 } 00072 00073 virtual size_t GetNextPosition () 00074 { 00075 if (nextElement.IsValid ()) 00076 return parent->GetNextPosition (); 00077 else 00078 return parent->GetEndPosition (); 00079 } 00080 00081 virtual size_t GetEndPosition () 00082 { return parent->GetEndPosition (); } 00083 00084 private: 00085 void ForwardIterator () 00086 { 00087 if (!parent) nextElement = 0; 00088 00089 while (parent->HasNext ()) 00090 { 00091 csRef<iDocumentNode> parentNext = parent->Next (); 00092 if (filter (parentNext)) 00093 { 00094 nextElement = parentNext; 00095 return; 00096 } 00097 } 00098 nextElement = 0; 00099 parent = 0; 00100 } 00101 00102 csRef<iDocumentNodeIterator> parent; 00103 T filter; 00104 csRef<iDocumentNode> nextElement; 00105 }; 00106 } // namespace Implementation 00107 00114 template<class T> 00115 void RemoveDuplicateChildren (iDocumentNode *rootNode, T eq) 00116 { 00117 csRef<iDocumentNodeIterator> it = rootNode->GetNodes (); 00118 RemoveDuplicateChildren (rootNode, it, eq); 00119 } 00120 00127 template<class T> 00128 void RemoveDuplicateChildren (iDocumentNode *rootNode, 00129 csRef<iDocumentNodeIterator> childIt, T eq) 00130 { 00131 typedef csRefArray<iDocumentNode> NodeListType; 00132 NodeListType nodesToRemove; 00133 NodeListType nodesToKeep; 00134 00135 if (!childIt) return; 00136 00137 while (childIt->HasNext ()) 00138 { 00139 csRef<iDocumentNode> node = childIt->Next (); 00140 //compare it to those we already have 00141 bool keep = true; 00142 00143 NodeListType::Iterator it = nodesToKeep.GetIterator (); 00144 while (it.HasNext ()) 00145 { 00146 csRef<iDocumentNode> keepNode = it.Next (); 00147 if (keepNode->Equals (node)) 00148 { 00149 keep = false; 00150 break; 00151 } 00152 if (eq (node, keepNode)) 00153 { 00154 keep = false; 00155 break; 00156 } 00157 } 00158 00159 if (keep) 00160 { 00161 nodesToKeep.Push (node); 00162 } 00163 else 00164 { 00165 nodesToRemove.Push (node); 00166 } 00167 } 00168 00169 while (nodesToRemove.GetSize ()) 00170 { 00171 csRef<iDocumentNode> node = nodesToRemove.Pop (); 00172 rootNode->RemoveNode (node); 00173 } 00174 } 00175 00181 inline void CloneAttributes (iDocumentNode* from, iDocumentNode* to) 00182 { 00183 csRef<iDocumentAttributeIterator> atit = from->GetAttributes (); 00184 while (atit->HasNext ()) 00185 { 00186 csRef<iDocumentAttribute> attr = atit->Next (); 00187 to->SetAttribute (attr->GetName (), attr->GetValue ()); 00188 } 00189 } 00190 00196 inline void CloneNode (iDocumentNode* from, iDocumentNode* to) 00197 { 00198 to->SetValue (from->GetValue ()); 00199 csRef<iDocumentNodeIterator> it = from->GetNodes (); 00200 while (it->HasNext ()) 00201 { 00202 csRef<iDocumentNode> child = it->Next (); 00203 csRef<iDocumentNode> child_clone = to->CreateNodeBefore ( 00204 child->GetType (), 0); 00205 CloneNode (child, child_clone); 00206 } 00207 CloneAttributes (from, to); 00208 } 00209 00216 struct NodeNameCompare 00217 { 00218 bool operator () (iDocumentNode *node1, iDocumentNode *node2) const 00219 { 00220 if (node1->GetType () != CS_NODE_ELEMENT) return false; 00221 if (node2->GetType () != CS_NODE_ELEMENT) return false; 00222 00223 const char* name1 = node1->GetValue (); 00224 const char* name2 = node2->GetValue (); 00225 if (!csStrCaseCmp (name1, name2)) return true; 00226 return false; 00227 } 00228 }; 00229 00234 struct NodeAttributeCompare 00235 { 00236 NodeAttributeCompare (const char* attributeName) 00237 : attributeName (attributeName) 00238 { 00239 } 00240 00241 bool operator () (iDocumentNode *node1, iDocumentNode *node2) const 00242 { 00243 if (node1->GetType () != CS_NODE_ELEMENT) return false; 00244 if (node2->GetType () != CS_NODE_ELEMENT) return false; 00245 00246 csRef<iDocumentAttribute> attribute1 = 00247 node1->GetAttribute (attributeName.GetData ()); 00248 csRef<iDocumentAttribute> attribute2 = 00249 node2->GetAttribute (attributeName.GetData ()); 00250 if (!attribute1 || !attribute2) return false; 00251 00252 if (!csStrCaseCmp (attribute1->GetValue (), attribute2->GetValue ())) 00253 return true; 00254 00255 return false; 00256 } 00257 private: 00258 csString attributeName; 00259 }; 00260 00264 struct NodeValueTest 00265 { 00266 NodeValueTest (const char* value) 00267 : value (value) 00268 {} 00269 00270 bool operator () (iDocumentNode *node) 00271 { 00272 if (!node) return false; 00273 00274 const char *nodeValue = node->GetValue (); 00275 return (value == nodeValue); 00276 } 00277 00278 private: 00279 csString value; 00280 }; 00281 00285 struct NodeAttributeValueTest 00286 { 00287 NodeAttributeValueTest (const char *attribute, const char* value) 00288 : attribute (attribute), value (value) 00289 {} 00290 00291 bool operator () (iDocumentNode *node) 00292 { 00293 if (!node) return false; 00294 00295 const char* attributeValue = node->GetAttributeValue ( 00296 attribute.GetData ()); 00297 00298 return (value == attributeValue); 00299 } 00300 00301 private: 00302 csString attribute; 00303 csString value; 00304 }; 00305 00310 struct NodeAttributeRegexpTest 00311 { 00312 NodeAttributeRegexpTest (const char *attribute, const char* regexp) 00313 : attribute (attribute), valueMatcher (regexp) 00314 { 00315 } 00316 00317 bool operator () (iDocumentNode *node) 00318 { 00319 if (!node) return false; 00320 00321 const char* attributeValue = node->GetAttributeValue ( 00322 attribute.GetData ()); 00323 00324 return (valueMatcher.Match (attributeValue, csrxIgnoreCase) 00325 == csrxNoError); 00326 } 00327 00328 private: 00329 csString attribute; 00330 csRegExpMatcher valueMatcher; 00331 }; 00346 template<class T> 00347 csPtr<iDocumentNodeIterator> FilterDocumentNodeIterator( 00348 csRef<iDocumentNodeIterator> parent, T filter) 00349 { 00350 return new Implementation::FilterDocumentNodeIterator<T> 00351 (parent, filter); 00352 } 00353 00358 CS_CRYSTALSPACE_EXPORT csString FlattenNode (iDocumentNode* node); 00359 } // namespace DocSystem 00360 00365 namespace DocumentHelper 00366 { 00368 CS_DEPRECATED_TYPE_MSG("Use CS::DocSystem::NodeAttributeCompare") 00369 typedef CS::DocSystem::NodeAttributeCompare NodeAttributeCompare; 00370 00372 CS_DEPRECATED_TYPE_MSG("Use CS::DocSystem::NodeAttributeRegexpTest") 00373 typedef CS::DocSystem::NodeAttributeRegexpTest NodeAttributeRegexpTest; 00374 00376 CS_DEPRECATED_TYPE_MSG("Use CS::DocSystem::NodeAttributeValueTest") 00377 typedef CS::DocSystem::NodeAttributeValueTest NodeAttributeValueTest; 00378 00380 CS_DEPRECATED_TYPE_MSG("Use CS::DocSystem::NodeNameCompare") 00381 typedef CS::DocSystem::NodeNameCompare NodeNameCompare; 00382 00384 CS_DEPRECATED_TYPE_MSG("Use CS::DocSystem::NodeValueTest") 00385 typedef CS::DocSystem::NodeValueTest NodeValueTest; 00386 00388 template<class T> 00389 CS_DEPRECATED_METHOD_MSG("Use CS::DocSystem::RemoveDuplicateChildren") 00390 void RemoveDuplicateChildren (iDocumentNode *rootNode, T eq) 00391 { 00392 csRef<iDocumentNodeIterator> it = rootNode->GetNodes (); 00393 RemoveDuplicateChildren (rootNode, it, eq); 00394 } 00395 00397 template<class T> 00398 CS_DEPRECATED_METHOD_MSG("Use CS::DocSystem::RemoveDuplicateChildren") 00399 void RemoveDuplicateChildren (iDocumentNode *rootNode, 00400 csRef<iDocumentNodeIterator> childIt, T eq) 00401 { 00402 CS::DocSystem::RemoveDuplicateChildren (rootNode, childIt, eq); 00403 } 00404 00406 CS_DEPRECATED_METHOD_MSG("Use CS::DocSystem::CloneAttributes") 00407 inline void CloneAttributes (iDocumentNode* from, iDocumentNode* to) 00408 { 00409 CS::DocSystem::CloneAttributes (from, to); 00410 } 00411 00413 CS_DEPRECATED_METHOD_MSG("Use CS::DocSystem::CloneNode") 00414 inline void CloneNode (iDocumentNode* from, iDocumentNode* to) 00415 { 00416 CS::DocSystem::CloneNode (from, to); 00417 } 00418 00420 template<class T> 00421 CS_DEPRECATED_METHOD_MSG("Use CS::DocSystem::FilterDocumentNodeIterator") 00422 csPtr<iDocumentNodeIterator> FilterDocumentNodeIterator( 00423 csRef<iDocumentNodeIterator> parent, T filter) 00424 { 00425 return CS::DocSystem::FilterDocumentNodeIterator (parent, filter); 00426 } 00427 00429 CS_DEPRECATED_METHOD_MSG("Use CS::DocSystem::FlattenNode") 00430 inline csString FlattenNode (iDocumentNode* node) 00431 { 00432 return CS::DocSystem::FlattenNode (node); 00433 } 00434 } 00435 00436 } //namespace CS 00437 00438 #endif
Generated for Crystal Space 1.2.1 by doxygen 1.5.3