--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/servlib/bundling/BlockInfo.cc Thu Apr 21 14:57:45 2011 +0100
@@ -0,0 +1,283 @@
+/*
+ * Copyright 2006 Intel 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <dtn-config.h>
+#endif
+
+#include <oasys/debug/Log.h>
+#include "BlockInfo.h"
+#include "BlockProcessor.h"
+#include "APIBlockProcessor.h"
+#include "BundleProtocol.h"
+#include "SDNV.h"
+
+namespace dtn {
+
+//----------------------------------------------------------------------
+BlockInfo::BlockInfo(BlockProcessor* owner, const BlockInfo* source)
+ : SerializableObject(),
+ owner_(owner),
+ owner_type_(owner->block_type()),
+ source_(source),
+ eid_list_(),
+ contents_(),
+ locals_("BlockInfo constructor"),
+ data_length_(0),
+ data_offset_(0),
+ complete_(false),
+ reloaded_(false)
+{
+ eid_list_.clear();
+}
+
+//----------------------------------------------------------------------
+BlockInfo::BlockInfo(oasys::Builder& builder)
+ : SerializableObject(),
+ owner_(NULL),
+ owner_type_(0),
+ source_(NULL),
+ eid_list_(),
+ contents_(),
+ locals_("BlockInfo constructor"),
+ data_length_(0),
+ data_offset_(0),
+ complete_(false),
+ reloaded_(true)
+{
+ (void)builder;
+}
+
+//----------------------------------------------------------------------
+BlockInfo::BlockInfo(const BlockInfo &bi)
+ : SerializableObject(),
+ owner_(bi.owner_),
+ owner_type_(bi.owner_type_),
+ source_(bi.source_),
+ eid_list_(bi.eid_list_),
+ contents_(bi.contents_),
+ locals_(bi.locals_.object(), "BlockInfo copy constructor"),
+ data_length_(bi.data_length_),
+ data_offset_(bi.data_offset_),
+ complete_(bi.complete_),
+ reloaded_(bi.reloaded_)
+{
+}
+
+//----------------------------------------------------------------------
+BlockInfo::~BlockInfo()
+{
+}
+
+//----------------------------------------------------------------------
+void
+BlockInfo::set_locals(BP_Local* l)
+{
+ locals_ = l;
+}
+
+//----------------------------------------------------------------------
+int
+BlockInfo::type() const
+{
+ if (owner_->block_type() == BundleProtocol::PRIMARY_BLOCK) {
+ return BundleProtocol::PRIMARY_BLOCK;
+ }
+
+ if (contents_.len() == 0) {
+ if (owner_ != NULL)
+ return owner_->block_type();
+
+ return BundleProtocol::UNKNOWN_BLOCK;
+ }
+
+ u_char* data = contents_.buf();
+ (void)data;
+ if (owner_ != NULL)
+ ASSERT(contents_.buf()[0] == owner_->block_type()
+ || owner_->block_type() == BundleProtocol::UNKNOWN_BLOCK
+ || owner_->block_type() == BundleProtocol::API_EXTENSION_BLOCK);
+ return contents_.buf()[0];
+}
+
+//----------------------------------------------------------------------
+u_int64_t
+BlockInfo::flags() const
+{
+ if (type() == BundleProtocol::PRIMARY_BLOCK) {
+ return 0x0;
+ }
+
+ u_int64_t flags;
+ int sdnv_size = SDNV::decode(contents_.buf() + 1, contents_.len() - 1,
+ &flags);
+ ASSERT(sdnv_size > 0);
+ return flags;
+}
+
+//----------------------------------------------------------------------
+void
+BlockInfo::set_flag(u_int64_t flag)
+{
+ size_t sdnv_len = SDNV::encoding_len(flag);
+ ASSERT(contents_.len() >= 1 + sdnv_len);
+ SDNV::encode(flag, contents_.buf() + 1, sdnv_len);
+}
+
+//----------------------------------------------------------------------
+bool
+BlockInfo::last_block() const
+{
+ //check if it's too small to be flagged as last
+ if (contents_.len() < 2) {
+ return false;
+ }
+
+ u_int64_t flag = flags();
+ return ((flag & BundleProtocol::BLOCK_FLAG_LAST_BLOCK) != 0);
+}
+
+//----------------------------------------------------------------------
+void
+BlockInfo::serialize(oasys::SerializeAction* a)
+{
+ a->process("owner_type", &owner_type_);
+ if (a->action_code() == oasys::Serialize::UNMARSHAL) {
+ // need to re-assign the owner
+ if (owner_type_ == BundleProtocol::API_EXTENSION_BLOCK) {
+ owner_ = APIBlockProcessor::instance();
+ } else {
+ owner_ = BundleProtocol::find_processor(owner_type_);
+ }
+ }
+
+ u_int32_t length = contents_.len();
+ a->process("length", &length);
+
+ // when we're unserializing, we need to reserve space and set the
+ // length of the contents buffer before we write into it
+ if (a->action_code() == oasys::Serialize::UNMARSHAL) {
+ contents_.reserve(length);
+ contents_.set_len(length);
+ }
+
+ a->process("contents", contents_.buf(), length);
+ a->process("data_length", &data_length_);
+ a->process("data_offset", &data_offset_);
+ a->process("complete", &complete_);
+ a->process("eid_list", &eid_list_);
+}
+
+//----------------------------------------------------------------------
+BlockInfoVec::BlockInfoVec()
+ : oasys::SerializableVector<BlockInfo>(),
+ error_major_(0),
+ error_minor_(0),
+ error_debug_(0)
+{
+}
+
+//----------------------------------------------------------------------
+BlockInfo*
+BlockInfoVec::append_block(BlockProcessor* owner, const BlockInfo* source)
+{
+ push_back(BlockInfo(owner, source));
+ return &back();
+}
+
+//----------------------------------------------------------------------
+const BlockInfo*
+BlockInfoVec::find_block(u_int8_t type) const
+{
+ for (const_iterator iter = begin(); iter != end(); ++iter) {
+ if (iter->type() == type ||
+ iter->owner()->block_type() == type)
+ {
+ return &*iter;
+ }
+ }
+ return false;
+}
+
+//----------------------------------------------------------------------
+LinkBlockSet::Entry::Entry(const LinkRef& link)
+ : blocks_(NULL), link_(link.object(), "LinkBlockSet::Entry")
+{
+}
+
+//----------------------------------------------------------------------
+LinkBlockSet::~LinkBlockSet()
+{
+ for (iterator iter = entries_.begin();
+ iter != entries_.end();
+ ++iter)
+ {
+ delete iter->blocks_;
+ iter->blocks_ = 0;
+ }
+}
+
+//----------------------------------------------------------------------
+BlockInfoVec*
+LinkBlockSet::create_blocks(const LinkRef& link)
+{
+ oasys::ScopeLock l(lock_, "LinkBlockSet::create_blocks");
+
+ ASSERT(find_blocks(link) == NULL);
+ entries_.push_back(Entry(link));
+ entries_.back().blocks_ = new BlockInfoVec();
+ return entries_.back().blocks_;
+}
+
+//----------------------------------------------------------------------
+BlockInfoVec*
+LinkBlockSet::find_blocks(const LinkRef& link) const
+{
+ oasys::ScopeLock l(lock_, "LinkBlockSet::find_blocks");
+
+ for (const_iterator iter = entries_.begin();
+ iter != entries_.end();
+ ++iter)
+ {
+ if (iter->link_ == link) {
+ return iter->blocks_;
+ }
+ }
+ return NULL;
+}
+
+//----------------------------------------------------------------------
+void
+LinkBlockSet::delete_blocks(const LinkRef& link)
+{
+ oasys::ScopeLock l(lock_, "LinkBlockSet::delete_blocks");
+
+ for (iterator iter = entries_.begin();
+ iter != entries_.end();
+ ++iter)
+ {
+ if (iter->link_ == link) {
+ delete iter->blocks_;
+ entries_.erase(iter);
+ return;
+ }
+ }
+
+ PANIC("LinkBlockVec::delete_blocks: "
+ "no block vector for link *%p", link.object());
+}
+
+} // namespace dtn