L:/channel/channel/include/HierarchicalIdTrait.h

Go to the documentation of this file.
00001 
00002 // Copyright (c) 2005, 2006 Yigong Liu
00003 // Permission to use, copy, modify, distribute and sell this software for any 
00004 //     purpose is hereby granted without fee, provided that the above copyright 
00005 //     notice appear in all copies and that both that copyright notice and this 
00006 //     permission notice appear in supporting documentation.
00007 // The author makes no representations about the 
00008 //     suitability of this software for any purpose. It is provided "as is" 
00009 //     without express or implied warranty.
00011 
00012 #ifndef _HIERARCHICAL_IDTRAITS_H_
00013 #define _HIERARCHICAL_IDTRAITS_H_
00014 
00015 #include <vector>
00016 #include <string>
00017 #include <sstream>
00018 #include "ace/CDR_Stream.h"
00019 
00020 namespace channel {
00021 
00039 
00040   template <class IdType> class  IdTrait;
00041 
00048   template <char separator = '/'>
00049   struct StringPathId : public std::vector<std::string> {
00050     enum { Separator = separator };
00051     bool valid_;
00052     StringPathId () {
00053       valid_ = true;
00054     }
00055     StringPathId (const char * pathname) {
00056       std::string name(pathname);
00057       valid_ = true;
00058       size_type pos1 = std::string::npos, pos2 = std::string::npos;
00059       pos1 = name.find(Separator);
00060       if (pos1 == std::string::npos) {
00061         valid_ = false;
00062       } else {
00063         while (true) {
00064           pos2 = name.find(Separator,pos1+1);
00065           if (pos2 != std::string::npos)
00066             push_back(name.substr(pos1+1, pos2-pos1-1));
00067           else {
00068             std::string s = name.substr(pos1+1);
00069             pos2 = s.find_last_not_of(' ');
00070             if (pos2 != std::string::npos)
00071               push_back(s.substr(0, pos2+1));
00072             break;
00073           }
00074           pos1 = pos2;
00075         }
00076       }
00077     }
00078   };
00079 
00081   template <>
00082     template <char separator>
00083     class IdTrait<StringPathId<separator> > {
00084     public:
00085 
00086     typedef StringPathId<separator> IdType;
00087     enum { Separator = IdType::Separator };
00088 
00089     typedef typename IdType::value_type NameType;
00090     
00092     static IdType CHANNEL_CONN_MSG;
00093     static IdType CHANNEL_DISCONN_MSG;
00094     static IdType INIT_SUBSCRIPTION_INFO_MSG;
00095     static IdType INIT_PUBLICATION_INFO_MSG;
00096     static IdType SUBSCRIPTION_INFO_MSG;
00097     static IdType UNSUBSCRIPTION_INFO_MSG;
00098     static IdType PUBLICATION_INFO_MSG;
00099     static IdType UNPUBLICATION_INFO_MSG;
00100 
00101     static NameType RootName;     //just a name for root trie node, not in namespace
00102     static NameType WildcardName;
00103 
00105     static bool eq(const IdType &id1, const IdType &id2)
00106       { return id1 == id2; }
00107     static bool lt(const IdType &id1, const IdType &id2)
00108       { return id1 < id2; }
00109 
00110     static std::string idToString(const IdType &id) {
00111       std::ostringstream os;
00112       for(size_t i=0; i<id.size(); i++)
00113         os << (char)Separator << id[i];
00114       return os.str();
00115     }
00116 
00117     static bool endWithWildcard(const IdType &id) {
00118       return (*id.rbegin()) == WildcardName;
00119     }
00120 
00121     static bool valid(const IdType &id) {
00122       if (!id.valid) return false;
00123       size_t sz = id.size();
00124       for (size_t i=0; i<sz; i++)
00125         if (id[i] == IdTrait::WildcardName && i != (sz-1))
00126           return false;
00127       return true;
00128     }
00129 
00130     enum ID_COMPARE_RESULT {
00131       ID_MATCH,
00132       ID_1_CONTAINS_2,
00133       ID_2_CONTAINS_1,
00134       ID_MISMATCH
00135     };
00136 
00137     static ID_COMPARE_RESULT compare(const IdType &id1, const IdType &id2)
00138       {
00139         int sz1 = id1.size();
00140         int sz2 = id2.size();
00141         int sz = (sz1 < sz2)?sz1:sz2;
00142         for(int i=0; i<sz; i++) {
00143           if (id1[i] != id2[i]) {
00144             if (id1[i] == IdTrait::WildcardName)
00145               return ID_1_CONTAINS_2;
00146             else if (id2[i] == IdTrait::WildcardName)
00147               return ID_2_CONTAINS_1;
00148             else return ID_MISMATCH;
00149           }
00150         }
00151         if (sz1 == sz2)
00152           return ID_MATCH;
00153         else if(sz1 < sz2 && id2[sz1] == IdTrait::WildcardName)
00154           return ID_2_CONTAINS_1;
00155         else if(sz2 < sz1 && id1[sz2] == IdTrait::WildcardName)
00156           return ID_1_CONTAINS_2;
00157         return ID_MISMATCH;
00158       }
00159 
00160     //compiler doesnt allow references here
00161     //static bool match(const IdType &id1, const IdType &id2)
00162     static bool match(const IdType id1, const IdType id2)
00163       {
00164         return compare(id1,id2) != ID_MISMATCH;
00165       }
00166 
00167     //compiler doesnt allow references here
00168     //static bool id1contains2(const IdType &id1, const IdType &id2)
00169     static bool id1contains2(const IdType id1, const IdType id2)
00170       {
00171         ID_COMPARE_RESULT res = compare(id1,id2);
00172         return res == ID_MATCH || res == ID_1_CONTAINS_2;
00173       }
00174 
00175     static int size(const IdType &id) {
00176       int sz = 4; //num of elements
00177       for(size_t i=0; i<id.size(); i++)
00178         sz += 4 /*len*/ + id[i].length();
00179       return sz;
00180     }
00181 
00183     static int marshal(ACE_OutputCDR &cdr, const IdType &id)
00184       {
00185         cdr << ACE_CDR::Long (id.size());
00186         for(size_t i=0; i<id.size(); i++) {
00187           cdr << ACE_CDR::Long (id[i].length());
00188           cdr.write_char_array (id[i].c_str(), id[i].length());
00189         }
00190         return cdr.good_bit();
00191       }
00192     static int demarshal(ACE_InputCDR &cdr, IdType &id)
00193       {
00194         ACE_CDR::Long d;
00195         char buffer[1024];
00196         cdr >> d;
00197         int sz = (int) d;
00198         for (int i=0; i<sz; i++) {
00199           cdr >> d;
00200           int len = (int) d;
00201           buffer[0] = '\0';
00202           cdr.read_char_array(buffer, len);
00203           buffer[len] = '\0';
00204           id.push_back(buffer);
00205         }
00206         return cdr.good_bit();
00207       }    
00208   };
00209 
00214   /*
00215   template <typename HierIdType>
00216     class SlashInitializer {
00217     typedef HierIdType::ElementType ElementType;
00218     private:
00219     
00220     protected:
00221     
00222   };
00223   */
00230   /*
00231   struct NumericPathId : public std::vector<int> {
00232   };
00233 
00235   template <>
00236     class IdTrait<NumericPathId> {
00237     public:
00239 
00240     static NumericPathId CHANNEL_CONN_MSG;
00241     static NumericPathId CHANNEL_DISCONN_MSG;
00242     static NumericPathId INIT_SUBSCRIPTION_INFO_MSG;
00243     static NumericPathId INIT_PUBLICATION_INFO_MSG;
00244     static NumericPathId SUBSCRIPTION_INFO_MSG;
00245     static NumericPathId UNSUBSCRIPTION_INFO_MSG;
00246     static NumericPathId PUBLICATION_INFO_MSG;
00247     static NumericPathId UNPUBLICATION_INFO_MSG;
00248 
00249     typedef NumericPathId IdType;
00250 
00251     //define root_name
00252     
00253     //define wildcard_name
00254 
00256     static bool eq(const NumericPathId &id1, const NumericPathId &id2)
00257       { return id1 == id2; }
00258     static bool lt(const NumericPathId &id1, const NumericPathId &id2)
00259       { return id1 < id2; }
00260 
00261     static std::string idToString(const NumericPathId id) {
00262       std::ostringstream os;
00263       os << "[Family:" << id.family << ", Type:" << id.type <<"]";
00264       return os.str();
00265     }
00266 
00267     static int size(const NumericPathId &id2) {
00268       ACE_UNUSED_ARG(id2);
00269       return sizeof(NumericPathId);
00270     }
00271 
00273     static int marshal(ACE_OutputCDR &cdr, const NumericPathId &id)
00274       {
00275         cdr << ACE_CDR::Long (id.family);
00276         cdr << ACE_CDR::Long (id.type);
00277         return cdr.good_bit();
00278       }
00279     static int demarshal(ACE_InputCDR &cdr, NumericPathId &id)
00280       {
00281         ACE_CDR::Long d;
00282         cdr >> d;
00283         id.family = (MessageFamily) d;
00284         cdr >> d;
00285         id.type = (int) d;
00286         return cdr.good_bit();
00287       }    
00288   };
00289   */
00290 };
00291 
00292 #endif

Generated on Mon Feb 27 19:59:21 2006 for channel by  doxygen 1.4.6-NO