Router stores filters in a sequence. For now packages just point
authorAdam Dickmeiss <adam@indexdata.dk>
Thu, 6 Oct 2005 12:55:20 +0000 (12:55 +0000)
committerAdam Dickmeiss <adam@indexdata.dk>
Thu, 6 Oct 2005 12:55:20 +0000 (12:55 +0000)
the filters that is currently handling. That might be improved by
an interator. Changed the move function to return a Package reference.
Added two check programs.

src/Makefile.am
src/design.h
src/design_main.cpp
src/test_filter1.cpp [new file with mode: 0644]
src/test_filter2.cpp [new file with mode: 0644]

index 3bbe77b..784b9eb 100644 (file)
@@ -1,15 +1,17 @@
-## $Id: Makefile.am,v 1.2 2005-10-06 09:53:11 marc Exp $
+## $Id: Makefile.am,v 1.3 2005-10-06 12:55:20 adam Exp $
 
 AM_CXXFLAGS = $(YAZPPINC) $(XSLT_CFLAGS) $(USEMARCONINC)
 
 bin_PROGRAMS =
-check_PROGRAMS =  
+check_PROGRAMS = test_filter1 test_filter2
 noinst_PROGRAMS =  p2 design
 
 TESTS=$(check_PROGRAMS)
 
 design_SOURCES=design.h  design_main.cpp
 
+test_filter1_SOURCES=test_filter1.cpp
+test_filter2_SOURCES=test_filter2.cpp
 
 p2_SOURCES=p2_frontend.cpp p2_msg.cpp p2.cpp p2_frontend.h \
  p2_config.cpp p2_config.h \
index 481b705..10e06a6 100644 (file)
 #define DESIGN_H
 
 #include <stdexcept>
