servlib/bundling/BPQBlock.cc
changeset 55 1938118cd06c
parent 53 ed28624b4b7a
child 64 1296a0283271
--- a/servlib/bundling/BPQBlock.cc	Mon Aug 22 15:28:21 2011 +0100
+++ b/servlib/bundling/BPQBlock.cc	Thu Sep 01 15:53:24 2011 +0100
@@ -53,6 +53,7 @@
     log_info_p(LOG, "leaving constructor");
 }
 
+//----------------------------------------------------------------------
 BPQBlock::BPQBlock(BlockInfo* block)
 {
     log_info_p(LOG, "BPQBlock::constructor()");
@@ -64,6 +65,7 @@
     log_info_p(LOG, "leaving constructor");
 }
 
+//----------------------------------------------------------------------
 BPQBlock::~BPQBlock()
 {
     log_info_p(LOG, "BPQBlock: destructor");
@@ -72,38 +74,8 @@
         query_val_ = NULL;
     }
 }
-/*
-int 
-BPQBlock::format(char* buf, size_t sz) const
-{
-    if ( kind_ == KIND_QUERY ) {
-        return snprintf (buf, sz, "BPQ Query [%s] Matching Rule [%d]",
-                         query_val_,
-                         matching_rule_);
-    } else if ( kind_ == KIND_RESPONSE ) {
-        return snprintf (buf, sz, "BPQ Response [%s] Matching Rule [%d]",
-                         query_val_,
-                         matching_rule_);
-    } else
-        return snprintf (buf, sz, "INVALID BPQ KIND [%d]", kind_);
-    }
-}
 
-void
-BPQBlock::format_verbose(oasys::StringBuffer* buf) const
-{
-    if ( kind_ == KIND_QUERY )
-        buf->appendf("     BPQ Query:\n");
-    else if ( kind_ == KIND_RESPONSE )
-        buf->appendf("   BPQ Response:\n");
-
-    buf->appendf("Matching Rule: %d\n", matching_rule_);
-    buf->appendf(" Query Length: %d\n", query_len_);
-    buf->appendf("  Query Value: %s\n", query_val_);
-    buf->appendf("\n");
-
-}
-*/
+//----------------------------------------------------------------------
 int
 BPQBlock::write_to_buffer(u_char* buf, size_t len)
 {
@@ -123,7 +95,6 @@
         return -1;
 
     // query-length         SDNV
-    // todo: check this len -i is correct
     if ( i < len &&
         (encoding_len = SDNV::encode (query_len_, &(buf[i]), len -i)) >= 0 ) {
         i += encoding_len;
@@ -136,18 +107,44 @@
     for (j=0; query_val_ != NULL && i < len && j < query_len_; i++, j++)
         buf[i] = query_val_[j];    
 
-    // todo: Still need to handle fragments
+    // fragment-length		SDNV
     if ( i < len &&
-        (encoding_len = SDNV::encode (0, &(buf[i]), len -i)) >= 0 ) {
+        (encoding_len = SDNV::encode (frag_len(), &(buf[i]), len -i)) >= 0 ) {
         i += encoding_len;
     } else {
         log_err_p(LOG, "Error encoding _BPQ fragment length");
         return -1;
     }
 
+    // fragment-values		SDNV
+    BPQFragmentVec::const_iterator iter;
+    for (iter  = fragments_.begin();
+    	 iter != fragments_.end();
+    	 ++iter) {
+
+        if ( i < len &&
+            (encoding_len = SDNV::encode (iter->offset(), &(buf[i]), len -i)) >= 0 ) {
+            i += encoding_len;
+        } else {
+            log_err_p(LOG, "Error encoding _BPQ individual fragment offset");
+            return -1;
+        }
+
+        if ( i < len &&
+            (encoding_len = SDNV::encode (iter->length(), &(buf[i]), len -i)) >= 0 ) {
+            i += encoding_len;
+        } else {
+            log_err_p(LOG, "Error encoding _BPQ individual fragment length");
+            return -1;
+        }
+    }
+
+    ASSERT ( i == this->length())
+
     return i;
 }
 
+//----------------------------------------------------------------------
 u_int
 BPQBlock::length() const
 {
@@ -156,10 +153,21 @@
         
     len += SDNV::encoding_len(query_len_);
     len += query_len_;
-    len += SDNV::encoding_len(0); // todo: frag len
+    len += SDNV::encoding_len(frag_len());
+
+    BPQFragmentVec::const_iterator iter;
+	for (iter  = fragments_.begin();
+		 iter != fragments_.end();
+		 ++iter) {
+
+		len += SDNV::encoding_len(iter->offset());
+		len += SDNV::encoding_len(iter->length());
+	}
+
     return len;
 }
 
+//----------------------------------------------------------------------
 bool
 BPQBlock::match(const BPQBlock* other) const
 {
@@ -168,13 +176,21 @@
                      query_len_ ) == 0;
 }
 
