servlib/bundling/BlockInfo.h
changeset 0 2b3e5ec03512
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/servlib/bundling/BlockInfo.h	Thu Apr 21 14:57:45 2011 +0100
@@ -0,0 +1,258 @@
+/*
+ *    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.
+ */
+
+#ifndef _BUNDLEBLOCKINFO_H_
+#define _BUNDLEBLOCKINFO_H_
+
+#include <oasys/debug/DebugUtils.h>
+#include <oasys/serialize/Serialize.h>
+#include <oasys/serialize/SerializableVector.h>
+#include <oasys/util/ScratchBuffer.h>
+
+#include "BP_Local.h"
+#include "Dictionary.h"
+#include "contacts/Link.h"
+
+namespace dtn {
+
+class BlockProcessor;
+class BP_Local;
+
+/**
+ * Class used to store unparsed bundle blocks and associated metadata
+ * about them.
+ */
+class BlockInfo : public oasys::SerializableObject {
+public:
+    /// To store the formatted block data, we use a scratch buffer
+    /// with 64 bytes of static buffer space which should be
+    /// sufficient to cover most blocks and avoid mallocs.
+    typedef oasys::ScratchBuffer<u_char*, 64> DataBuffer;
+    
+    /// Default constructor assigns the owner and optionally the
+    /// BlockInfo source (i.e. the block as it arrived off the wire)
+    BlockInfo(BlockProcessor* owner, const BlockInfo* source = NULL);
+
+    /// Constructor for unserializing
+    BlockInfo(oasys::Builder& builder);
+
+    /// Copy constructor to increment refcount for locals_
+    BlockInfo(const BlockInfo& bi);
+    
+    /**
+     * Virtual destructor.
+     */
+    virtual ~BlockInfo();
+
+    /**
+     * List owner indicator (not transmitted)
+     */
+    typedef enum {
+        LIST_NONE           = 0x00,
+        LIST_RECEIVED       = 0x01,
+        LIST_API            = 0x02,
+        LIST_EXT            = 0x03,
+        LIST_XMIT           = 0x04
+    } list_owner_t;
+    
+    /// @{ Accessors
+    BlockProcessor*   owner()          const { return owner_; }
+    const BlockInfo*  source()         const { return source_; }
+    const EndpointIDVector& eid_list() const { return eid_list_; }
+    const DataBuffer& contents()       const { return contents_; }
+    BP_Local*         locals()         const { return locals_.object(); }
+    u_int32_t         data_length()    const { return data_length_; }
+    u_int32_t         data_offset()    const { return data_offset_; }
+    u_int32_t         full_length()    const { return (data_offset_ +
+                                                       data_length_); }
+    u_char*           data()           const { return (contents_.buf() +
+                                                       data_offset_); }
+    bool              complete()       const { return complete_; }
+    bool              reloaded()       const { return reloaded_; }
+    bool              last_block()     const;
+    ///@}
+
+    /// @{ Mutating accessors
+    void        set_owner(BlockProcessor* o) { owner_ = o; }
+    void        set_eid_list(const EndpointIDVector& l) { eid_list_ = l; }
+    void        set_complete(bool t)         { complete_ = t; }
+    void        set_data_length(u_int32_t l) { data_length_ = l; }
+    void        set_data_offset(u_int32_t o) { data_offset_ = o; }
+    DataBuffer* writable_contents()          { return &contents_; }
+    void        set_locals(BP_Local* l);
+    void        add_eid(EndpointID e)        { eid_list_.push_back(e); }
+    void        set_reloaded(bool t)         { reloaded_ = t; }
+    /// @}
+
+    /// @{ These accessors need special case processing since the
+    /// primary block doesn't have the fields in the same place.
+    int       type()  const;
+    u_int64_t flags() const;
+    void      set_flag(u_int64_t flag);
+    /// @}
+
+    /// Virtual from SerializableObject
+    virtual void serialize(oasys::SerializeAction* action);
+
+protected:
+    BlockProcessor*  owner_;       ///< Owner of this block
+    u_int16_t        owner_type_;  ///< Extracted from owner
+    const BlockInfo* source_;      ///< Owner of this block
+    EndpointIDVector eid_list_;    ///< List of EIDs used in this block
+    DataBuffer       contents_;    ///< Block contents with length set to
+                                   ///  the amount currently in the buffer
+    BP_LocalRef      locals_;      ///< Local variable storage for block processor
+    u_int32_t        data_length_; ///< Length of the block data (w/o preamble)
+    u_int32_t        data_offset_; ///< Offset of first byte of the block data
+    bool             complete_;    ///< Whether or not this block is complete
+    bool             reloaded_;    ///< Whether or not this block is reloaded
+                                   ///  from store (set in ::reload_post_process
+                                   ///  of the BlockProcessor classes)
+};
+
+/**
+ * Class for a vector of BlockInfo structures.
+ */
+class BlockInfoVec : public oasys::SerializableVector<BlockInfo> {
+public:
+    /**
+     * Default constructor.
+     */
+    BlockInfoVec();
+    
+    /**
+     * Append a block using the given processor and optional source
+     * block.
+     *
+     * @return the newly allocated block -- note that this pointer may
+     * be invalidated with a future call that changes the vector.
+     */
+    BlockInfo* append_block(BlockProcessor*  owner,
+                            const BlockInfo* source = NULL);
+
+    /**
+     * Find the block for the given type.
+     *
+     * @return the block or NULL if not found
+     */
+    const BlockInfo* find_block(u_int8_t type) const;
+    
+    /**
+     * Check if an entry exists in the vector for the given block type.
+     */
+    bool has_block(u_int8_t type) const { return find_block(type) != NULL; }
+
+    /**
+     * Return the dictionary.
+     */
+    Dictionary* dict()  { return &dict_; }
+
+    /**
+     * Error values stored by processing routines
+     *   -- accessors
+     */
+    u_int32_t         error_major()     const { return error_major_; }
+    u_int32_t         error_minor()     const { return error_minor_; }
+    u_int32_t         error_debug()     const { return error_debug_; }
+
+    /**
+     * Error values stored by processing routines
+     *   -- mutating accessors
+     */
+    void        set_error_major(u_int32_t e)  { error_major_ = e; }
+    void        set_error_minor(u_int32_t e)  { error_minor_ = e; }
+    void        set_error_debug(u_int32_t e)  { error_debug_ = e; }
+
+protected:
+    /**
+     * Error values stored by processing routines
+     */
+    u_int32_t    error_major_;
+    u_int32_t    error_minor_;
+    u_int32_t    error_debug_;
+
+    /**
+     * Dictionary for this vector of BlockInfo structures
+     */
+    Dictionary   dict_;
+
+    /**
+     * Disable the copy constructor and assignment operator.
+     */
+    NO_ASSIGN_COPY(BlockInfoVec);
+};
+
+/**
+ * A set of BlockInfoVecs, one for each outgoing link.
+ */
+class LinkBlockSet {
+public:
+    LinkBlockSet(oasys::Lock* lock) : lock_(lock) {}
+    
+    /**
+     * Destructor that clears the set.
+     */
+    virtual ~LinkBlockSet();
+    
+    /**
+     * Create a new BlockInfoVec for the given link.
+     *
+     * @return Pointer to the new BlockInfoVec
+     */
+    BlockInfoVec* create_blocks(const LinkRef& link);
+    
+    /**
+     * Find the BlockInfoVec for the given link.
+     *
+     * @return Pointer to the BlockInfoVec or NULL if not found
+     */
+    BlockInfoVec* find_blocks(const LinkRef& link) const;
+    
+    /**
+     * Remove the BlockInfoVec for the given link.
+     */
+    void delete_blocks(const LinkRef& link);
+
+protected:
+    /**
+     * Struct to hold a block list and a link pointer. Note that we
+     * allow the STL vector to copy the pointers to both the block
+     * list and the link pointer. This is safe because the lifetime of
+     * the BlockInfoVec object is defined by create_blocks() and
+     * delete_blocks().
+     */
+    struct Entry {
+        Entry(const LinkRef& link);
+        
+        BlockInfoVec* blocks_;
+        LinkRef       link_;
+    };
+
+    typedef std::vector<Entry> Vector;
+    typedef std::vector<Entry>::iterator iterator;
+    typedef std::vector<Entry>::const_iterator const_iterator;
+    Vector entries_;
+    oasys::Lock* lock_;
+
+    /**
+     * Disable the copy constructor and assignment operator.
+     */
+    NO_ASSIGN_COPY(LinkBlockSet);
+};
+
+} // namespace dtn
+
+#endif /* _BUNDLEBLOCKINFO_H_ */