servlib/bundling/MetadataBlock.cc
changeset 0 2b3e5ec03512
equal deleted inserted replaced
-1:000000000000 0:2b3e5ec03512
       
     1 /*
       
     2  *    Copyright 2007 The MITRE Corporation
       
     3  * 
       
     4  *    Licensed under the Apache License, Version 2.0 (the "License");
       
     5  *    you may not use this file except in compliance with the License.
       
     6  *    You may obtain a copy of the License at
       
     7  * 
       
     8  *        http://www.apache.org/licenses/LICENSE-2.0
       
     9  * 
       
    10  *    Unless required by applicable law or agreed to in writing, software
       
    11  *    distributed under the License is distributed on an "AS IS" BASIS,
       
    12  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
       
    13  *    See the License for the specific language governing permissions and
       
    14  *    limitations under the License.
       
    15  *
       
    16  *    The US Government will not be charged any license fee and/or royalties
       
    17  *    related to this software. Neither name of The MITRE Corporation; nor the
       
    18  *    names of its contributors may be used to endorse or promote products
       
    19  *    derived from this software without specific prior written permission.
       
    20  */
       
    21 
       
    22 #ifdef HAVE_CONFIG_H
       
    23 #  include <dtn-config.h>
       
    24 #endif
       
    25 
       
    26 #include <oasys/debug/Log.h>
       
    27 
       
    28 #include "MetadataBlock.h"
       
    29 #include "MetadataBlockProcessor.h"
       
    30 
       
    31 namespace dtn {
       
    32 
       
    33 unsigned int MetadataBlock::index_ = 0;
       
    34 
       
    35 //----------------------------------------------------------------------
       
    36 MetadataBlock::MetadataBlock(u_int64_t type, u_char* buf, u_int32_t len):
       
    37     lock_("MetadataBlock"), id_(MetadataBlock::get_next_index()),
       
    38     block_(NULL), generated_(true), error_(false),
       
    39     source_id_(0), source_(false), flags_(0),
       
    40     ontology_(type), metadata_(NULL), metadata_len_(0)
       
    41 {
       
    42     if (len > 0) {
       
    43         ASSERT(buf != NULL);
       
    44         metadata_ = new u_char[len];
       
    45         memcpy(metadata_, buf, len);
       
    46         metadata_len_ = len;
       
    47     }
       
    48 }
       
    49 
       
    50 //----------------------------------------------------------------------
       
    51 MetadataBlock::MetadataBlock(unsigned int source_id, u_int64_t type,
       
    52                              u_char* buf, u_int32_t len):
       
    53     lock_("MetadataBlock"), id_(MetadataBlock::get_next_index()),
       
    54     block_(NULL), generated_(true), error_(false),
       
    55     source_id_(source_id), source_(true), flags_(0),
       
    56     ontology_(type), metadata_(NULL), metadata_len_(0)
       
    57 {
       
    58     if (len > 0) {
       
    59         ASSERT(buf != NULL);
       
    60         metadata_ = new u_char[len];
       
    61         memcpy(metadata_, buf, len);
       
    62         metadata_len_ = len;
       
    63     }
       
    64 }
       
    65 
       
    66 //----------------------------------------------------------------------
       
    67 MetadataBlock::MetadataBlock(const MetadataBlock& copy):
       
    68     BP_Local(copy),
       
    69     oasys::SerializableObject(copy),
       
    70     lock_("MetadataBlock"), id_(copy.id_), block_(copy.block_),
       
    71     generated_(copy.generated_), error_(copy.error_),
       
    72     source_id_(copy.source_id_), source_(copy.source_),
       
    73     ontology_(copy.ontology_), metadata_(NULL),
       
    74     metadata_len_(0)
       
    75 {
       
    76     if (copy.generated_ && (copy.metadata_len_ > 0)) {
       
    77         ASSERT(copy.metadata_ != NULL);
       
    78         metadata_ = new u_char[copy.metadata_len_];
       
    79         memcpy(metadata_, copy.metadata_, copy.metadata_len_);
       
    80         metadata_len_ = copy.metadata_len_;
       
    81 
       
    82     } else {
       
    83         metadata_     = copy.metadata_;
       
    84         metadata_len_ = copy.metadata_len_;
       
    85     }
       
    86 }
       
    87 
       
    88 //----------------------------------------------------------------------
       
    89 MetadataBlock::~MetadataBlock()
       
    90 {
       
    91     outgoing_metadata_.clear();
       
    92     if (generated_ && (metadata_ != NULL)) {
       
    93         delete[] metadata_;
       
    94         metadata_ = NULL;
       
    95         metadata_len_ = 0;
       
    96     }
       
    97 }
       
    98 
       
    99 //----------------------------------------------------------------------
       
   100 void
       
   101 MetadataBlock::set_flags(u_int64_t flags)
       
   102 {
       
   103     ASSERT(generated_);
       
   104     flags_ = flags;
       
   105 }
       
   106 
       
   107 //----------------------------------------------------------------------
       
   108 void
       
   109 MetadataBlock::set_metadata(u_char *buf, u_int32_t len)
       
   110 {
       
   111     ASSERT(!generated_);
       
   112 
       
   113     if (len > 0) {
       
   114         ASSERT(buf != NULL);
       
   115         metadata_ = buf;
       
   116         metadata_len_ = len;
       
   117     } else {
       
   118         metadata_ = NULL;
       
   119         metadata_len_ = 0;
       
   120     }
       
   121 }
       
   122 
       
   123 //----------------------------------------------------------------------
       
   124 bool
       
   125 MetadataBlock::remove_outgoing_metadata(const LinkRef& link)
       
   126 {
       
   127     static const char* log = "/dtn/bundle/protocol";
       
   128 
       
   129     if (has_outgoing_metadata(link)) {
       
   130         log_err_p(log, "MetadataBlock::remove_outgoing_metadata: "
       
   131                        "outgoing metadata already exists for link");
       
   132         return false;
       
   133     }
       
   134 
       
   135     outgoing_metadata_.push_back(OutgoingMetadata(link));
       
   136     return true;
       
   137 }
       
   138 
       
   139 //----------------------------------------------------------------------
       
   140 bool
       
   141 MetadataBlock::modify_outgoing_metadata(const LinkRef& link,
       
   142                                         u_char* buf, u_int32_t len)
       
   143 {
       
   144     static const char* log = "/dtn/bundle/protocol";
       
   145 
       
   146     if (has_outgoing_metadata(link)) {
       
   147         log_err_p(log, "MetadataBlock::modify_outgoing_metadata: "
       
   148                        "outgoing metadata already exists for link");
       
   149         return false;
       
   150     }
       
   151 
       
   152     outgoing_metadata_.push_back(OutgoingMetadata(link, buf, len));
       
   153     return true;
       
   154 }
       
   155 
       
   156 //----------------------------------------------------------------------
       
   157 bool
       
   158 MetadataBlock::metadata_removed(const LinkRef& link)
       
   159 {
       
   160     OutgoingMetadata* metadata = find_outgoing_metadata(link);
       
   161     if (metadata == NULL) {
       
   162         return false;
       
   163     }
       
   164 
       
   165     return (metadata->remove());
       
   166 }
       
   167 
       
   168 //----------------------------------------------------------------------
       
   169 bool
       
   170 MetadataBlock::metadata_modified(const LinkRef& link)
       
   171 {
       
   172     OutgoingMetadata* metadata = find_outgoing_metadata(link);
       
   173     if ((metadata == NULL) || metadata->remove()) {
       
   174         return false;
       
   175     }
       
   176     return true;
       
   177 }
       
   178 
       
   179 //----------------------------------------------------------------------
       
   180 bool
       
   181 MetadataBlock::metadata_modified(const LinkRef& link,
       
   182                                  u_char** buf, u_int32_t& len)
       
   183 {
       
   184     OutgoingMetadata* outgoing = find_outgoing_metadata(link);
       
   185     if ((outgoing == NULL) || outgoing->remove()) {
       
   186         return false;
       
   187     }
       
   188 
       
   189     *buf = outgoing->metadata();
       
   190     len  = outgoing->metadata_len();
       
   191     return true;
       
   192 }
       
   193 
       
   194 //----------------------------------------------------------------------
       
   195 void
       
   196 MetadataBlock::delete_outgoing_metadata(const LinkRef& link)
       
   197 {
       
   198     std::vector<OutgoingMetadata>::iterator iter = outgoing_metadata_.begin();
       
   199     for ( ; iter != outgoing_metadata_.end(); ++iter) {
       
   200         if (iter->link() == link) {
       
   201             outgoing_metadata_.erase(iter);
       
   202             return;
       
   203         }
       
   204     }
       
   205 }
       
   206 
       
   207 //----------------------------------------------------------------------
       
   208 void
       
   209 MetadataBlock::operator=(const MetadataBlock& copy)
       
   210 {
       
   211     if (&copy == this) {
       
   212         return;
       
   213     }
       
   214 
       
   215     outgoing_metadata_.clear();
       
   216     if (generated_ && (metadata_ != NULL)) {
       
   217         delete[] metadata_;
       
   218         metadata_ = NULL;
       
   219         metadata_len_ = 0;
       
   220     }
       
   221 
       
   222     id_        = copy.id_;
       
   223     block_     = copy.block_;
       
   224     generated_ = copy.generated_;
       
   225     error_     = copy.error_;
       
   226     ontology_  = copy.ontology_;
       
   227 
       
   228     if (copy.generated_ && (copy.metadata_len_ > 0)) {
       
   229         ASSERT(copy.metadata_ != NULL);
       
   230         metadata_ = new u_char[copy.metadata_len_];
       
   231         memcpy(metadata_, copy.metadata_, copy.metadata_len_);
       
   232         metadata_len_ = copy.metadata_len_;
       
   233 
       
   234     } else {
       
   235         metadata_     = copy.metadata_;
       
   236         metadata_len_ = copy.metadata_len_;
       
   237     }
       
   238 }
       
   239 
       
   240 //----------------------------------------------------------------------
       
   241 MetadataBlock::OutgoingMetadata *
       
   242 MetadataBlock::find_outgoing_metadata(const LinkRef& link)
       
   243 {
       
   244     std::vector<OutgoingMetadata>::iterator iter = outgoing_metadata_.begin();
       
   245     for ( ; iter != outgoing_metadata_.end(); ++iter) {
       
   246         if (iter->link() == link) {
       
   247             return &*iter;
       
   248         }
       
   249     }
       
   250     return NULL;
       
   251 }
       
   252 
       
   253 //----------------------------------------------------------------------
       
   254 MetadataBlock::OutgoingMetadata::OutgoingMetadata(
       
   255     const LinkRef& link, u_char* buf, u_int32_t len):
       
   256     link_(link.object(), "OutgoingMetadata"), remove_(false),
       
   257     metadata_(NULL), metadata_len_(0)
       
   258 {
       
   259     if (len > 0) {
       
   260         ASSERT(buf != NULL);
       
   261         metadata_ = new u_char[len];
       
   262         memcpy(metadata_, buf, len);
       
   263         metadata_len_ = len;
       
   264     }
       
   265 }
       
   266 
       
   267 //----------------------------------------------------------------------
       
   268 MetadataBlock::OutgoingMetadata::OutgoingMetadata(const OutgoingMetadata& copy):
       
   269     link_(copy.link_.object(), "OutgoingMetadata"), remove_(copy.remove_),
       
   270     metadata_(NULL), metadata_len_(0)
       
   271 {
       
   272     if (copy.metadata_len_ > 0) {
       
   273         ASSERT(copy.metadata_ != NULL);
       
   274         metadata_ = new u_char[copy.metadata_len_];
       
   275         memcpy(metadata_, copy.metadata_, copy.metadata_len_);
       
   276         metadata_len_ = copy.metadata_len_;
       
   277     }
       
   278 }
       
   279 
       
   280 //----------------------------------------------------------------------
       
   281 MetadataBlock::OutgoingMetadata::~OutgoingMetadata()
       
   282 {
       
   283     if (metadata_ != NULL) {
       
   284         delete[] metadata_;
       
   285         metadata_ = NULL;
       
   286         metadata_len_ = 0;
       
   287     }
       
   288 }
       
   289 
       
   290 //----------------------------------------------------------------------
       
   291 void
       
   292 MetadataBlock::OutgoingMetadata::operator=(const OutgoingMetadata& copy)
       
   293 {
       
   294     if (&copy == this) {
       
   295         return;
       
   296     }
       
   297 
       
   298     if (metadata_ != NULL) {
       
   299         delete[] metadata_;
       
   300         metadata_ = NULL;
       
   301         metadata_len_ = 0;
       
   302     }
       
   303 
       
   304     link_ = copy.link_;
       
   305     remove_ = copy.remove_;
       
   306 
       
   307     if (copy.metadata_len_ > 0) {
       
   308         ASSERT(copy.metadata_ != NULL);
       
   309         metadata_ = new u_char[copy.metadata_len_];
       
   310         memcpy(metadata_, copy.metadata_, copy.metadata_len_);
       
   311         metadata_len_ = copy.metadata_len_;
       
   312     }
       
   313 }
       
   314 
       
   315 //----------------------------------------------------------------------
       
   316 LinkMetadataSet::Entry::Entry(const LinkRef& link):
       
   317     blocks_(NULL), link_(link.object(), "LinkMetadataSet::Entry")
       
   318 {
       
   319 }
       
   320 
       
   321 //----------------------------------------------------------------------
       
   322 LinkMetadataSet::~LinkMetadataSet()
       
   323 {
       
   324     for (iterator iter = entries_.begin(); iter != entries_.end(); ++iter) {
       
   325         delete iter->blocks_;
       
   326         iter->blocks_ = NULL;
       
   327     }
       
   328 }
       
   329 
       
   330 //----------------------------------------------------------------------
       
   331 MetadataVec*
       
   332 LinkMetadataSet::create_blocks(const LinkRef& link)
       
   333 {
       
   334     ASSERT(find_blocks(link) == NULL);
       
   335     entries_.push_back(Entry(link));
       
   336     entries_.back().blocks_ =
       
   337         new MetadataVec(std::string("metadata for link ") +
       
   338                         ((link == NULL) ? "(null link)" : link->name()));
       
   339     return entries_.back().blocks_;
       
   340 }
       
   341 
       
   342 //----------------------------------------------------------------------
       
   343 MetadataVec*
       
   344 LinkMetadataSet::find_blocks(const LinkRef& link) const
       
   345 {
       
   346     for (const_iterator iter = entries_.begin();
       
   347          iter != entries_.end(); ++iter) {
       
   348         if (iter->link_ == link) {
       
   349             return iter->blocks_;
       
   350         }
       
   351     }
       
   352     return NULL;
       
   353 }
       
   354 
       
   355 //----------------------------------------------------------------------
       
   356 void
       
   357 LinkMetadataSet::delete_blocks(const LinkRef& link)
       
   358 {
       
   359     for (iterator iter = entries_.begin(); iter != entries_.end(); ++iter) {
       
   360         if (iter->link_ == link) {
       
   361             delete iter->blocks_;
       
   362             iter->blocks_ = NULL;
       
   363             entries_.erase(iter);
       
   364             return;
       
   365         }
       
   366     }
       
   367 }
       
   368 
       
   369 } // namespace dtn