servlib/bundling/BPQBlock.cc
changeset 5 1849bf57d910
parent 4 c02ca5a6ab82
child 6 d1f220643814
--- a/servlib/bundling/BPQBlock.cc	Wed May 04 15:44:40 2011 +0100
+++ b/servlib/bundling/BPQBlock.cc	Fri May 27 18:33:25 2011 +0100
@@ -19,44 +19,195 @@
 #endif
 
 #include "BPQBlock.h"
+#include "Bundle.h"
+#include "BundleProtocol.h"
+#include "SDNV.h"
 
 namespace dtn {
 
+// Setup our logging information
+static const char* LOG = "/dtn/bundle/extblock/bpq";
+
+BPQBlock::BPQBlock(Bundle* bundle)
+{
+    log_info_p(LOG, "BPQBlock::constructor()");
+
+    if( bundle->recv_blocks().
+        has_block(BundleProtocol::QUERY_EXTENSION_BLOCK) ) {
+
+        log_debug_p(LOG, "BPQBlock found in Recv Block Vec => created remotly");
+        initialise( const_cast<BlockInfo*> (bundle->recv_blocks().
+                    find_block(BundleProtocol::QUERY_EXTENSION_BLOCK)) );
+
+    } else if( bundle->api_blocks()->
+               has_block(BundleProtocol::QUERY_EXTENSION_BLOCK) ) {
+
+        log_debug_p(LOG, "BPQBlock found in API Block Vec => created locally");
+        initialise( const_cast<BlockInfo*> (bundle->api_blocks()->
+                    find_block(BundleProtocol::QUERY_EXTENSION_BLOCK)) );
+
+    } else {
+        log_err_p(LOG, "BPQ Block not found in bundle");
+    }
+
+    log_info_p(LOG, "leaving constructor");
+}
+
 BPQBlock::BPQBlock(BlockInfo* block)
 {
-    static const char* log = "/dtn/bundle/protocol";
-    log_err_p(log, "BPQBlock: constructor");
-    
-    log_err_p(log, "block->data_length(): %d",block->data_length());
-    log_err_p(log, "block->data_offset(): %d",block->data_offset());
-    log_err_p(log, "block->full_length(): %d",block->full_length());
-
-
-    size_t len = block->writable_contents()->buf_len();
-    u_char*  buf = block->writable_contents()->buf(len);
+    log_info_p(LOG, "BPQBlock::constructor()");
 
-    size_t i=0;
-//, j=0, decoding_len=0;
+    initialise(block);
 
-    // BPQ-kind             1-byte
-    if (i<len) {
-        kind_ = (u_int) buf[i++];
-        log_err_p(log, "kind: %d",kind_);
-    }
-
-    // matching rule type   1-byte
-    if (i<len) {
-        matching_rule_ = (u_int) buf[i++];
-        log_err_p(log, "marching rule: %d",matching_rule_);
-    }
-    log_err_p(log, "leaving constructor");
+    log_info_p(LOG, "leaving constructor");
 }
 
 BPQBlock::~BPQBlock()
 {
-    static const char* log = "/dtn/bundle/protocol";
-    log_err_p(log, "BPQBlock: destructor");
+    log_info_p(LOG, "BPQBlock: destructor");
+//TODO
+/*
+    if ( query_val_ != NULL ){
+        free(query_val_);
+        query_val_ = NULL;
+    }
+*/
+}
+
+int
+BPQBlock::write_to_buffer(u_char* buf, size_t len)
+{
+    int encoding_len=0; 
+    u_int i=0, j=0;
+
+    // BPQ-kind             1-byte
+    if ( i < len ) 
+        buf[i++] = (u_char) kind_;
+    else
+        return -1;
+
+    // matching rule type   1-byte
+    if ( i < len )
+        buf[i++] = (u_char) matching_rule_;
+    else
+        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;
+    } else {
+        log_err_p(LOG, "Error encoding _BPQ query length");
+        return -1;
+    }
+
+    // query-value           n-bytes
+    for (j=0; query_val_ != NULL && i < len && j < query_len_; i++, j++)
+        buf[i] = query_val_[j];    
+
+    // todo: Still need to handle fragments
+    if ( i < len &&
+        (encoding_len = SDNV::encode (0, &(buf[i]), len -i)) >= 0 ) {
+        i += encoding_len;
+    } else {
+        log_err_p(LOG, "Error encoding _BPQ fragment length");
+        return -1;
+    }
+
+    return i;
+}
+
+u_int
+BPQBlock::length() const
+{
+    // initial size {kind, matching rule}
+    u_int len = 2; 
+        
+    len += SDNV::encoding_len(query_len_);
+    len += query_len_;
+    len += SDNV::encoding_len(0); // todo: frag len
+    return len;
 }
 
+bool
+BPQBlock::match(BPQBlock* other) const
+{
+    log_debug_p(LOG, "_BPQ_ Match: this(%s) other(%s)",
+            (char*)query_val_,
+            (char*)other->query_val());
+
+    return query_len_ == other->query_len() &&
+           strncmp( (char*)query_val_, (char*)other->query_val(),
+                     query_len_ ) == 0;
+}
+
+int
+BPQBlock::initialise(BlockInfo* block)
+{
+    int decoding_len=0; 
+    u_int i=0, j=0;
+    u_int len = block->data_length();
+    u_int num_frags;
+    u_char* buf = block->data();
+
+    // BPQ-kind             1-byte
+    if ( i < len )
+        kind_ = (kind_t) buf[i++];
+
+    // matching rule type   1-byte
+    if ( i < len )
+        matching_rule_ = (u_int) buf[i++];
+
+    // 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 )
+        i += decoding_len;
+    else
+        log_err_p(LOG, "Error decoding BPQ query length");
+
+    // query-value           n-bytes
+    if ( (i+query_len_) < len ) {
+        query_val_ = (u_char*) malloc ( sizeof(u_char) * query_len_ );
+
+        for (j=0; query_val_ != NULL && i < len && j < query_len_; i++, j++)
+            query_val_[j] = buf[i];
+
+    } else {
+        query_val_ = NULL;
+    }
+
+    if ( i < len &&
+        (decoding_len = SDNV::decode(&(buf[i]), len - i, &num_frags)) >= 0 )
+        i += decoding_len;
+    else
+        log_err_p(LOG, "Error decoding BPQ fragment length");
+
+    // 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);
+
+    return BP_SUCCESS;
+}
 
 } // namespace dtn
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+