myserver-commit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[myserver-commit] [2749] Added support for XPath


From: Giuseppe Scrivano
Subject: [myserver-commit] [2749] Added support for XPath
Date: Thu, 14 Aug 2008 16:28:58 +0000

Revision: 2749
          http://svn.sv.gnu.org/viewvc/?view=rev&root=myserver&revision=2749
Author:   gscrivano
Date:     2008-08-14 16:28:58 +0000 (Thu, 14 Aug 2008)

Log Message:
-----------
Added support for XPath

Modified Paths:
--------------
    trunk/myserver/TODO
    trunk/myserver/include/xml_parser.h
    trunk/myserver/src/cached_file_factory.cpp
    trunk/myserver/src/clients_thread.cpp
    trunk/myserver/src/server.cpp
    trunk/myserver/src/xml_parser.cpp

Added Paths:
-----------
    trunk/myserver/tests/test_xml.cpp

Modified: trunk/myserver/TODO
===================================================================
--- trunk/myserver/TODO 2008-08-13 22:29:37 UTC (rev 2748)
+++ trunk/myserver/TODO 2008-08-14 16:28:58 UTC (rev 2749)
@@ -8,7 +8,7 @@
 
 *      Security mechanism: SECURE ONE FILE with "security".
 **     Add more functionality to "security".
-**     Usage of XPath.
+**     Usage of XPath to make source code clearer.
 
 *      Deny and allow ACCESS by ip, browser, etc.
 **     Provide this functionality for "security".

