00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifdef HAVE_CONFIG_H
00018 # include <dtn-config.h>
00019 #endif
00020
00021 #include <oasys/debug/Log.h>
00022 #include "BlockInfo.h"
00023 #include "BlockProcessor.h"
00024 #include "APIBlockProcessor.h"
00025 #include "BundleProtocol.h"
00026 #include "SDNV.h"
00027
00028 namespace dtn {
00029
00030
00031 BlockInfo::BlockInfo(BlockProcessor* owner, const BlockInfo* source)
00032 : SerializableObject(),
00033 owner_(owner),
00034 owner_type_(owner->block_type()),
00035 source_(source),
00036 eid_list_(),
00037 contents_(),
00038 locals_("BlockInfo constructor"),
00039 data_length_(0),
00040 data_offset_(0),
00041 complete_(false),
00042 reloaded_(false)
00043 {
00044 eid_list_.clear();
00045 }
00046
00047
00048 BlockInfo::BlockInfo(oasys::Builder& builder)
00049 : SerializableObject(),
00050 owner_(NULL),
00051 owner_type_(0),
00052 source_(NULL),
00053 eid_list_(),
00054 contents_(),
00055 locals_("BlockInfo constructor"),
00056 data_length_(0),
00057 data_offset_(0),
00058 complete_(false),
00059 reloaded_(true)
00060 {
00061 (void)builder;
00062 }
00063
00064
00065 BlockInfo::BlockInfo(const BlockInfo &bi)
00066 : SerializableObject(),
00067 owner_(bi.owner_),
00068 owner_type_(bi.owner_type_),
00069 source_(bi.source_),
00070 eid_list_(bi.eid_list_),
00071 contents_(bi.contents_),
00072 locals_(bi.locals_.object(), "BlockInfo copy constructor"),
00073 data_length_(bi.data_length_),
00074 data_offset_(bi.data_offset_),
00075 complete_(bi.complete_),
00076 reloaded_(bi.reloaded_)
00077 {
00078 }
00079
00080
00081 BlockInfo::~BlockInfo()
00082 {
00083 }
00084
00085
00086 void
00087 BlockInfo::set_locals(BP_Local* l)
00088 {
00089 locals_ = l;
00090 }
00091
00092
00093 int
00094 BlockInfo::type() const
00095 {
00096 if (owner_->block_type() == BundleProtocol::PRIMARY_BLOCK) {
00097 return BundleProtocol::PRIMARY_BLOCK;
00098 }
00099
00100 if (contents_.len() == 0) {
00101 if (owner_ != NULL)
00102 return owner_->block_type();
00103
00104 return BundleProtocol::UNKNOWN_BLOCK;
00105 }
00106
00107 u_char* data = contents_.buf();
00108 (void)data;
00109 if (owner_ != NULL)
00110 ASSERT(contents_.buf()[0] == owner_->block_type()
00111 || owner_->block_type() == BundleProtocol::UNKNOWN_BLOCK
00112 || owner_->block_type() == BundleProtocol::API_EXTENSION_BLOCK);
00113 return contents_.buf()[0];
00114 }
00115
00116
00117 u_int64_t
00118 BlockInfo::flags() const
00119 {
00120 if (type() == BundleProtocol::PRIMARY_BLOCK) {
00121 return 0x0;
00122 }
00123
00124 u_int64_t flags;
00125 int sdnv_size = SDNV::decode(contents_.buf() + 1, contents_.len() - 1,
00126 &flags);
00127 ASSERT(sdnv_size > 0);
00128 return flags;
00129 }
00130
00131
00132 void
00133 BlockInfo::set_flag(u_int64_t flag)
00134 {
00135 size_t sdnv_len = SDNV::encoding_len(flag);
00136 ASSERT(contents_.len() >= 1 + sdnv_len);
00137 SDNV::encode(flag, contents_.buf() + 1, sdnv_len);
00138 }
00139
00140
00141 bool
00142 BlockInfo::last_block() const
00143 {
00144
00145 if (contents_.len() < 2) {
00146 return false;
00147 }
00148
00149 u_int64_t flag = flags();
00150 return ((flag & BundleProtocol::BLOCK_FLAG_LAST_BLOCK) != 0);
00151 }
00152
00153
00154 void
00155 BlockInfo::serialize(oasys::SerializeAction* a)
00156 {
00157 a->process("owner_type", &owner_type_);
00158 if (a->action_code() == oasys::Serialize::UNMARSHAL) {
00159
00160 if (owner_type_ == BundleProtocol::API_EXTENSION_BLOCK) {
00161 owner_ = APIBlockProcessor::instance();
00162 } else {
00163 owner_ = BundleProtocol::find_processor(owner_type_);
00164 }
00165 }
00166
00167 u_int32_t length = contents_.len();
00168 a->process("length", &length);
00169
00170
00171
00172 if (a->action_code() == oasys::Serialize::UNMARSHAL) {
00173 contents_.reserve(length);
00174 contents_.set_len(length);
00175 }
00176
00177 a->process("contents", contents_.buf(), length);
00178 a->process("data_length", &data_length_);
00179 a->process("data_offset", &data_offset_);
00180 a->process("complete", &complete_);
00181 a->process("eid_list", &eid_list_);
00182 }
00183
00184
00185 BlockInfoVec::BlockInfoVec()
00186 : oasys::SerializableVector<BlockInfo>(),
00187 error_major_(0),
00188 error_minor_(0),
00189 error_debug_(0)
00190 {
00191 }
00192
00193
00194 BlockInfo*
00195 BlockInfoVec::append_block(BlockProcessor* owner, const BlockInfo* source)
00196 {
00197 push_back(BlockInfo(owner, source));
00198 return &back();
00199 }
00200
00201
00202 const BlockInfo*
00203 BlockInfoVec::find_block(u_int8_t type) const
00204 {
00205 for (const_iterator iter = begin(); iter != end(); ++iter) {
00206 if (iter->type() == type ||
00207 iter->owner()->block_type() == type)
00208 {
00209 return &*iter;
00210 }
00211 }
00212 return false;
00213 }
00214
00215
00216 LinkBlockSet::Entry::Entry(const LinkRef& link)
00217 : blocks_(NULL), link_(link.object(), "LinkBlockSet::Entry")
00218 {
00219 }
00220
00221
00222 LinkBlockSet::~LinkBlockSet()
00223 {
00224 for (iterator iter = entries_.begin();
00225 iter != entries_.end();
00226 ++iter)
00227 {
00228 delete iter->blocks_;
00229 iter->blocks_ = 0;
00230 }
00231 }
00232
00233
00234 BlockInfoVec*
00235 LinkBlockSet::create_blocks(const LinkRef& link)
00236 {
00237 oasys::ScopeLock l(lock_, "LinkBlockSet::create_blocks");
00238
00239 ASSERT(find_blocks(link) == NULL);
00240 entries_.push_back(Entry(link));
00241 entries_.back().blocks_ = new BlockInfoVec();
00242 return entries_.back().blocks_;
00243 }
00244
00245
00246 BlockInfoVec*
00247 LinkBlockSet::find_blocks(const LinkRef& link) const
00248 {
00249 oasys::ScopeLock l(lock_, "LinkBlockSet::find_blocks");
00250
00251 for (const_iterator iter = entries_.begin();
00252 iter != entries_.end();
00253 ++iter)
00254 {
00255 if (iter->link_ == link) {
00256 return iter->blocks_;
00257 }
00258 }
00259 return NULL;
00260 }
00261
00262
00263 void
00264 LinkBlockSet::delete_blocks(const LinkRef& link)
00265 {
00266 oasys::ScopeLock l(lock_, "LinkBlockSet::delete_blocks");
00267
00268 for (iterator iter = entries_.begin();
00269 iter != entries_.end();
00270 ++iter)
00271 {
00272 if (iter->link_ == link) {
00273 delete iter->blocks_;
00274 entries_.erase(iter);
00275 return;
00276 }
00277 }
00278
00279 PANIC("LinkBlockVec::delete_blocks: "
00280 "no block vector for link *%p", link.object());
00281 }
00282
00283 }