-
+#include <list>
 
 namespace yp2 {
 
-  class Package;
-  
-  class Filter {
-  public:
-    virtual ~Filter(){};
-    virtual  Package & process(Package & package) const {
-      return package;
+    class Package;
+    
+    class Filter {
+    public:
+        virtual ~Filter(){};
+        virtual  Package & process(Package & package) const {
+            return package;
+        };
+        virtual  void configure(){};
+        
+        // set/get the C++ way .. just as showoff
+        
+        // get function - returns copy and keeps object const, 
+        // thus is right val in assignment
+        std::string name() const {
+            return m_name;
+        }
+        // set function - returns reference and changes object,
+        // thus is left val in assignment
+        std::string & name() {
+            return m_name;
+        }
+        // more traditional set function, taking const reference 
+        // or copy (here const ref for demo), returning ref to object
+        // can be chained with other similar functions!
+        Filter & name(const std::string & name){
+            m_name = name;
+            return *this;
+        }
+        
+    private:
+        std::string m_name;
     };
-    virtual  void configure(){};
-
-    // set/get the C++ way .. just as showoff
-
-    // get function - returns copy and keeps object const, 
-    // thus is right val in assignment
-    std::string name() const {
-      return m_name;
-    }
-    // set function - returns reference and changes object,
-    // thus is left val in assignment
-    std::string & name() {
-      return m_name;
-    }
-    // more traditional set function, taking const reference 
-    // or copy (here const ref for demo), returning ref to object
-    // can be chained with other similar functions!
-    Filter & name(const std::string & name){
-      m_name = name;
-      return *this;
-    }
     
-  private:
-    std::string m_name;
-  };
-
-
-  class Filter_Exception : public std::runtime_error {
-  public:
-    Filter_Exception(const std::string message)
-      : std::runtime_error("Filter_Exception: " + message){
+    
+    class Filter_Exception : public std::runtime_error {
+    public:
+        Filter_Exception(const std::string message)
+            : std::runtime_error("Filter_Exception: " + message){
+        };
     };
-  };
-
+    
 
   class Router {
   public:
-    Router(){};
-    virtual ~Router(){};
-    virtual const Filter * 
-      route(const Filter *filter, const Package *package) const {
-      //if (!m_sillyrule)
-      //throw Router_Exception("no routing rules known");
-          return m_filter;
-    };
-    virtual void configure(){};
-    Router & rule(const Filter &filter){
-      m_filter = &filter;
+      Router(){};
+      virtual ~Router(){};
+      virtual const Filter * 
+          move(const Filter *filter, const Package *package) const {
+          std::list<const Filter *>::const_iterator it;
+          it = m_filter_list.begin();
+          if (filter)
+          {
+              for (; it != m_filter_list.end(); it++)
+                  if (*it == filter)
+                  {
+                      it++;
+                      break;
+                  }
+          }
+          if (it == m_filter_list.end())
+          {
+              //throw Router_Exception("no routing rules known");
+              return 0;
+          }
+          return *it;
+      };
+      virtual void configure(){};
+      Router & rule(const Filter &filter){
+          m_filter_list.push_back(&filter);
       return *this;
-    }
+      }
   private:
-    Router(const Router &);
-    Router& operator=(const Router &);
-    const Filter *m_filter;
+      Router(const Router &);
+      Router& operator=(const Router &);
+      std::list<const Filter *> m_filter_list;
   };
   
   
   class Router_Exception : public std::runtime_error {
   public:
-    Router_Exception(const std::string message)
-      : std::runtime_error("Router_Exception: " + message){};
+      Router_Exception(const std::string message)
+          : std::runtime_error("Router_Exception: " + message){};
   };
   
-
+  
   class Package {
   public:
-
-    // send package to it's next filter defined in chain
-    void move() 
-      {
-        m_filter = m_router->route(m_filter, this);
-        if (m_filter)
-          m_filter->process(*this);
+      
+      // send package to it's next filter defined in chain
+      Package & move() {
+          m_filter = m_router->move(m_filter, this);
+          if (m_filter)
+              return m_filter->process(*this);
+          else
+              return *this;
+          }
+      
+      // get function - returns copy and keeps object const, 
+      // thus is right val in assignment
+      unsigned int data() const {
+          return m_data;
       }
-    
-
-    // get function - returns copy and keeps object const, 
-    // thus is right val in assignment
-    unsigned int data() const {
-      return m_data;
-    }
-    // set function - returns reference and changes object,
-    // thus is left val in assignment
-    unsigned int & data() {
-      return m_data;
-    }
-
-    // more traditional set function, taking const reference 
-    // or copy (here const ref for demo), returning ref to object
-    // can be chained with other similar functions!
-    Package & data(const unsigned int & data){
-      m_data = data;
-      return *this;
-    }
-
-    // get function - returns copy and keeps object const, 
-    // thus is right val in assignment
-    //Router router() const {
-    //  return m_router;
-    //}
-    // set function - returns reference and changes object,
-    // thus is left val in assignment
-    //Router & router() {
-    //  return m_router;
-    //}
-    // more traditional set function, taking const reference 
-    // or copy (here const ref for demo), returning ref to object
-    // can be chained with other similar functions!
-    Package & router(const Router &router){
-      m_router = &router;
-      return *this;
-    }
-    
+      // set function - returns reference and changes object,
+      // thus is left val in assignment
+      unsigned int & data() {
+          return m_data;
+      }
+      
+      // more traditional set function, taking const reference 
+      // or copy (here const ref for demo), returning ref to object
+      // can be chained with other similar functions!
+      Package & data(const unsigned int & data){
+          m_data = data;
+          return *this;
+      }
+      
+      // get function - returns copy and keeps object const, 
+      // thus is right val in assignment
+      //Router router() const {
+      //  return m_router;
+      //}
+      // set function - returns reference and changes object,
+      // thus is left val in assignment
+      //Router & router() {
+      //  return m_router;
+      //}
+      // more traditional set function, taking const reference 
+      // or copy (here const ref for demo), returning ref to object
+      // can be chained with other similar functions!
+      Package & router(const Router &router){
+          m_filter = 0;
+          m_router = &router;
+          return *this;
+      }
+      Package() {
+          m_filter = 0;
+          m_router = 0;
+          m_data = 0;
+      }
+      
   private:
-    unsigned int m_data;
-    const Filter *m_filter;
-    const Router *m_router;
+      unsigned int m_data;
+      const Filter *m_filter;
+      const Router *m_router;
   };
-
-
+  
+  
   class Package_Exception : public std::runtime_error {
   public:
-    Package_Exception(const std::string message)
-      : std::runtime_error("Package_Exception: " + message){
-    };
+      Package_Exception(const std::string message)
+          : std::runtime_error("Package_Exception: " + message){
+      };
   };
-
-
-
   
 }
 
 #endif
+/*
+ * Local variables:
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ * vim: shiftwidth=4 tabstop=8 expandtab
+ */
index 6f2d2c6..f0b571e 100644 (file)
@@ -2,68 +2,70 @@
 #include <iostream>
 #include  "design.h"
 
-
-
 int main(int argc, char **argv) {
 
-   // test filter set/get/exception
-  try {
-    std::cout << "\nTRY" << "\n";
-    yp2::Filter filter;
+    // test filter set/get/exception
+    try {
+        std::cout << "\nTRY" << "\n";
+        yp2::Filter filter;
     
-    filter.name("filter1");
-    std::cout << "filter: " << filter.name() << "\n";
+        filter.name("filter1");
+        std::cout << "filter: " << filter.name() << "\n";
 
-    filter.name() = "filter1 rename";
-    std::cout << "filter: " << filter.name() << "\n";
+        filter.name() = "filter1 rename";
+        std::cout << "filter: " << filter.name() << "\n";
 
-    throw yp2::Filter_Exception("finished");
-  }
-  catch (std::exception &e) {
-    std::cout << e.what() << "\n";
-  }
+        throw yp2::Filter_Exception("finished");
+    }
+    catch (std::exception &e) {
+        std::cout << e.what() << "\n";
+    }
 
   
-  try {
-    std::cout << "\nTRY" << "\n";
+    try {
+        std::cout << "\nTRY" << "\n";
 
-    yp2::Filter filter1;
-    filter1.name("filter1");
+        yp2::Filter filter1;
+        filter1.name("filter1");
     
-    yp2::Filter filter2;
-    filter2.name() = "filter2";
+        yp2::Filter filter2;
+        filter2.name() = "filter2";
 
-    std::cout << "filter1 filter2" << "\n";
+        std::cout << "filter1 filter2" << "\n";
     
-    yp2::Router router1;
-    router1.rule(filter1);
-    std::cout << "router1.rule(filter1)" << "\n";
-
-    yp2::Router router2;
-    router2.rule(filter2);
-    std::cout << "router2.rule(filter2)" << "\n";
-
-    yp2::Package pack_in;
-    pack_in.data(7).router(router1);
-    std::cout << "pack_in.data(7).router(router1)" << "\n";
-
-    pack_in.move();
-    std::cout << "pack_in.move()" << "\n";
+        yp2::Router router1;
+        router1.rule(filter1);
+        std::cout << "router1.rule(filter1)" << "\n";
 
-    pack_in.router(router2);
-    std::cout << "pack_in.router(router2)" << "\n";
+        yp2::Router router2;
+        router2.rule(filter2);
+        std::cout << "router2.rule(filter2)" << "\n";
 
-    pack_in.move();
-    std::cout << "pack_in.move()" << "\n";
+        yp2::Package pack_in;
+        pack_in.data(7).router(router1);
+        std::cout << "pack_in.data(7).router(router1)" << "\n";
 
-    throw  yp2::Router_Exception("finished");
+        pack_in.move();
+        std::cout << "pack_in.move()" << "\n";
 
-  }
-  catch (std::exception &e) {
-    std::cout << e.what() << "\n";
-  }
+        pack_in.router(router2);
+        std::cout << "pack_in.router(router2)" << "\n";
 
+        pack_in.move();
+        std::cout << "pack_in.move()" << "\n";
 
+        throw  yp2::Router_Exception("finished");
 
+    }
+    catch (std::exception &e) {
+        std::cout << e.what() << "\n";
+    }
 }
 
+/*
+ * Local variables:
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ * vim: shiftwidth=4 tabstop=8 expandtab
+ */
diff --git a/src/test_filter1.cpp b/src/test_filter1.cpp
new file mode 100644 (file)
index 0000000..488da1f
--- /dev/null
@@ -0,0 +1,45 @@
+
+#include <iostream>
+#include "design.h"
+
+class TFilter: public yp2::Filter {
+public:
+    yp2::Package & process(yp2::Package & package) const {
+       return package;
+    };
+};
+    
+int main(int argc, char **argv)
+{
+    // test filter set/get/exception
+    try {
+        TFilter filter;
+       
+        filter.name("filter1");
+
+       if (filter.name() != "filter1")
+       {
+           std::cout << "filter name does not match 1\n";
+           exit(1);
+       }
+        filter.name() = "filter1 rename";
+       if (filter.name() != "filter1 rename")
+       {
+           std::cout << "filter name does not match 2\n";
+           exit(1);
+       }
+    }
+    catch (std::exception &e) {
+        std::cout << e.what() << "\n";
+       exit(1);
+    }
+    exit(0);
+}
+
+/*
+ * Local variables:
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ * vim: shiftwidth=4 tabstop=8 expandtab
+ */
diff --git a/src/test_filter2.cpp b/src/test_filter2.cpp
new file mode 100644 (file)
index 0000000..f7db7fe
--- /dev/null
@@ -0,0 +1,80 @@
+
+#include <iostream>
+#include "design.h"
+
+class FilterConstant: public yp2::Filter {
+public:
+    yp2::Package & process(yp2::Package & package) const {
+       package.data() = 1234;
+       return package.move();
+    };
+};
+
+
+class FilterDouble: public yp2::Filter {
+public:
+    yp2::Package & process(yp2::Package & package) const {
+       package.data() = package.data() * 2;
+       return package.move();
+    };
+};
+    
+    
+int main(int argc, char **argv)
+{
+    try {
+       FilterConstant fc;
+       FilterDouble fd;
+
+       {
+           yp2::Router router1;
+           
+           // test filter set/get/exception
+           router1.rule(fc);
+           
+           router1.rule(fd);
+           
+           yp2::Package pack_in;
+           
+           yp2::Package pack_out;
+           
+           pack_out = pack_in.router(router1).move(); 
+           
+           if (pack_out.data() != 2468)
+           {
+               exit(1);
+           }
+       }
+       {
+           yp2::Router router1;
+           
+           router1.rule(fd);
+           router1.rule(fc);
+           
+           yp2::Package pack_in;
+           
+           yp2::Package pack_out;
+           
+           pack_out = pack_in.router(router1).move(); 
+           
+           if (pack_out.data() != 1234)
+           {
+               exit(1);
+           }
+       }
+
+    }
+    catch (std::exception &e) {
+        std::cout << e.what() << "\n";
+       exit(1);
+    }
+    exit(0);
+}
+
+/*
+ * Local variables:
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ * vim: shiftwidth=4 tabstop=8 expandtab
+ */