00001
00002
00003
00004
00005
00006
00007
00008
00009
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;
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
00161
00162 static bool match(const IdType id1, const IdType id2)
00163 {
00164 return compare(id1,id2) != ID_MISMATCH;
00165 }
00166
00167
00168
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;
00177 for(size_t i=0; i<id.size(); i++)
00178 sz += 4 + 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
00216
00217
00218
00219
00220
00221
00222
00223
00230
00231
00232
00233
00235
00236
00237
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290 };
00291
00292 #endif