CrystalSpace

Public API Reference

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