csutil/documenthelper.h Source File (Crystal Space 2.0 Public API Reference)

| ## Public API Reference

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

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);
    00363   CS_CRYSTALSPACE_EXPORT csString FlattenNodeShallow (iDocumentNode* node);
    00364
    00372   CS_CRYSTALSPACE_EXPORT csPtr<iDocument> MakeChangeable (iDocument* doc,
    00373                                                           iDocumentSystem* docsys);
    00374
    00383   CS_CRYSTALSPACE_EXPORT bool SetContentsValue (iDocumentNode* node,
    00384                                                 const char* contents);
    00385 } // namespace DocSystem
    00386
    00387
    00388 } //namespace CS
    00389
    00390 #endif