--- /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 (© == 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 (© == 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