servlib/bundling/Dictionary.cc
changeset 0 2b3e5ec03512
equal deleted inserted replaced
-1:000000000000 0:2b3e5ec03512
       
     1 /*
       
     2  *    Copyright 2006 Intel Corporation
       
     3  * 
       
     4  *    Licensed under the Apache License, Version 2.0 (the "License");
       
     5  *    you may not use this file except in compliance with the License.
       
     6  *    You may obtain a copy of the License at
       
     7  * 
       
     8  *        http://www.apache.org/licenses/LICENSE-2.0
       
     9  * 
       
    10  *    Unless required by applicable law or agreed to in writing, software
       
    11  *    distributed under the License is distributed on an "AS IS" BASIS,
       
    12  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
       
    13  *    See the License for the specific language governing permissions and
       
    14  *    limitations under the License.
       
    15  */
       
    16 
       
    17 #ifdef HAVE_CONFIG_H
       
    18 #  include <dtn-config.h>
       
    19 #endif
       
    20 
       
    21 #include "Dictionary.h"
       
    22 #include <oasys/debug/Log.h>
       
    23 
       
    24 namespace dtn {
       
    25 
       
    26 //----------------------------------------------------------------------
       
    27 Dictionary::Dictionary()
       
    28     : dict_(NULL), dict_length_(0), length_(0)
       
    29 {
       
    30 }
       
    31 
       
    32 //----------------------------------------------------------------------
       
    33 Dictionary::Dictionary(const oasys::Builder&)
       
    34     : dict_(NULL), dict_length_(0), length_(0)
       
    35 {
       
    36 }
       
    37 
       
    38 //----------------------------------------------------------------------
       
    39 Dictionary::~Dictionary()
       
    40 {
       
    41     if (dict_) {
       
    42         free(dict_);
       
    43         dict_ = 0;
       
    44         dict_length_ = 0;
       
    45         length_ = 0;
       
    46     }
       
    47 }
       
    48 
       
    49 //----------------------------------------------------------------------
       
    50 void
       
    51 Dictionary::set_dict(const u_char* dict, u_int32_t length)
       
    52 {
       
    53     ASSERT(dict_ == NULL);
       
    54     dict_ = (u_char*)malloc(length);
       
    55     memcpy(dict_, dict, length);
       
    56     length_ = dict_length_ = length;
       
    57 }
       
    58 
       
    59 //----------------------------------------------------------------------
       
    60 bool
       
    61 Dictionary::get_offset(const std::string& str, u_int32_t* offset)
       
    62 {
       
    63     *offset = 0;
       
    64     while (*offset < length_) {
       
    65         u_int32_t len = strlen((char*)(&dict_[*offset]));
       
    66         if (!strncmp(str.c_str(), (char*)(&dict_[*offset]), len)) {
       
    67             if (str.length() == len) {
       
    68                 return true; // already there
       
    69             }
       
    70         }
       
    71         *offset += (len + 1);
       
    72         ASSERT(*offset <= length_);
       
    73     }
       
    74 
       
    75     return false;
       
    76 }
       
    77     
       
    78 //----------------------------------------------------------------------
       
    79 bool
       
    80 Dictionary::get_offset(const std::string& str, u_int64_t* offset)
       
    81 {
       
    82     *offset = 0;
       
    83     while (*offset < length_) {
       
    84         u_int64_t len = strlen((char*)(&dict_[*offset]));
       
    85         if (!strncmp(str.c_str(), (char*)(&dict_[*offset]), len)) {
       
    86             if (str.length() == len) {
       
    87                 return true; // already there
       
    88             }
       
    89         }
       
    90         *offset += (len + 1);
       
    91         ASSERT(*offset <= length_);
       
    92     }
       
    93 
       
    94     return false;
       
    95 }
       
    96     
       
    97 //----------------------------------------------------------------------
       
    98 void
       
    99 Dictionary::add_str(const std::string& str)
       
   100 {
       
   101     u_int32_t offset;
       
   102     if (get_offset(str, &offset)) {
       
   103         return;
       
   104     }
       
   105     
       
   106     if (dict_length_ < length_ + str.length() + 1) {
       
   107         do {
       
   108             dict_length_ = (dict_length_ == 0) ? 64 : dict_length_ * 2;
       
   109         } while (dict_length_ < length_ + str.length() + 1);
       
   110         
       
   111         dict_ = (u_char*)realloc(dict_, dict_length_);
       
   112     }
       
   113 
       
   114     memcpy(&dict_[length_], str.data(), str.length());
       
   115     dict_[length_ + str.length()] = '\0';
       
   116     length_ += str.length() + 1;
       
   117 }
       
   118 
       
   119 
       
   120 //----------------------------------------------------------------------
       
   121 void
       
   122 Dictionary::serialize(oasys::SerializeAction* a)
       
   123 {
       
   124     a->process("dict", dict_, length_);
       
   125     a->process("dict_length", &dict_length_);
       
   126     a->process("length", &length_);
       
   127 }
       
   128 
       
   129 //----------------------------------------------------------------------
       
   130 bool
       
   131 Dictionary::extract_eid(EndpointID* eid,
       
   132                         u_int32_t scheme_offset,
       
   133                         u_int32_t ssp_offset)
       
   134 {
       
   135     static const char* log = "/dtn/bundle/protocol";
       
   136 
       
   137     // If there's nothing in the dictionary, return
       
   138     if (dict_length_ == 0) {
       
   139         log_err_p(log, "cannot extract eid from zero-length dictionary");
       
   140         return false;
       
   141     }    
       
   142 
       
   143     if (scheme_offset >= (dict_length_ - 1)) {
       
   144 	log_err_p(log, "illegal offset for scheme dictionary offset: "
       
   145                   "offset %d, total length %u",
       
   146                   scheme_offset, dict_length_);
       
   147 	return false;
       
   148     }
       
   149 
       
   150     if (ssp_offset >= (dict_length_ - 1)) {
       
   151 	log_err_p(log, "illegal offset for ssp dictionary offset: "
       
   152                   "offset %d, total length %u",
       
   153                   ssp_offset, dict_length_);
       
   154 	return false;
       
   155     }
       
   156     
       
   157     eid->assign((char*)&dict_[scheme_offset],
       
   158                 (char*)&dict_[ssp_offset]);
       
   159 
       
   160     if (! eid->valid()) {
       
   161 	log_err_p(log, "invalid endpoint id '%s': "
       
   162                   "scheme '%s' offset %u/%u ssp '%s' offset %u/%u",
       
   163                   eid->c_str(),
       
   164                   eid->scheme_str().c_str(),
       
   165                   scheme_offset, dict_length_,
       
   166                   eid->ssp().c_str(),
       
   167                   ssp_offset, dict_length_);
       
   168         return false;                                                      
       
   169     }                                                                   
       
   170     
       
   171     log_debug_p(log, "parsed eid (offsets %u, %u) %s", 
       
   172                 scheme_offset, ssp_offset, eid->c_str());
       
   173     return true;
       
   174 }
       
   175 
       
   176 //----------------------------------------------------------------------
       
   177 bool
       
   178 Dictionary::extract_eid(EndpointID* eid,
       
   179                         u_int64_t scheme_offset,
       
   180                         u_int64_t ssp_offset)
       
   181 {
       
   182 	u_int32_t scheme_offset32 = scheme_offset;
       
   183 	u_int32_t ssp_offset32 = ssp_offset;
       
   184 	
       
   185 	return extract_eid(eid, scheme_offset32, ssp_offset32);
       
   186 }
       
   187 
       
   188 #if 0
       
   189 // the routines here are slightly different from those
       
   190 // in PrimaryBlockProcessor.cc although the functionality
       
   191 // appears to be the same
       
   192 ///XXX-pl TODO check to see
       
   193 
       
   194 //----------------------------------------------------------------------
       
   195 void
       
   196 PrimaryBlockProcessor::get_dictionary_offsets(DictionaryVector *dict,
       
   197                                               const EndpointID& eid,
       
   198                                               u_int16_t* scheme_offset,
       
   199                                               u_int16_t* ssp_offset)
       
   200 {
       
   201     DictionaryVector::iterator iter;
       
   202     for (iter = dict->begin(); iter != dict->end(); ++iter) {
       
   203 	if (iter->str == eid.scheme_str())
       
   204 	    *scheme_offset = htons(iter->offset);
       
   205 
       
   206 	if (iter->str == eid.ssp())
       
   207 	    *ssp_offset = htons(iter->offset);
       
   208     }
       
   209 }
       
   210 
       
   211 //----------------------------------------------------------------------
       
   212 bool
       
   213 PrimaryBlockProcessor::extract_dictionary_eid(EndpointID* eid,
       
   214                                               const char* what,
       
   215                                               u_int16_t* scheme_offsetp,
       
   216                                               u_int16_t* ssp_offsetp,
       
   217                                               u_char* dictionary,
       
   218                                               u_int32_t dictionary_len)
       
   219 {
       
   220     static const char* log = "/dtn/bundle/protocol";
       
   221     u_int16_t scheme_offset, ssp_offset;
       
   222     memcpy(&scheme_offset, scheme_offsetp, 2);
       
   223     memcpy(&ssp_offset, ssp_offsetp, 2);
       
   224     scheme_offset = ntohs(scheme_offset);
       
   225     ssp_offset = ntohs(ssp_offset);
       
   226 
       
   227     if (scheme_offset >= (dictionary_len - 1)) {
       
   228 	log_err_p(log, "illegal offset for %s scheme dictionary offset: "
       
   229                   "offset %d, total length %u", what,
       
   230                   scheme_offset, dictionary_len);
       
   231 	return false;
       
   232     }
       
   233 
       
   234     if (ssp_offset >= (dictionary_len - 1)) {
       
   235 	log_err_p(log, "illegal offset for %s ssp dictionary offset: "
       
   236                   "offset %d, total length %u", what,
       
   237                   ssp_offset, dictionary_len);
       
   238 	return false;
       
   239     }
       
   240     
       
   241     eid->assign((char*)&dictionary[scheme_offset],
       
   242                 (char*)&dictionary[ssp_offset]);
       
   243 
       
   244     if (! eid->valid()) {
       
   245 	log_err_p(log, "invalid %s endpoint id '%s': "
       
   246                   "scheme '%s' offset %u/%u ssp '%s' offset %u/%u",
       
   247                   what, eid->c_str(),
       
   248                   eid->scheme_str().c_str(),
       
   249                   scheme_offset, dictionary_len,
       
   250                   eid->ssp().c_str(),
       
   251                   ssp_offset, dictionary_len);
       
   252         return false;                                                      
       
   253     }                                                                   
       
   254     
       
   255     log_debug_p(log, "parsed %s eid (offsets %u, %u) %s", 
       
   256                 what, scheme_offset, ssp_offset, eid->c_str());
       
   257     return true;
       
   258 }
       
   259 
       
   260 //----------------------------------------------------------------------
       
   261 void
       
   262 PrimaryBlockProcessor::debug_dump_dictionary(const char* bp, u_int32_t len,
       
   263                                              PrimaryBlock2* primary2)
       
   264 {
       
   265 #ifndef NDEBUG
       
   266     oasys::StringBuffer dict_copy;
       
   267 
       
   268     const char* end = bp + len;
       
   269     ASSERT(end[-1] == '\0');
       
   270     
       
   271     while (bp != end) {
       
   272         dict_copy.appendf("%s ", bp);
       
   273         bp += strlen(bp) + 1;
       
   274     }
       
   275 
       
   276     log_debug_p("/dtn/bundle/protocol",
       
   277                 "dictionary len %zu, value: '%s'", len, dict_copy.c_str());
       
   278                   
       
   279     log_debug_p("/dtn/bundle/protocol",
       
   280                 "dictionary offsets: dest %u,%u source %u,%u, "
       
   281                 "custodian %u,%u replyto %u,%u",
       
   282                 ntohs(primary2->dest_scheme_offset),
       
   283                 ntohs(primary2->dest_ssp_offset),
       
   284                 ntohs(primary2->source_scheme_offset),
       
   285                 ntohs(primary2->source_ssp_offset),
       
   286                 ntohs(primary2->custodian_scheme_offset),
       
   287                 ntohs(primary2->custodian_ssp_offset),
       
   288                 ntohs(primary2->replyto_scheme_offset),
       
   289                 ntohs(primary2->replyto_ssp_offset));
       
   290 #else
       
   291     (void)bp;
       
   292     (void)len;
       
   293     (void)primary2;
       
   294 #endif
       
   295 }
       
   296 #endif /* zero */
       
   297 
       
   298 } // namespace dtn