Modified: trunk/myserver/include/xml_parser.h
===================================================================
--- trunk/myserver/include/xml_parser.h 2008-08-13 22:29:37 UTC (rev 2748)
+++ trunk/myserver/include/xml_parser.h 2008-08-14 16:28:58 UTC (rev 2749)
@@ -1,6 +1,6 @@
 /*
 MyServer
-Copyright (C) 2002, 2003, 2004, 2007 Free Software Foundation, Inc.
+Copyright (C) 2002, 2003, 2004, 2007, 2008 Free Software Foundation, Inc.
 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation; either version 3 of the License, or
@@ -26,44 +26,64 @@
 #include <libxml/xmlmemory.h>
 #include <libxml/parser.h>
 #include <libxml/tree.h> 
+#include <libxml/xpath.h>
+#include <libxml/xpathInternals.h>
 }
 #include <string>
 
 using namespace std;
 
 /*!
+ *Helper class to memorize a xpath result.
+ */
+class XmlXPathResult
+{
+public:
+  XmlXPathResult(xmlXPathObjectPtr obj){xpathObj = obj;}
+  ~XmlXPathResult(){if(xpathObj)xmlXPathFreeObject(xpathObj);}
+  xmlXPathObjectPtr getObject(){return xpathObj;}
+  xmlNodeSetPtr getNodeSet(){return (xpathObj ? xpathObj->nodesetval : NULL);}
+private:
+  xmlXPathObjectPtr xpathObj;
+};
+
+/*!
  *This class is used to open a .xml file and read information from it.
  */
 class XmlParser
 {
 public:
        static bool startXML();
-    static bool cleanXML();
+  static bool cleanXML();
        XmlParser();
        ~XmlParser();
        xmlDocPtr getDoc();
-       int open(const char* filename);
-       int open(string const &filename){return open(filename.c_str());};
-       int openMemBuf(MemBuf &);
+       int open(const char* filename, bool useXpath = 0);
+       int open(string const &filename, bool useXpath = 0){return 
open(filename.c_str(), useXpath);};
+       int openMemBuf(MemBuf &, bool useXpath = 0);
+
        char *getValue(const char* field);
        char *getValue(string const &field){return getValue(field.c_str());};
        char *getAttr(const char* field, const char *attr);
        int setValue(const char* field, const char *value);
        int close();
+
        int save(const char *filename,int *nbytes = 0);
        int save(string const &filename,int *nbytes = 0){return 
save(filename.c_str(), nbytes);};
        int saveMemBuf(MemBuf &,int *nbytes = 0);
+
        void newfile(const char * root);
        void newfile(string const &root){newfile(root.c_str());};
        void addChild(const char * name, const char * value);
        void addChild(string const &name, string& value)
-    {addChild(name.c_str(), value.c_str());};
+  {addChild(name.c_str(), value.c_str());};
        void addGroup(const char * name);
        void addGroup(string const &name)
-    {addGroup(name.c_str());};
+  {addGroup(name.c_str());};
        void endGroup();
+
        void setAttr(const char * name, const char * value);
-       
+
        void setAttr(string& name, string& value)
        {
                setAttr(name.c_str(), value.c_str());
@@ -72,7 +92,10 @@
        void addLineFeed();
        time_t getLastModTime();
        
+  XmlXPathResult* evaluateXpath(const char*);
 private:
+  xmlXPathContextPtr xpathCtx;
+  bool useXpath;
        xmlDocPtr doc;
        string buffer;
        xmlNodePtr cur;

Modified: trunk/myserver/src/cached_file_factory.cpp
===================================================================
--- trunk/myserver/src/cached_file_factory.cpp  2008-08-13 22:29:37 UTC (rev 
2748)
+++ trunk/myserver/src/cached_file_factory.cpp  2008-08-14 16:28:58 UTC (rev 
2749)
@@ -142,6 +142,7 @@
   CachedFileBuffer *buffer;
   CachedFile* cachedFile;
   u_long ticks;
+
   mutex.lock();
   
   ticks = getTicks();

Modified: trunk/myserver/src/clients_thread.cpp
===================================================================
--- trunk/myserver/src/clients_thread.cpp       2008-08-13 22:29:37 UTC (rev 
2748)
+++ trunk/myserver/src/clients_thread.cpp       2008-08-14 16:28:58 UTC (rev 
2749)
@@ -67,6 +67,7 @@
 {
   if(initialized == 0)
     return;
+
   threadIsRunning = 0;
 
   if(httpParser)

Modified: trunk/myserver/src/server.cpp
===================================================================
--- trunk/myserver/src/server.cpp       2008-08-13 22:29:37 UTC (rev 2748)
+++ trunk/myserver/src/server.cpp       2008-08-14 16:28:58 UTC (rev 2749)
@@ -158,18 +158,18 @@
   {
     try
     {
-      string software_signature;
-      software_signature.assign("************MyServer ");
-      software_signature.append(versionOfSoftware);
-      software_signature.append("************");
+      string softwareSignature;
+      softwareSignature.assign("************MyServer ");
+      softwareSignature.append(versionOfSoftware);
+      softwareSignature.append("************");
 
-      i = software_signature.length();
+      i = softwareSignature.length();
       while(i--)
         logManager.write("*");
       logManager.writeln("");
-      logManager.write(software_signature.c_str());
+      logManager.write(softwareSignature.c_str());
       logManager.write("\n");
-      i = software_signature.length();
+      i = softwareSignature.length();
       while(i--)
         logManager.write("*");
       logManager.writeln("");
@@ -379,7 +379,8 @@
               delete oldvhost;
 
               /* Load the virtual hosts configuration from the xml file.  */
-              
if(vhostList->loadXMLConfigurationFile(vhostConfigurationFile->c_str(), 
getMaxLogFileSize()))
+              
if(vhostList->loadXMLConfigurationFile(vhostConfigurationFile->c_str(),
+                                                     getMaxLogFileSize()))
               {
                 listenThreads.rollbackFastReboot();
 
@@ -435,6 +436,7 @@
 {
   u_long ticks = getTicks();
   u_long destroyed = 0;
+
   purgeThreadsThreshold = std::min(purgeThreadsThreshold << 1, nMaxThreads);
   threadsMutex->lock();
   for(list<ClientsThread*>::iterator it = threads.begin(); it != 
threads.end();)
@@ -571,11 +573,13 @@
   listenThreads.terminate();
 
   threadsMutex->lock();
+
   for(list<ClientsThread*>::iterator it = threads.begin(); it != 
threads.end(); it++)
   {
     threadsIds.push_back((*it)->getThreadId());
     (*it)->stop();
   }
+
   threadsMutex->unlock();
   Socket::stopBlockingOperations(true);
 

Modified: trunk/myserver/src/xml_parser.cpp
===================================================================
--- trunk/myserver/src/xml_parser.cpp   2008-08-13 22:29:37 UTC (rev 2748)
+++ trunk/myserver/src/xml_parser.cpp   2008-08-14 16:28:58 UTC (rev 2749)
@@ -19,7 +19,8 @@
 #include "../include/utility.h"
 #include "../include/files_utility.h"
 
-extern "C" {
+extern "C" 
+{
 #include <string.h>
 }
 
@@ -73,22 +74,24 @@
 
 /**
  * Opens a files and stores it in memory.
- * \param filename The filename
+ * \param filename The XML file to open.
+ * \param useXpath Specify if XPath is enabled.
  * \return Returns 0 on success, non zero values on failure
  */
-int XmlParser::open(const char* filename)
+int XmlParser::open(const char* filename, bool useXpath)
 {
-  cur = 0;
+  cur = NULL;
+  this->useXpath = useXpath;
 
   if(!FilesUtility::fileExists(filename))
     return -1;
 
-  if(doc!=0)
+  if(doc!= NULL)
     close();
 
   doc = xmlParseFile(filename);
 
-  if(doc == 0)
+  if(doc == NULL)
     return -1;
 
   cur = xmlDocGetRootElement(doc);
@@ -106,7 +109,17 @@
     close();
     return -1;
   }
-  
+
+  if(useXpath)
+  {
+    xpathCtx = xmlXPathNewContext(doc);
+    if(xpathCtx == NULL)
+    {
+      close();
+      return -1;
+    }
+  }
+
   return 0;
 }
 
@@ -122,13 +135,15 @@
 
 /**
  * Read the XML data from a char array
- * \param memory Memory Buffer
+ * \param memory The memory buffer to read from.
+ * \param useXpath Specify if XPath is enabled.
  * \return Returns 0 on succes, non 0 on failure
  */
-int XmlParser::openMemBuf(MemBuf & memory)
+int XmlParser::openMemBuf(MemBuf & memory, bool useXpath)
 {
   mtime = 0;
-  cur = 0;
+  cur = NULL;
+  this->useXpath = useXpath;
   
   if(memory.getLength() == 0)
     return -1;
@@ -152,6 +167,16 @@
     return -1;
   }
 
+  if(useXpath)
+  {
+    xpathCtx = xmlXPathNewContext(doc);
+    if(xpathCtx == NULL)
+    {
+      close();
+      return -1;
+    }
+  }
+
   return 0;
 }
 
@@ -160,10 +185,13 @@
  */
 XmlParser::XmlParser()
 {
-  doc = 0;
-  cur = 0;
-  prevCur = 0;
-  lastNode = 0;
+  doc = NULL;
+  cur = NULL;
+  xpathCtx = NULL;
+  useXpath = false;
+  prevCur = NULL;
+  lastNode = NULL;
+  mtime = 0;
 }
 
 /**
@@ -191,7 +219,7 @@
  */
 char *XmlParser::getValue(const char* vName)
 {
-  char *ret = 0;
+  char *ret = NULL;
   xmlNodePtr lcur;
   cur = xmlDocGetRootElement(doc);
 
@@ -291,7 +319,7 @@
           return (char*)attrs->children->content;
         }
         
-        attrs=attrs->next;
+        attrs = attrs->next;
       }
     }
     
@@ -301,7 +329,28 @@
   return 0;
 }
 
+/**
+ *Evaluate an XPath expression.
+ *\param query The xpath expression.
+ *\return NULL on errors.
+ *\return The XmlXPathResult containing the result.
+ */
+XmlXPathResult* XmlParser::evaluateXpath(const char* expr)
+{
+  xmlXPathObjectPtr xpathObj;
 
+  if(!useXpath)
+    return NULL;
+
+  xpathObj = xmlXPathEvalExpression((const xmlChar*)expr, xpathCtx);
+  
+  if(xpathObj == NULL) 
+    return NULL;
+
+  return new XmlXPathResult(xpathObj);
+}
+
+
 /**
  * Frees the memory, use by the XmlParser class
  */
@@ -311,12 +360,17 @@
   {
     xmlFreeDoc(doc);
   }
-  
-  doc=0;
-  cur=0;
-  prevCur=0;
-  lastNode=0;
-  
+
+  if(useXpath && xpathCtx)
+  {
+    xmlXPathFreeContext(xpathCtx); 
+  }
+
+  doc = NULL;
+  cur = NULL;
+  prevCur = NULL;
+  lastNode = NULL;
+
   return 0;
 }
 
@@ -375,7 +429,7 @@
  */
 void XmlParser::newfile(const char * root)
 {
-  if(doc != 0)
+  if(doc != NULL)
     close();
   
   doc = xmlNewDoc((const xmlChar*)"1.0");
@@ -409,7 +463,7 @@
  */
 void XmlParser::addGroup(const char * name)
 {
-  if(prevCur == 0)
+  if(prevCur == NULL)
   {
     prevCur = cur;
     cur = xmlNewTextChild(cur, NULL, (const xmlChar*)name, NULL);
@@ -426,10 +480,10 @@
  */
 void XmlParser::endGroup()
 {
-  if(prevCur != 0)
+  if(prevCur != NULL)
   {
     cur = prevCur;
-    prevCur = 0;
+    prevCur = NULL;
      
     addLineFeed();
     addLineFeed();
@@ -444,7 +498,7 @@
  */
 void XmlParser::setAttr(const char * name, const char * value)
 {
-  if(lastNode == 0)
+  if(lastNode == NULL)
     return;
   
   xmlSetProp(lastNode, (const xmlChar*)name, (const xmlChar*)value);

Added: trunk/myserver/tests/test_xml.cpp
===================================================================
--- trunk/myserver/tests/test_xml.cpp                           (rev 0)
+++ trunk/myserver/tests/test_xml.cpp   2008-08-14 16:28:58 UTC (rev 2749)
@@ -0,0 +1,108 @@
+/*
+ MyServer
+ Copyright (C) 2008 Free Software Foundation, Inc.
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+ 
+ This program is distributed in the hope that it will be useful, 
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ GNU General Public License for more details.
+ 
+ You should have received a copy of the GNU General Public License
+ along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <ctype.h>
+
+#include <cppunit/CompilerOutputter.h>
+#include <cppunit/extensions/TestFactoryRegistry.h>
+#include <cppunit/ui/text/TestRunner.h>
+#include <cppunit/extensions/HelperMacros.h>
+#include "../include/xml_parser.h"
+#include <string.h>
+#include <string>
+
+using namespace std;
+
+
+class TestXml : public CppUnit::TestFixture
+{
+  CPPUNIT_TEST_SUITE( TestXml );
+  CPPUNIT_TEST( testOpenMemBuf );
+  CPPUNIT_TEST( testXPath );
+  CPPUNIT_TEST_SUITE_END();
+
+  MemBuf* getXmlMemBuf()
+  {
+    MemBuf* memBuf = new MemBuf();
+
+    *memBuf << "<?xml version=\"1.0\"?>"
+            << "<ROOT>"
+            << "<NODE><ELEMENT name=\"a\">a</ELEMENT></NODE>"
+            << "<NODE><ELEMENT>b</ELEMENT><ELEMENT>c</ELEMENT></NODE>"
+            << "<NODE><ELEMENT>d</ELEMENT><ELEMENT>e</ELEMENT></NODE>"
+            << "<NODE><ELEMENT>f</ELEMENT></NODE>"
+            << "</ROOT>";
+    
+    return memBuf;
+  }
+
+public:
+
+  void setUp()
+  {
+ 
+  }
+
+  void tearDown()
+  {
+
+  }
+  
+  void testOpenMemBuf()
+  {
+    MemBuf* memBuf = getXmlMemBuf();
+
+    XmlParser *xml = new XmlParser();
+    int ret = xml->openMemBuf(*memBuf);
+
+    CPPUNIT_ASSERT_EQUAL(ret, 0);
+
+    delete memBuf;
+    delete xml;
+  }
+
+  void testXPath()
+  {
+    MemBuf* memBuf = getXmlMemBuf();
+
+    XmlParser *xml = new XmlParser();
+    xml->openMemBuf(*memBuf, true);
+
+
+    XmlXPathResult* xpathRes = 
xml->evaluateXpath("/ROOT/NODE/address@hidden'a']/text()");
+
+    CPPUNIT_ASSERT(xpathRes);
+
+    xmlXPathObjectPtr obj = xpathRes->getObject();
+
+    xmlNodeSetPtr nodes = xpathRes->getNodeSet();
+
+    CPPUNIT_ASSERT(obj);
+
+    CPPUNIT_ASSERT_EQUAL(nodes->nodeNr, 1);
+    
+    CPPUNIT_ASSERT(!strcmp((const char*)nodes->nodeTab[0]->content, "a"));
+
+    delete xpathRes;
+    delete memBuf;
+    delete xml;
+  }
+
+};
+
+
+CPPUNIT_TEST_SUITE_REGISTRATION( TestXml );






reply via email to

[Prev in Thread] Current Thread [Next in Thread]