+//----------------------------------------------------------------------
 int
 BPQBlock::initialise(BlockInfo* b)
 {
     ASSERT ( b != NULL);
 
+    int decoding_len=0;
+	u_int i=0, j=0, offset=0, length=0, full_len=0;
+	u_int frag_count=0, frag_off=0, frag_len=0;
+	u_char* buf = 0;
     BlockInfo* block = b;
 
+    /**************************************************************************
+     * Begin extracting block length with lots of logging
+     *************************************************************************/
     log_debug_p(LOG, "block: data_length() = %d", block->data_length());
     log_debug_p(LOG, "block: data_offset() = %d", block->data_offset());
     log_debug_p(LOG, "block: full_length() = %d", block->full_length());
@@ -184,7 +200,6 @@
     log_debug_p(LOG, "block: reloaded() = %s",
         (block->reloaded()) ? "true" : "false" );
 
-
     if ( b->source() != NULL ) {
         BlockInfo* block_src = const_cast<BlockInfo*>(b->source());;
 
@@ -198,126 +213,121 @@
             (block_src->reloaded()) ? "true" : "false" );
     }
 
-/*
 
-
-
-    BlockInfo* block = NULL;
-
-    if ( b->source() != NULL ) {
-        block = const_cast<BlockInfo*>(b->source());
-        log_debug_p(LOG, "BPQBlock::initialise: b->source() != NULL");
-    } else {
-        log_debug_p(LOG, "BPQBlock::initialise: b->source() == NULL");
-        block = b;
-    }
-*/
-    int decoding_len=0; 
-    u_int i=0, j=0, offset=0, len=0, flen=0, num_frags=0;
-    u_char* buf = 0;
- /*
-/////////////////////////////////////////////////////
-    ASSERT ( block != NULL );
-//    ASSERT ( block->data() != NULL );
+    offset = block->data_offset();
+    length = block->data_length();
+    full_len = block->full_length();
 
-    log_debug_p(LOG, "BPQBlock::initialise: block != NULL");
-    log_debug_p(LOG, "BPQBlock::initialise: block->data() != NULL"); 
+    if ( full_len != offset + length ) {
+        log_err_p(LOG, "BPQBlock::initialise: full_len != offset + length");
+    }
 
-    log_debug_p(LOG, "BPQBlock::initialise: data_length() = %d", block->data_length());
-    log_debug_p(LOG, "BPQBlock::initialise: data_offset() = %d", block->data_offset());
-    log_debug_p(LOG, "BPQBlock::initialise: full_length() = %d", block->full_length());
-    log_debug_p(LOG, "BPQBlock::initialise: complete() = %s", 
-        (block->complete()) ? "true" : "false" );
-    log_debug_p(LOG, "BPQBlock::initialise: reloaded() = %s", 
-        (block->reloaded()) ? "true" : "false" );
-////////////////////////////////////////////////////
-*/
-    log_debug_p(LOG, "BPQBlock::initialise: extracting offset");
-    offset = block->data_offset();
-    log_debug_p(LOG, "BPQBlock::initialise: extracting full len");
-    flen = block->full_length();
-    log_debug_p(LOG, "BPQBlock::initialise: extracting len");
-    len = block->data_length();
-
-    if ( flen != offset + len ) {
-        log_err_p(LOG, "BPQBlock::initialise: flen != offset + len");
-    }
-    if ( block->writable_contents()->buf_len() < flen ){
-        log_err_p(LOG, "BPQBlock::initialise:  buf_len() < flen");
-        log_err_p(LOG, "BPQBlock::initialise:  buf_len() = %lu", 
+    if ( block->writable_contents()->buf_len() < full_len ){
+        log_err_p(LOG, "BPQBlock::initialise:  buf_len() < full_len");
+        log_err_p(LOG, "BPQBlock::initialise:  buf_len() = %zu",
             block->writable_contents()->buf_len());
 
-        log_debug_p(LOG, "BPQBlock::initialise: reserving space in buffer %lu",
-            flen);
-        block->writable_contents()->reserve(flen);
-        log_debug_p(LOG, "BPQBlock::initialise: new buf_len() = %lu",
+        log_debug_p(LOG, "BPQBlock::initialise: reserving space in buffer %zu",
+            full_len);
+
+        block->writable_contents()->reserve(full_len);
+        log_debug_p(LOG, "BPQBlock::initialise: new buf_len() = %zu",
             block->writable_contents()->buf_len());
     }
 
-    log_debug_p(LOG, "BPQBlock::initialise: extracting buf");
     buf = block->data();
 
+
     // BPQ Kind must be 0 or 1
     if ( *(block->data()) != 0 &&
          *(block->data()) != 1 ) {
-        log_err_p(LOG, "BPQBlock::initialise: block->data() = %c(should be 0|1)",
+        log_err_p(LOG, "BPQBlock::initialise: block->data() = %c (should be 0|1)",
             *(block->data()));
+        return BP_FAIL;
     }
 
+    /**************************************************************************
+     * Begin extracting block info
+     *************************************************************************/
+
     // BPQ-kind             1-byte
-    if ( i < len ) {
+    if ( i < length ) {
         log_debug_p(LOG, "BPQBlock::initialise: extracting kind");
         kind_ = (kind_t) buf[i++];
         log_debug_p(LOG, "BPQBlock::initialise: kind = %d", kind_);
+    } else {
+    	log_err_p(LOG, "Error decoding BPQ kind");
+    	return BP_FAIL;
     }
 
     // matching rule type   1-byte
-    if ( i < len ) {
+    if ( i < length ) {
         matching_rule_ = (u_int) buf[i++];
         log_debug_p(LOG, "BPQBlock::initialise: matching rule = %u", matching_rule_);
+    } else {
+    	log_err_p(LOG, "Error decoding BPQ matching rule");
+    	return BP_FAIL;
     }
 
-    if ( b->source() != NULL ) {
-        log_debug_p(LOG, "BPQBlock::initialise: b->source() != NULL and OK :)");
-    } 
-
-    // Decode the SDNV-encoded query length. Note that we need to know the length of the
-    // of the encoded value and provide some pointers to the encoded value along with
-    // where we want the decoded value (in this case, query_len_).
-    if ( i < len &&
-        (decoding_len = SDNV::decode(&(buf[i]), len - i, &query_len_)) >= 0 ) {
+    // query-len			SDNV
+    if ( i < length &&
+        (decoding_len = SDNV::decode(&(buf[i]), length - i, &query_len_)) >= 0 ) {
         i += decoding_len;
         log_debug_p(LOG, "BPQBlock::initialise: query len = %u", query_len_);
+    } else {
+        log_err_p(LOG, "Error decoding BPQ query length");
+        return BP_FAIL;
     }
-    else
-        log_err_p(LOG, "Error decoding BPQ query length");
 
     // query-value           n-bytes
-    if ( (i+query_len_) < len ) {
+    if ( (i+query_len_) < length ) {
         query_val_ = (u_char*) malloc ( sizeof(u_char) * query_len_ );
 
-        for (j=0; query_val_ != NULL && i < len && j < query_len_; i++, j++)
+        for (j=0; query_val_ != NULL && i < length && j < query_len_; i++, j++)
             query_val_[j] = buf[i];
 
         log_debug_p(LOG, "BPQBlock::initialise: query val = %s", query_val_);
 
     } else {
         query_val_ = NULL;
+        log_err_p(LOG, "Error extracting BPQ query value");
+        return BP_FAIL;
+    }
+
+    if ( i < length &&
+        (decoding_len = SDNV::decode(&(buf[i]), length - i, &frag_count)) >= 0 ) {
+        i += decoding_len;
+        log_debug_p(LOG, "BPQBlock::initialise: frag count = %u", frag_count);
+    } else {
+        log_err_p(LOG, "Error decoding BPQ fragment count");
+        return BP_FAIL;
     }
 
-    if ( i < len &&
-        (decoding_len = SDNV::decode(&(buf[i]), len - i, &num_frags)) >= 0 ) {
-        i += decoding_len;
-        log_debug_p(LOG, "BPQBlock::initialise: num frags = %u", num_frags);
-    }
-    else
-        log_err_p(LOG, "Error decoding BPQ fragment length");
+
+	for (j=0;  i < length && j < frag_count; j++) {
+
+		if ( (decoding_len = SDNV::decode(&(buf[i]), length - i, &frag_off)) >= 0 ) {
+			i += decoding_len;
+			log_debug_p(LOG, "BPQBlock::initialise: frag offset = %u", frag_off);
+		} else {
+			log_err_p(LOG, "Error decoding BPQ fragment offset");
+			return BP_FAIL;
+		}
 
-    // todo: Still need to handle fragments
-    // test assert - to be removed once we start handling fragments
-    //ASSERT ( num_frags == 0 );
-    if ( num_frags != 0 )
-        log_err_p(LOG, "Error BPQ fragment length = %d", num_frags);
+		if ( (decoding_len = SDNV::decode(&(buf[i]), length - i, &frag_len)) >= 0 ) {
+			i += decoding_len;
+			log_debug_p(LOG, "BPQBlock::initialise: frag length = %u", frag_len);
+		} else {
+			log_err_p(LOG, "Error decoding BPQ fragment length");
+			return BP_FAIL;
+		}
+
+
+		BPQFragment frag(frag_off, frag_len);
+		add_fragment(frag);
+	}
+
+
 
     return BP_SUCCESS;
 }