servlib/bundling/MetadataBlock.cc
changeset 0 2b3e5ec03512
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/servlib/bundling/MetadataBlock.cc	Thu Apr 21 14:57:45 2011 +0100
@@ -0,0 +1,369 @@
+/*
+ *    Copyright 2007 The MITRE Corporation
+ * 
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ * 
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ *
+ *    The US Government will not be charged any license fee and/or royalties
+ *    related to this software. Neither name of The MITRE Corporation; nor the
+ *    names of its contributors may be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ */
+
+#ifdef HAVE_CONFIG_H
+#  include <dtn-config.h>
+#endif
+
+#include <oasys/debug/Log.h>
+
+#include "MetadataBlock.h"
+#include "MetadataBlockProcessor.h"
+
+namespace dtn {
+
+unsigned int MetadataBlock::index_ = 0;
+
+//----------------------------------------------------------------------
+MetadataBlock::MetadataBlock(u_int64_t type, u_char* buf, u_int32_t len):
+    lock_("MetadataBlock"), id_(MetadataBlock::get_next_index()),
+    block_(NULL), generated_(true), error_(false),
+    source_id_(0), source_(false), flags_(0),
+    ontology_(type), metadata_(NULL), metadata_len_(0)
+{
+    if (len > 0) {
+        ASSERT(buf != NULL);
+        metadata_ = new u_char[len];
+        memcpy(metadata_, buf, len);
+        metadata_len_ = len;
+    }
+}
+
+//----------------------------------------------------------------------
+MetadataBlock::MetadataBlock(unsigned int source_id, u_int64_t type,
+                             u_char* buf, u_int32_t len):
+    lock_("MetadataBlock"), id_(MetadataBlock::get_next_index()),
+    block_(NULL), generated_(true), error_(false),
+    source_id_(source_id), source_(true), flags_(0),
+    ontology_(type), metadata_(NULL), metadata_len_(0)
+{
+    if (len > 0) {
+        ASSERT(buf != NULL);
+        metadata_ = new u_char[len];
+        memcpy(metadata_, buf, len);
+        metadata_len_ = len;
+    }
+}
+
+//----------------------------------------------------------------------
+MetadataBlock::MetadataBlock(const MetadataBlock& copy):
+    BP_Local(copy),
+    oasys::SerializableObject(copy),
+    lock_("MetadataBlock"), id_(copy.id_), block_(copy.block_),
+    generated_(copy.generated_), error_(copy.error_),
+    source_id_(copy.source_id_), source_(copy.source_),
+    ontology_(copy.ontology_), metadata_(NULL),
+    metadata_len_(0)
+{
+    if (copy.generated_ && (copy.metadata_len_ > 0)) {
+        ASSERT(copy.metadata_ != NULL);
+        metadata_ = new u_char[copy.metadata_len_];
+        memcpy(metadata_, copy.metadata_, copy.metadata_len_);
+        metadata_len_ = copy.metadata_len_;
+
+    } else {
+        metadata_     = copy.metadata_;
+        metadata_len_ = copy.metadata_len_;
+    }
+}
+
+//----------------------------------------------------------------------
+MetadataBlock::~MetadataBlock()
+{
+    outgoing_metadata_.clear();
+    if (generated_ && (metadata_ != NULL)) {
+        delete[] metadata_;
+        metadata_ = NULL;
+        metadata_len_ = 0;
+    }
+}
+
+//----------------------------------------------------------------------
+void
+MetadataBlock::set_flags(u_int64_t flags)
+{
+    ASSERT(generated_);
+    flags_ = flags;
+}
+
+//----------------------------------------------------------------------
+void
+MetadataBlock::set_metadata(u_char *buf, u_int32_t len)
+{
+    ASSERT(!generated_);
+
+    if (len > 0) {
+        ASSERT(buf != NULL);
+        metadata_ = buf;
+        metadata_len_ = len;
+    } else {
+        metadata_ = NULL;
+        metadata_len_ = 0;
+    }
+}
+
+//----------------------------------------------------------------------
+bool
+MetadataBlock::remove_outgoing_metadata(const LinkRef& link)
+{
+    static const char* log = "/dtn/bundle/protocol";
+
+    if (has_outgoing_metadata(link)) {
+        log_err_p(log, "MetadataBlock::remove_outgoing_metadata: "
+                       "outgoing metadata already exists for link");
+        return false;
+    }
+
+    outgoing_metadata_.push_back(OutgoingMetadata(link));
+    return true;
+}
+
+//----------------------------------------------------------------------
+bool
+MetadataBlock::modify_outgoing_metadata(const LinkRef& link,
+                                        u_char* buf, u_int32_t len)
+{
+    static const char* log = "/dtn/bundle/protocol";
+
+    if (has_outgoing_metadata(link)) {
+        log_err_p(log, "MetadataBlock::modify_outgoing_metadata: "
+                       "outgoing metadata already exists for link");
+        return false;
+    }
+
+    outgoing_metadata_.push_back(OutgoingMetadata(link, buf, len));
+    return true;
+}
+
+//----------------------------------------------------------------------
+bool
+MetadataBlock::metadata_removed(const LinkRef& link)
+{
+    OutgoingMetadata* metadata = find_outgoing_metadata(link);
+    if (metadata == NULL) {
+        return false;
+    }
+
+    return (metadata->remove());
+}
+
+//----------------------------------------------------------------------
+bool
+MetadataBlock::metadata_modified(const LinkRef& link)
+{
+    OutgoingMetadata* metadata = find_outgoing_metadata(link);
+    if ((metadata == NULL) || metadata->remove()) {
+        return false;
+    }
+    return true;
+}
+
+//----------------------------------------------------------------------
+bool
+MetadataBlock::metadata_modified(const LinkRef& link,
+                                 u_char** buf, u_int32_t& len)
+{
+    OutgoingMetadata* outgoing = find_outgoing_metadata(link);
+    if ((outgoing == NULL) || outgoing->remove()) {
+        return false;
+    }
+
+    *buf = outgoing->metadata();
+    len  = outgoing->metadata_len();
+    return true;
+}
+
+//----------------------------------------------------------------------
+void
+MetadataBlock::delete_outgoing_metadata(const LinkRef& link)
+{
+    std::vector<OutgoingMetadata>::iterator iter = outgoing_metadata_.begin();
+    for ( ; iter != outgoing_metadata_.end(); ++iter) {
+        if (iter->link() == link) {
+            outgoing_metadata_.erase(iter);
+            return;
+        }
+    }
+}
+
+//----------------------------------------------------------------------
+void
+MetadataBlock::operator=(const MetadataBlock& copy)
+{
+    if (&copy == this) {
+        return;
+    }
+
+    outgoing_metadata_.clear();
+    if (generated_ && (metadata_ != NULL)) {
+        delete[] metadata_;
+        metadata_ = NULL;
+        metadata_len_ = 0;
+    }
+
+    id_        = copy.id_;
+    block_     = copy.block_;
+    generated_ = copy.generated_;
+    error_     = copy.error_;
+    ontology_  = copy.ontology_;
+
+    if (copy.generated_ && (copy.metadata_len_ > 0)) {
+        ASSERT(copy.metadata_ != NULL);
+        metadata_ = new u_char[copy.metadata_len_];
+        memcpy(metadata_, copy.metadata_, copy.metadata_len_);
+        metadata_len_ = copy.metadata_len_;
+
+    } else {
+        metadata_     = copy.metadata_;
+        metadata_len_ = copy.metadata_len_;
+    }
+}
+
+//----------------------------------------------------------------------
+MetadataBlock::OutgoingMetadata *
+MetadataBlock::find_outgoing_metadata(const LinkRef& link)
+{
+    std::vector<OutgoingMetadata>::iterator iter = outgoing_metadata_.begin();
+    for ( ; iter != outgoing_metadata_.end(); ++iter) {
+        if (iter->link() == link) {
+            return &*iter;
+        }
+    }
+    return NULL;
+}
+
+//----------------------------------------------------------------------
+MetadataBlock::OutgoingMetadata::OutgoingMetadata(
+    const LinkRef& link, u_char* buf, u_int32_t len):
+    link_(link.object(), "OutgoingMetadata"), remove_(false),
+    metadata_(NULL), metadata_len_(0)
+{
+    if (len > 0) {
+        ASSERT(buf != NULL);
+        metadata_ = new u_char[len];
+        memcpy(metadata_, buf, len);
+        metadata_len_ = len;
+    }
+}
+
+//----------------------------------------------------------------------
+MetadataBlock::OutgoingMetadata::OutgoingMetadata(const OutgoingMetadata& copy):
+    link_(copy.link_.object(), "OutgoingMetadata"), remove_(copy.remove_),
+    metadata_(NULL), metadata_len_(0)
+{
+    if (copy.metadata_len_ > 0) {
+        ASSERT(copy.metadata_ != NULL);
+        metadata_ = new u_char[copy.metadata_len_];
+        memcpy(metadata_, copy.metadata_, copy.metadata_len_);
+        metadata_len_ = copy.metadata_len_;
+    }
+}
+
+//----------------------------------------------------------------------
+MetadataBlock::OutgoingMetadata::~OutgoingMetadata()
+{
+    if (metadata_ != NULL) {
+        delete[] metadata_;
+        metadata_ = NULL;
+        metadata_len_ = 0;
+    }
+}
+
+//----------------------------------------------------------------------
+void
+MetadataBlock::OutgoingMetadata::operator=(const OutgoingMetadata& copy)
+{
+    if (&copy == this) {
+        return;
+    }
+
+    if (metadata_ != NULL) {
+        delete[] metadata_;
+        metadata_ = NULL;
+        metadata_len_ = 0;
+    }
+
+    link_ = copy.link_;
+    remove_ = copy.remove_;
+
+    if (copy.metadata_len_ > 0) {
+        ASSERT(copy.metadata_ != NULL);
+        metadata_ = new u_char[copy.metadata_len_];
+        memcpy(metadata_, copy.metadata_, copy.metadata_len_);
+        metadata_len_ = copy.metadata_len_;
+    }
+}
+
+//----------------------------------------------------------------------
+LinkMetadataSet::Entry::Entry(const LinkRef& link):
+    blocks_(NULL), link_(link.object(), "LinkMetadataSet::Entry")
+{
+}
+
+//----------------------------------------------------------------------
+LinkMetadataSet::~LinkMetadataSet()
+{
+    for (iterator iter = entries_.begin(); iter != entries_.end(); ++iter) {
+        delete iter->blocks_;
+        iter->blocks_ = NULL;
+    }
+}
+
+//----------------------------------------------------------------------
+MetadataVec*
+LinkMetadataSet::create_blocks(const LinkRef& link)
+{
+    ASSERT(find_blocks(link) == NULL);
+    entries_.push_back(Entry(link));
+    entries_.back().blocks_ =
+        new MetadataVec(std::string("metadata for link ") +
+                        ((link == NULL) ? "(null link)" : link->name()));
+    return entries_.back().blocks_;
+}
+
+//----------------------------------------------------------------------
+MetadataVec*
+LinkMetadataSet::find_blocks(const LinkRef& link) const
+{
+    for (const_iterator iter = entries_.begin();
+         iter != entries_.end(); ++iter) {
+        if (iter->link_ == link) {
+            return iter->blocks_;
+        }
+    }
+    return NULL;
+}
+
+//----------------------------------------------------------------------
+void
+LinkMetadataSet::delete_blocks(const LinkRef& link)
+{
+    for (iterator iter = entries_.begin(); iter != entries_.end(); ++iter) {
+        if (iter->link_ == link) {
+            delete iter->blocks_;
+            iter->blocks_ = NULL;
+            entries_.erase(iter);
+            return;
+        }
+    }
+}
+
+} // namespace dtn