servlib/bundling/BPQBlock.cc
changeset 55 1938118cd06c
parent 53 ed28624b4b7a
child 64 1296a0283271
equal deleted inserted replaced
54:4122c50abb39 55:1938118cd06c
    51     }
    51     }
    52 
    52 
    53     log_info_p(LOG, "leaving constructor");
    53     log_info_p(LOG, "leaving constructor");
    54 }
    54 }
    55 
    55 
       
    56 //----------------------------------------------------------------------
    56 BPQBlock::BPQBlock(BlockInfo* block)
    57 BPQBlock::BPQBlock(BlockInfo* block)
    57 {
    58 {
    58     log_info_p(LOG, "BPQBlock::constructor()");
    59     log_info_p(LOG, "BPQBlock::constructor()");
    59 
    60 
    60     ASSERT( block->type() == BundleProtocol::QUERY_EXTENSION_BLOCK);
    61     ASSERT( block->type() == BundleProtocol::QUERY_EXTENSION_BLOCK);
    62     initialise(block);
    63     initialise(block);
    63 
    64 
    64     log_info_p(LOG, "leaving constructor");
    65     log_info_p(LOG, "leaving constructor");
    65 }
    66 }
    66 
    67 
       
    68 //----------------------------------------------------------------------
    67 BPQBlock::~BPQBlock()
    69 BPQBlock::~BPQBlock()
    68 {
    70 {
    69     log_info_p(LOG, "BPQBlock: destructor");
    71     log_info_p(LOG, "BPQBlock: destructor");
    70     if ( query_val_ != NULL ){
    72     if ( query_val_ != NULL ){
    71         free(query_val_);
    73         free(query_val_);
    72         query_val_ = NULL;
    74         query_val_ = NULL;
    73     }
    75     }
    74 }
    76 }
    75 /*
    77 
    76 int 
    78 //----------------------------------------------------------------------
    77 BPQBlock::format(char* buf, size_t sz) const
       
    78 {
       
    79     if ( kind_ == KIND_QUERY ) {
       
    80         return snprintf (buf, sz, "BPQ Query [%s] Matching Rule [%d]",
       
    81                          query_val_,
       
    82                          matching_rule_);
       
    83     } else if ( kind_ == KIND_RESPONSE ) {
       
    84         return snprintf (buf, sz, "BPQ Response [%s] Matching Rule [%d]",
       
    85                          query_val_,
       
    86                          matching_rule_);
       
    87     } else
       
    88         return snprintf (buf, sz, "INVALID BPQ KIND [%d]", kind_);
       
    89     }
       
    90 }
       
    91 
       
    92 void
       
    93 BPQBlock::format_verbose(oasys::StringBuffer* buf) const
       
    94 {
       
    95     if ( kind_ == KIND_QUERY )
       
    96         buf->appendf("     BPQ Query:\n");
       
    97     else if ( kind_ == KIND_RESPONSE )
       
    98         buf->appendf("   BPQ Response:\n");
       
    99 
       
   100     buf->appendf("Matching Rule: %d\n", matching_rule_);
       
   101     buf->appendf(" Query Length: %d\n", query_len_);
       
   102     buf->appendf("  Query Value: %s\n", query_val_);
       
   103     buf->appendf("\n");
       
   104 
       
   105 }
       
   106 */
       
   107 int
    79 int
   108 BPQBlock::write_to_buffer(u_char* buf, size_t len)
    80 BPQBlock::write_to_buffer(u_char* buf, size_t len)
   109 {
    81 {
   110     int encoding_len=0; 
    82     int encoding_len=0; 
   111     u_int i=0, j=0;
    83     u_int i=0, j=0;
   121         buf[i++] = (u_char) matching_rule_;
    93         buf[i++] = (u_char) matching_rule_;
   122     else
    94     else
   123         return -1;
    95         return -1;
   124 
    96 
   125     // query-length         SDNV
    97     // query-length         SDNV
   126     // todo: check this len -i is correct
       
   127     if ( i < len &&
    98     if ( i < len &&
   128         (encoding_len = SDNV::encode (query_len_, &(buf[i]), len -i)) >= 0 ) {
    99         (encoding_len = SDNV::encode (query_len_, &(buf[i]), len -i)) >= 0 ) {
   129         i += encoding_len;
   100         i += encoding_len;
   130     } else {
   101     } else {
   131         log_err_p(LOG, "Error encoding _BPQ query length");
   102         log_err_p(LOG, "Error encoding _BPQ query length");
   134 
   105 
   135     // query-value           n-bytes
   106     // query-value           n-bytes
   136     for (j=0; query_val_ != NULL && i < len && j < query_len_; i++, j++)
   107     for (j=0; query_val_ != NULL && i < len && j < query_len_; i++, j++)
   137         buf[i] = query_val_[j];    
   108         buf[i] = query_val_[j];    
   138 
   109 
   139     // todo: Still need to handle fragments
   110     // fragment-length		SDNV
   140     if ( i < len &&
   111     if ( i < len &&
   141         (encoding_len = SDNV::encode (0, &(buf[i]), len -i)) >= 0 ) {
   112         (encoding_len = SDNV::encode (frag_len(), &(buf[i]), len -i)) >= 0 ) {
   142         i += encoding_len;
   113         i += encoding_len;
   143     } else {
   114     } else {
   144         log_err_p(LOG, "Error encoding _BPQ fragment length");
   115         log_err_p(LOG, "Error encoding _BPQ fragment length");
   145         return -1;
   116         return -1;
   146     }
   117     }
   147 
   118 
       
   119     // fragment-values		SDNV
       
   120     BPQFragmentVec::const_iterator iter;
       
   121     for (iter  = fragments_.begin();
       
   122     	 iter != fragments_.end();
       
   123     	 ++iter) {
       
   124 
       
   125         if ( i < len &&
       
   126             (encoding_len = SDNV::encode (iter->offset(), &(buf[i]), len -i)) >= 0 ) {
       
   127             i += encoding_len;
       
   128         } else {
       
   129             log_err_p(LOG, "Error encoding _BPQ individual fragment offset");
       
   130             return -1;
       
   131         }
       
   132 
       
   133         if ( i < len &&
       
   134             (encoding_len = SDNV::encode (iter->length(), &(buf[i]), len -i)) >= 0 ) {
       
   135             i += encoding_len;
       
   136         } else {
       
   137             log_err_p(LOG, "Error encoding _BPQ individual fragment length");
       
   138             return -1;
       
   139         }
       
   140     }
       
   141 
       
   142     ASSERT ( i == this->length())
       
   143 
   148     return i;
   144     return i;
   149 }
   145 }
   150 
   146 
       
   147 //----------------------------------------------------------------------
   151 u_int
   148 u_int
   152 BPQBlock::length() const
   149 BPQBlock::length() const
   153 {
   150 {
   154     // initial size {kind, matching rule}
   151     // initial size {kind, matching rule}
   155     u_int len = 2; 
   152     u_int len = 2; 
   156         
   153         
   157     len += SDNV::encoding_len(query_len_);
   154     len += SDNV::encoding_len(query_len_);
   158     len += query_len_;
   155     len += query_len_;
   159     len += SDNV::encoding_len(0); // todo: frag len
   156     len += SDNV::encoding_len(frag_len());
       
   157 
       
   158     BPQFragmentVec::const_iterator iter;
       
   159 	for (iter  = fragments_.begin();
       
   160 		 iter != fragments_.end();
       
   161 		 ++iter) {
       
   162 
       
   163 		len += SDNV::encoding_len(iter->offset());
       
   164 		len += SDNV::encoding_len(iter->length());
       
   165 	}
       
   166 
   160     return len;
   167     return len;
   161 }
   168 }
   162 
   169 
       
   170 //----------------------------------------------------------------------
   163 bool
   171 bool
   164 BPQBlock::match(const BPQBlock* other) const
   172 BPQBlock::match(const BPQBlock* other) const
   165 {
   173 {
   166     return query_len_ == other->query_len() &&
   174     return query_len_ == other->query_len() &&
   167            strncmp( (char*)query_val_, (char*)other->query_val(),
   175            strncmp( (char*)query_val_, (char*)other->query_val(),
   168                      query_len_ ) == 0;
   176                      query_len_ ) == 0;
   169 }
   177 }
   170 
   178 
       
   179 //----------------------------------------------------------------------
   171 int
   180 int
   172 BPQBlock::initialise(BlockInfo* b)
   181 BPQBlock::initialise(BlockInfo* b)
   173 {
   182 {
   174     ASSERT ( b != NULL);
   183     ASSERT ( b != NULL);
   175 
   184 
       
   185     int decoding_len=0;
       
   186 	u_int i=0, j=0, offset=0, length=0, full_len=0;
       
   187 	u_int frag_count=0, frag_off=0, frag_len=0;
       
   188 	u_char* buf = 0;
   176     BlockInfo* block = b;
   189     BlockInfo* block = b;
   177 
   190 
       
   191     /**************************************************************************
       
   192      * Begin extracting block length with lots of logging
       
   193      *************************************************************************/
   178     log_debug_p(LOG, "block: data_length() = %d", block->data_length());
   194     log_debug_p(LOG, "block: data_length() = %d", block->data_length());
   179     log_debug_p(LOG, "block: data_offset() = %d", block->data_offset());
   195     log_debug_p(LOG, "block: data_offset() = %d", block->data_offset());
   180     log_debug_p(LOG, "block: full_length() = %d", block->full_length());
   196     log_debug_p(LOG, "block: full_length() = %d", block->full_length());
   181     log_debug_p(LOG, "block: complete() = %s",
   197     log_debug_p(LOG, "block: complete() = %s",
   182         (block->complete()) ? "true" : "false" );
   198         (block->complete()) ? "true" : "false" );
   183 
   199 
   184     log_debug_p(LOG, "block: reloaded() = %s",
   200     log_debug_p(LOG, "block: reloaded() = %s",
   185         (block->reloaded()) ? "true" : "false" );
   201         (block->reloaded()) ? "true" : "false" );
   186 
       
   187 
   202 
   188     if ( b->source() != NULL ) {
   203     if ( b->source() != NULL ) {
   189         BlockInfo* block_src = const_cast<BlockInfo*>(b->source());;
   204         BlockInfo* block_src = const_cast<BlockInfo*>(b->source());;
   190 
   205 
   191         log_debug_p(LOG, "block_src: data_length() = %d", block_src->data_length());
   206         log_debug_p(LOG, "block_src: data_length() = %d", block_src->data_length());
   196     
   211     
   197         log_debug_p(LOG, "block_src: reloaded() = %s",
   212         log_debug_p(LOG, "block_src: reloaded() = %s",
   198             (block_src->reloaded()) ? "true" : "false" );
   213             (block_src->reloaded()) ? "true" : "false" );
   199     }
   214     }
   200 
   215 
   201 /*
   216 
   202 
       
   203 
       
   204 
       
   205     BlockInfo* block = NULL;
       
   206 
       
   207     if ( b->source() != NULL ) {
       
   208         block = const_cast<BlockInfo*>(b->source());
       
   209         log_debug_p(LOG, "BPQBlock::initialise: b->source() != NULL");
       
   210     } else {
       
   211         log_debug_p(LOG, "BPQBlock::initialise: b->source() == NULL");
       
   212         block = b;
       
   213     }
       
   214 */
       
   215     int decoding_len=0; 
       
   216     u_int i=0, j=0, offset=0, len=0, flen=0, num_frags=0;
       
   217     u_char* buf = 0;
       
   218  /*
       
   219 /////////////////////////////////////////////////////
       
   220     ASSERT ( block != NULL );
       
   221 //    ASSERT ( block->data() != NULL );
       
   222 
       
   223     log_debug_p(LOG, "BPQBlock::initialise: block != NULL");
       
   224     log_debug_p(LOG, "BPQBlock::initialise: block->data() != NULL"); 
       
   225 
       
   226     log_debug_p(LOG, "BPQBlock::initialise: data_length() = %d", block->data_length());
       
   227     log_debug_p(LOG, "BPQBlock::initialise: data_offset() = %d", block->data_offset());
       
   228     log_debug_p(LOG, "BPQBlock::initialise: full_length() = %d", block->full_length());
       
   229     log_debug_p(LOG, "BPQBlock::initialise: complete() = %s", 
       
   230         (block->complete()) ? "true" : "false" );
       
   231     log_debug_p(LOG, "BPQBlock::initialise: reloaded() = %s", 
       
   232         (block->reloaded()) ? "true" : "false" );
       
   233 ////////////////////////////////////////////////////
       
   234 */
       
   235     log_debug_p(LOG, "BPQBlock::initialise: extracting offset");
       
   236     offset = block->data_offset();
   217     offset = block->data_offset();
   237     log_debug_p(LOG, "BPQBlock::initialise: extracting full len");
   218     length = block->data_length();
   238     flen = block->full_length();
   219     full_len = block->full_length();
   239     log_debug_p(LOG, "BPQBlock::initialise: extracting len");
   220 
   240     len = block->data_length();
   221     if ( full_len != offset + length ) {
   241 
   222         log_err_p(LOG, "BPQBlock::initialise: full_len != offset + length");
   242     if ( flen != offset + len ) {
   223     }
   243         log_err_p(LOG, "BPQBlock::initialise: flen != offset + len");
   224 
   244     }
   225     if ( block->writable_contents()->buf_len() < full_len ){
   245     if ( block->writable_contents()->buf_len() < flen ){
   226         log_err_p(LOG, "BPQBlock::initialise:  buf_len() < full_len");
   246         log_err_p(LOG, "BPQBlock::initialise:  buf_len() < flen");
   227         log_err_p(LOG, "BPQBlock::initialise:  buf_len() = %zu",
   247         log_err_p(LOG, "BPQBlock::initialise:  buf_len() = %lu", 
       
   248             block->writable_contents()->buf_len());
   228             block->writable_contents()->buf_len());
   249 
   229 
   250         log_debug_p(LOG, "BPQBlock::initialise: reserving space in buffer %lu",
   230         log_debug_p(LOG, "BPQBlock::initialise: reserving space in buffer %zu",
   251             flen);
   231             full_len);
   252         block->writable_contents()->reserve(flen);
   232 
   253         log_debug_p(LOG, "BPQBlock::initialise: new buf_len() = %lu",
   233         block->writable_contents()->reserve(full_len);
       
   234         log_debug_p(LOG, "BPQBlock::initialise: new buf_len() = %zu",
   254             block->writable_contents()->buf_len());
   235             block->writable_contents()->buf_len());
   255     }
   236     }
   256 
   237 
   257     log_debug_p(LOG, "BPQBlock::initialise: extracting buf");
       
   258     buf = block->data();
   238     buf = block->data();
       
   239 
   259 
   240 
   260     // BPQ Kind must be 0 or 1
   241     // BPQ Kind must be 0 or 1
   261     if ( *(block->data()) != 0 &&
   242     if ( *(block->data()) != 0 &&
   262          *(block->data()) != 1 ) {
   243          *(block->data()) != 1 ) {
   263         log_err_p(LOG, "BPQBlock::initialise: block->data() = %c(should be 0|1)",
   244         log_err_p(LOG, "BPQBlock::initialise: block->data() = %c (should be 0|1)",
   264             *(block->data()));
   245             *(block->data()));
   265     }
   246         return BP_FAIL;
       
   247     }
       
   248 
       
   249     /**************************************************************************
       
   250      * Begin extracting block info
       
   251      *************************************************************************/
   266 
   252 
   267     // BPQ-kind             1-byte
   253     // BPQ-kind             1-byte
   268     if ( i < len ) {
   254     if ( i < length ) {
   269         log_debug_p(LOG, "BPQBlock::initialise: extracting kind");
   255         log_debug_p(LOG, "BPQBlock::initialise: extracting kind");
   270         kind_ = (kind_t) buf[i++];
   256         kind_ = (kind_t) buf[i++];
   271         log_debug_p(LOG, "BPQBlock::initialise: kind = %d", kind_);
   257         log_debug_p(LOG, "BPQBlock::initialise: kind = %d", kind_);
       
   258     } else {
       
   259     	log_err_p(LOG, "Error decoding BPQ kind");
       
   260     	return BP_FAIL;
   272     }
   261     }
   273 
   262 
   274     // matching rule type   1-byte
   263     // matching rule type   1-byte
   275     if ( i < len ) {
   264     if ( i < length ) {
   276         matching_rule_ = (u_int) buf[i++];
   265         matching_rule_ = (u_int) buf[i++];
   277         log_debug_p(LOG, "BPQBlock::initialise: matching rule = %u", matching_rule_);
   266         log_debug_p(LOG, "BPQBlock::initialise: matching rule = %u", matching_rule_);
   278     }
   267     } else {
   279 
   268     	log_err_p(LOG, "Error decoding BPQ matching rule");
   280     if ( b->source() != NULL ) {
   269     	return BP_FAIL;
   281         log_debug_p(LOG, "BPQBlock::initialise: b->source() != NULL and OK :)");
   270     }
   282     } 
   271 
   283 
   272     // query-len			SDNV
   284     // Decode the SDNV-encoded query length. Note that we need to know the length of the
   273     if ( i < length &&
   285     // of the encoded value and provide some pointers to the encoded value along with
   274         (decoding_len = SDNV::decode(&(buf[i]), length - i, &query_len_)) >= 0 ) {
   286     // where we want the decoded value (in this case, query_len_).
       
   287     if ( i < len &&
       
   288         (decoding_len = SDNV::decode(&(buf[i]), len - i, &query_len_)) >= 0 ) {
       
   289         i += decoding_len;
   275         i += decoding_len;
   290         log_debug_p(LOG, "BPQBlock::initialise: query len = %u", query_len_);
   276         log_debug_p(LOG, "BPQBlock::initialise: query len = %u", query_len_);
   291     }
   277     } else {
   292     else
       
   293         log_err_p(LOG, "Error decoding BPQ query length");
   278         log_err_p(LOG, "Error decoding BPQ query length");
       
   279         return BP_FAIL;
       
   280     }
   294 
   281 
   295     // query-value           n-bytes
   282     // query-value           n-bytes
   296     if ( (i+query_len_) < len ) {
   283     if ( (i+query_len_) < length ) {
   297         query_val_ = (u_char*) malloc ( sizeof(u_char) * query_len_ );
   284         query_val_ = (u_char*) malloc ( sizeof(u_char) * query_len_ );
   298 
   285 
   299         for (j=0; query_val_ != NULL && i < len && j < query_len_; i++, j++)
   286         for (j=0; query_val_ != NULL && i < length && j < query_len_; i++, j++)
   300             query_val_[j] = buf[i];
   287             query_val_[j] = buf[i];
   301 
   288 
   302         log_debug_p(LOG, "BPQBlock::initialise: query val = %s", query_val_);
   289         log_debug_p(LOG, "BPQBlock::initialise: query val = %s", query_val_);
   303 
   290 
   304     } else {
   291     } else {
   305         query_val_ = NULL;
   292         query_val_ = NULL;
   306     }
   293         log_err_p(LOG, "Error extracting BPQ query value");
   307 
   294         return BP_FAIL;
   308     if ( i < len &&
   295     }
   309         (decoding_len = SDNV::decode(&(buf[i]), len - i, &num_frags)) >= 0 ) {
   296 
       
   297     if ( i < length &&
       
   298         (decoding_len = SDNV::decode(&(buf[i]), length - i, &frag_count)) >= 0 ) {
   310         i += decoding_len;
   299         i += decoding_len;
   311         log_debug_p(LOG, "BPQBlock::initialise: num frags = %u", num_frags);
   300         log_debug_p(LOG, "BPQBlock::initialise: frag count = %u", frag_count);
   312     }
   301     } else {
   313     else
   302         log_err_p(LOG, "Error decoding BPQ fragment count");
   314         log_err_p(LOG, "Error decoding BPQ fragment length");
   303         return BP_FAIL;
   315 
   304     }
   316     // todo: Still need to handle fragments
   305 
   317     // test assert - to be removed once we start handling fragments
   306 
   318     //ASSERT ( num_frags == 0 );
   307 	for (j=0;  i < length && j < frag_count; j++) {
   319     if ( num_frags != 0 )
   308 
   320         log_err_p(LOG, "Error BPQ fragment length = %d", num_frags);
   309 		if ( (decoding_len = SDNV::decode(&(buf[i]), length - i, &frag_off)) >= 0 ) {
       
   310 			i += decoding_len;
       
   311 			log_debug_p(LOG, "BPQBlock::initialise: frag offset = %u", frag_off);
       
   312 		} else {
       
   313 			log_err_p(LOG, "Error decoding BPQ fragment offset");
       
   314 			return BP_FAIL;
       
   315 		}
       
   316 
       
   317 		if ( (decoding_len = SDNV::decode(&(buf[i]), length - i, &frag_len)) >= 0 ) {
       
   318 			i += decoding_len;
       
   319 			log_debug_p(LOG, "BPQBlock::initialise: frag length = %u", frag_len);
       
   320 		} else {
       
   321 			log_err_p(LOG, "Error decoding BPQ fragment length");
       
   322 			return BP_FAIL;
       
   323 		}
       
   324 
       
   325 
       
   326 		BPQFragment frag(frag_off, frag_len);
       
   327 		add_fragment(frag);
       
   328 	}
       
   329 
       
   330 
   321 
   331 
   322     return BP_SUCCESS;
   332     return BP_SUCCESS;
   323 }
   333 }
   324 
   334 
   325 } // namespace dtn
   335 } // namespace dtn