CrystalSpace

Public API Reference

csutil/documenthelper.h

Go to the documentation of this file.
00001 /*
00002   Copyright (C) 2005 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/refarr.h"
00028 #include "csutil/regexp.h"
00029 #include "csutil/scf_implementation.h"
00030 
00031 #include "iutil/document.h"
00032 
00033 namespace CrystalSpace
00034 {
00039   namespace DocumentHelper
00040   {
00041     namespace Implementation
00042     {
00047       template<class T>
00048       class FilterDocumentNodeIterator : public 
00049         scfImplementation1 <FilterDocumentNodeIterator<T>, 
00050           iDocumentNodeIterator>
00051       {
00052       public:
00053         FilterDocumentNodeIterator (csRef<iDocumentNodeIterator> parent,
00054           T filter) : scfImplementation1<FilterDocumentNodeIterator<T>, 
00055             iDocumentNodeIterator> (this), parent (parent), filter (filter)
00056         {
00057           ForwardIterator ();
00058         }
00059 
00060         // -- iDocumentNodeIterator
00062         virtual bool HasNext ()
00063         {
00064           return nextElement.IsValid ();
00065         }
00066 
00068         virtual csRef<iDocumentNode> Next ()
00069         {
00070           csRef<iDocumentNode> current = nextElement;
00071           ForwardIterator ();
00072           return current;
00073         }
00074 
00075       private:
00076         void ForwardIterator ()
00077         {
00078           if (!parent) nextElement = 0;
00079 
00080           while (parent->HasNext ())
00081           {
00082             csRef<iDocumentNode> parentNext = parent->Next ();
00083             if (filter (parentNext))
00084             {
00085               nextElement = parentNext;
00086               return;
00087             }
00088           }
00089           nextElement = 0;
00090           parent = 0;
00091         }
00092 
00093         csRef<iDocumentNodeIterator> parent;
00094         T filter;
00095         csRef<iDocumentNode> nextElement;
00096       };
00097     }
00098     
00105     template<class T>
00106     void RemoveDuplicateChildren (iDocumentNode *rootNode, T eq)
00107     {
00108       csRef<iDocumentNodeIterator> it = rootNode->GetNodes ();
00109       RemoveDuplicateChildren (rootNode, it, eq);
00110     }
00111 
00118     template<class T>
00119     void RemoveDuplicateChildren (iDocumentNode *rootNode,
00120       csRef<iDocumentNodeIterator> childIt, T eq)
00121     {
00122       typedef csRefArray<iDocumentNode> NodeListType;
00123       NodeListType nodesToRemove;
00124       NodeListType nodesToKeep;
00125 
00126       if (!childIt) return;
00127 
00128       while (childIt->HasNext ())
00129       {
00130         csRef<iDocumentNode> node = childIt->Next ();
00131         //compare it to those we already have
00132         bool keep = true;
00133 
00134         NodeListType::Iterator it = nodesToKeep.GetIterator ();
00135         while (it.HasNext ())
00136         {
00137           csRef<iDocumentNode> keepNode = it.Next ();
00138           if (keepNode->Equals (node))
00139           {
00140             keep = false; 
00141             break;
00142           }
00143           if (eq (node, keepNode))
00144           {
00145             keep = false;
00146             break;
00147           }
00148         }
00149 
00150         if (keep)
00151         {
00152           nodesToKeep.Push (node);
00153         }
00154         else
00155         {
00156           nodesToRemove.Push (node);
00157         }
00158       }
00159 
00160       while (nodesToRemove.GetSize ())
00161       {
00162         csRef<iDocumentNode> node = nodesToRemove.Pop ();
00163         rootNode->RemoveNode (node);
00164       }
00165     }
00166 
00173     struct NodeNameCompare
00174     {
00175       bool operator () (iDocumentNode *node1, iDocumentNode *node2) const
00176       {
00177         if (node1->GetType () != CS_NODE_ELEMENT) return false;
00178         if (node2->GetType () != CS_NODE_ELEMENT) return false;
00179 
00180         const char* name1 = node1->GetValue ();
00181         const char* name2 = node2->GetValue ();
00182         if (!csStrCaseCmp (name1, name2)) return true;
00183         return false;
00184       }
00185     };
00186 
00191     struct NodeAttributeCompare
00192     {
00193       NodeAttributeCompare (const char* attributeName)
00194         : attributeName (attributeName)
00195       {
00196       }
00197 
00198       bool operator () (iDocumentNode *node1, iDocumentNode *node2) const
00199       {
00200         if (node1->GetType () != CS_NODE_ELEMENT) return false;
00201         if (node2->GetType () != CS_NODE_ELEMENT) return false;
00202 
00203         csRef<iDocumentAttribute> attribute1 = 
00204           node1->GetAttribute (attributeName.GetData ());
00205         csRef<iDocumentAttribute> attribute2 = 
00206           node2->GetAttribute (attributeName.GetData ());
00207         if (!attribute1 || !attribute2) return false;
00208 
00209         if (!csStrCaseCmp (attribute1->GetValue (), attribute2->GetValue ())) 
00210           return true;
00211 
00212         return false;
00213       }
00214     private:
00215       csString attributeName;
00216     };
00217 
00221     struct NodeValueTest
00222     {
00223       NodeValueTest (const char* value)
00224         : value (value)
00225       {}
00226 
00227       bool operator () (iDocumentNode *node)
00228       {
00229         if (!node) return false;
00230 
00231         const char *nodeValue = node->GetValue ();
00232         return (value == nodeValue);
00233       }
00234 
00235     private:
00236       csString value;
00237     };
00238 
00242     struct NodeAttributeValueTest
00243     {
00244       NodeAttributeValueTest (const char *attribute, const char* value)
00245         : attribute (attribute), value (value)
00246       {}
00247 
00248       bool operator () (iDocumentNode *node)
00249       {
00250         if (!node) return false;
00251 
00252         const char* attributeValue = node->GetAttributeValue (
00253                 attribute.GetData ());
00254 
00255         return (value == attributeValue);
00256       }
00257 
00258     private:
00259       csString attribute;
00260       csString value;
00261     };
00262 
00267     struct NodeAttributeRegexpTest
00268     {
00269       NodeAttributeRegexpTest (const char *attribute, const char* regexp)
00270         : attribute (attribute), valueMatcher (regexp)
00271       {
00272       }
00273 
00274       bool operator () (iDocumentNode *node)
00275       {
00276         if (!node) return false;
00277 
00278         const char* attributeValue = node->GetAttributeValue (
00279                 attribute.GetData ());
00280 
00281         return (valueMatcher.Match (attributeValue, csrxIgnoreCase)
00282                 == csrxNoError);
00283       }
00284 
00285     private:
00286       csString attribute;
00287       csRegExpMatcher valueMatcher;
00288     };
00302     template<class T>
00303     csPtr<iDocumentNodeIterator> FilterDocumentNodeIterator(
00304       csRef<iDocumentNodeIterator> parent, T filter)
00305     {
00306       return new Implementation::FilterDocumentNodeIterator<T>
00307         (parent, filter);
00308     }
00309   }
00310 }
00311 
00312 #endif

Generated for Crystal Space by doxygen 1.4.6