00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifdef HAVE_CONFIG_H
00018 # include <dtn-config.h>
00019 #endif
00020
00021 #include "Dictionary.h"
00022 #include <oasys/debug/Log.h>
00023
00024 namespace dtn {
00025
00026
00027 Dictionary::Dictionary()
00028 : dict_(NULL), dict_length_(0), length_(0)
00029 {
00030 }
00031
00032
00033 Dictionary::Dictionary(const oasys::Builder&)
00034 : dict_(NULL), dict_length_(0), length_(0)
00035 {
00036 }
00037
00038
00039 Dictionary::~Dictionary()
00040 {
00041 if (dict_) {
00042 free(dict_);
00043 dict_ = 0;
00044 dict_length_ = 0;
00045 length_ = 0;
00046 }
00047 }
00048
00049
00050 void
00051 Dictionary::set_dict(const u_char* dict, u_int32_t length)
00052 {
00053 ASSERT(dict_ == NULL);
00054 dict_ = (u_char*)malloc(length);
00055 memcpy(dict_, dict, length);
00056 length_ = dict_length_ = length;
00057 }
00058
00059
00060 bool
00061 Dictionary::get_offset(const std::string& str, u_int32_t* offset)
00062 {
00063 *offset = 0;
00064 while (*offset < length_) {
00065 u_int32_t len = strlen((char*)(&dict_[*offset]));
00066 if (!strncmp(str.c_str(), (char*)(&dict_[*offset]), len)) {
00067 if (str.length() == len) {
00068 return true;
00069 }
00070 }
00071 *offset += (len + 1);
00072 ASSERT(*offset <= length_);
00073 }
00074
00075 return false;
00076 }
00077
00078
00079 bool
00080 Dictionary::get_offset(const std::string& str, u_int64_t* offset)
00081 {
00082 *offset = 0;
00083 while (*offset < length_) {
00084 u_int64_t len = strlen((char*)(&dict_[*offset]));
00085 if (!strncmp(str.c_str(), (char*)(&dict_[*offset]), len)) {
00086 if (str.length() == len) {
00087 return true;
00088 }
00089 }
00090 *offset += (len + 1);
00091 ASSERT(*offset <= length_);
00092 }
00093
00094 return false;
00095 }
00096
00097
00098 void
00099 Dictionary::add_str(const std::string& str)
00100 {
00101 u_int32_t offset;
00102 if (get_offset(str, &offset)) {
00103 return;
00104 }
00105
00106 if (dict_length_ < length_ + str.length() + 1) {
00107 do {
00108 dict_length_ = (dict_length_ == 0) ? 64 : dict_length_ * 2;
00109 } while (dict_length_ < length_ + str.length() + 1);
00110
00111 dict_ = (u_char*)realloc(dict_, dict_length_);
00112 }
00113
00114 memcpy(&dict_[length_], str.data(), str.length());
00115 dict_[length_ + str.length()] = '\0';
00116 length_ += str.length() + 1;
00117 }
00118
00119
00120
00121 void
00122 Dictionary::serialize(oasys::SerializeAction* a)
00123 {
00124 a->process("dict", dict_, length_);
00125 a->process("dict_length", &dict_length_);
00126 a->process("length", &length_);
00127 }
00128
00129
00130 bool
00131 Dictionary::extract_eid(EndpointID* eid,
00132 u_int32_t scheme_offset,
00133 u_int32_t ssp_offset)
00134 {
00135 static const char* log = "/dtn/bundle/protocol";
00136
00137
00138 if (dict_length_ == 0) {
00139 log_err_p(log, "cannot extract eid from zero-length dictionary");
00140 return false;
00141 }
00142
00143 if (scheme_offset >= (dict_length_ - 1)) {
00144 log_err_p(log, "illegal offset for scheme dictionary offset: "
00145 "offset %d, total length %u",
00146 scheme_offset, dict_length_);
00147 return false;
00148 }
00149
00150 if (ssp_offset >= (dict_length_ - 1)) {
00151 log_err_p(log, "illegal offset for ssp dictionary offset: "
00152 "offset %d, total length %u",
00153 ssp_offset, dict_length_);
00154 return false;
00155 }
00156
00157 eid->assign((char*)&dict_[scheme_offset],
00158 (char*)&dict_[ssp_offset]);
00159
00160 if (! eid->valid()) {
00161 log_err_p(log, "invalid endpoint id '%s': "
00162 "scheme '%s' offset %u/%u ssp '%s' offset %u/%u",
00163 eid->c_str(),
00164 eid->scheme_str().c_str(),
00165 scheme_offset, dict_length_,
00166 eid->ssp().c_str(),
00167 ssp_offset, dict_length_);
00168 return false;
00169 }
00170
00171 log_debug_p(log, "parsed eid (offsets %u, %u) %s",
00172 scheme_offset, ssp_offset, eid->c_str());
00173 return true;
00174 }
00175
00176
00177 bool
00178 Dictionary::extract_eid(EndpointID* eid,
00179 u_int64_t scheme_offset,
00180 u_int64_t ssp_offset)
00181 {
00182 u_int32_t scheme_offset32 = scheme_offset;
00183 u_int32_t ssp_offset32 = ssp_offset;
00184
00185 return extract_eid(eid, scheme_offset32, ssp_offset32);
00186 }
00187
00188 #if 0
00189
00190
00191
00193
00194
00195 void
00196 PrimaryBlockProcessor::get_dictionary_offsets(DictionaryVector *dict,
00197 const EndpointID& eid,
00198 u_int16_t* scheme_offset,
00199 u_int16_t* ssp_offset)
00200 {
00201 DictionaryVector::iterator iter;
00202 for (iter = dict->begin(); iter != dict->end(); ++iter) {
00203 if (iter->str == eid.scheme_str())
00204 *scheme_offset = htons(iter->offset);
00205
00206 if (iter->str == eid.ssp())
00207 *ssp_offset = htons(iter->offset);
00208 }
00209 }
00210
00211
00212 bool
00213 PrimaryBlockProcessor::extract_dictionary_eid(EndpointID* eid,
00214 const char* what,
00215 u_int16_t* scheme_offsetp,
00216 u_int16_t* ssp_offsetp,
00217 u_char* dictionary,
00218 u_int32_t dictionary_len)
00219 {
00220 static const char* log = "/dtn/bundle/protocol";
00221 u_int16_t scheme_offset, ssp_offset;
00222 memcpy(&scheme_offset, scheme_offsetp, 2);
00223 memcpy(&ssp_offset, ssp_offsetp, 2);
00224 scheme_offset = ntohs(scheme_offset);
00225 ssp_offset = ntohs(ssp_offset);
00226
00227 if (scheme_offset >= (dictionary_len - 1)) {
00228 log_err_p(log, "illegal offset for %s scheme dictionary offset: "
00229 "offset %d, total length %u", what,
00230 scheme_offset, dictionary_len);
00231 return false;
00232 }
00233
00234 if (ssp_offset >= (dictionary_len - 1)) {
00235 log_err_p(log, "illegal offset for %s ssp dictionary offset: "
00236 "offset %d, total length %u", what,
00237 ssp_offset, dictionary_len);
00238 return false;
00239 }
00240
00241 eid->assign((char*)&dictionary[scheme_offset],
00242 (char*)&dictionary[ssp_offset]);
00243
00244 if (! eid->valid()) {
00245 log_err_p(log, "invalid %s endpoint id '%s': "
00246 "scheme '%s' offset %u/%u ssp '%s' offset %u/%u",
00247 what, eid->c_str(),
00248 eid->scheme_str().c_str(),
00249 scheme_offset, dictionary_len,
00250 eid->ssp().c_str(),
00251 ssp_offset, dictionary_len);
00252 return false;
00253 }
00254
00255 log_debug_p(log, "parsed %s eid (offsets %u, %u) %s",
00256 what, scheme_offset, ssp_offset, eid->c_str());
00257 return true;
00258 }
00259
00260
00261 void
00262 PrimaryBlockProcessor::debug_dump_dictionary(const char* bp, u_int32_t len,
00263 PrimaryBlock2* primary2)
00264 {
00265 #ifndef NDEBUG
00266 oasys::StringBuffer dict_copy;
00267
00268 const char* end = bp + len;
00269 ASSERT(end[-1] == '\0');
00270
00271 while (bp != end) {
00272 dict_copy.appendf("%s ", bp);
00273 bp += strlen(bp) + 1;
00274 }
00275
00276 log_debug_p("/dtn/bundle/protocol",
00277 "dictionary len %zu, value: '%s'", len, dict_copy.c_str());
00278
00279 log_debug_p("/dtn/bundle/protocol",
00280 "dictionary offsets: dest %u,%u source %u,%u, "
00281 "custodian %u,%u replyto %u,%u",
00282 ntohs(primary2->dest_scheme_offset),
00283 ntohs(primary2->dest_ssp_offset),
00284 ntohs(primary2->source_scheme_offset),
00285 ntohs(primary2->source_ssp_offset),
00286 ntohs(primary2->custodian_scheme_offset),
00287 ntohs(primary2->custodian_ssp_offset),
00288 ntohs(primary2->replyto_scheme_offset),
00289 ntohs(primary2->replyto_ssp_offset));
00290 #else
00291 (void)bp;
00292 (void)len;
00293 (void)primary2;
00294 #endif
00295 }
00296 #endif
00297
00298 }