--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/servlib/bundling/BundlePayload.h Thu Apr 21 14:57:45 2011 +0100
@@ -0,0 +1,192 @@
+/*
+ * Copyright 2004-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 _BUNDLE_PAYLOAD_H_
+#define _BUNDLE_PAYLOAD_H_
+
+#include <string>
+#include <oasys/serialize/Serialize.h>
+#include <oasys/debug/DebugUtils.h>
+#include <oasys/io/FileIOClient.h>
+
+namespace dtn {
+
+class BundleStore;
+
+/**
+ * The representation of a bundle payload.
+ *
+ * This is abstracted into a separate class to allow the daemon to
+ * separately manage the serialization of header information from the
+ * payload.
+ *
+ * Note that this implementation doesn't support payloads larger than
+ * 4GB. XXX/demmer fix this.
+ *
+ */
+class BundlePayload : public oasys::SerializableObject, public oasys::Logger {
+public:
+ BundlePayload(oasys::SpinLock* lock);
+ virtual ~BundlePayload();
+
+ /**
+ * Options for payload location state.
+ */
+ typedef enum {
+ MEMORY = 1, /// in memory only (TempBundle)
+ DISK = 2, /// on disk
+ NODATA = 3, /// no data storage at all (used for simulator)
+ } location_t;
+
+ /**
+ * Actual payload initialization function.
+ */
+ void init(int bundleid, location_t location = DISK);
+
+ /**
+ * Initialization when re-reading the database
+ */
+ void init_from_store(int bundleid);
+
+ /**
+ * Set the payload length in preparation for filling in with data.
+ */
+ void set_length(size_t len);
+
+ /**
+ * Truncate the payload. Used for reactive fragmentation.
+ */
+ void truncate(size_t len);
+
+ /**
+ * The payload length.
+ */
+ size_t length() const { return length_; }
+
+ /**
+ * The payload location.
+ */
+ location_t location() const { return location_; }
+
+ /**
+ * Set the payload data and length.
+ */
+ void set_data(const u_char* bp, size_t len);
+
+ /**
+ * Set the payload data and length.
+ */
+ void set_data(const std::string& data);
+
+ /**
+ * Append a chunk of payload data, extending the length to
+ * accomodate the new data.
+ */
+ void append_data(const u_char* bp, size_t len);
+
+ /**
+ * Write a chunk of payload data at the specified offset. The
+ * length must have been previously set to at least offset + len.
+ */
+ void write_data(const u_char* bp, size_t offset, size_t len);
+
+ /**
+ * Writes len bytes of payload data from from another payload at
+ * the given src_offset to the given dst_offset.
+ */
+ void write_data(const BundlePayload& src, size_t src_offset,
+ size_t len, size_t dst_offset);
+
+ /**
+ * Copy (or link) the payload to the given file client object
+ */
+ void copy_file(oasys::FileIOClient* dst) const;
+
+ /**
+ * Replace the underlying file with a hard link to the given path
+ * or a copy of the file contents if the link can't be created.
+ */
+ bool replace_with_file(const char* path);
+
+ /**
+ * Return the filename.
+ */
+ const std::string& filename() const
+ {
+ ASSERT(location_ == DISK);
+ return file_.path_str();
+ }
+
+ /**
+ * Get a pointer to the in-memory scratch buffer.
+ */
+ oasys::ScratchBuffer<u_char*>* memory_buf()
+ {
+ ASSERT(location_ == MEMORY);
+ return &data_;
+ }
+
+ /**
+ * Get a pointer to the in-memory scratch buffer (const variant
+ */
+ const oasys::ScratchBuffer<u_char*>* memory_buf() const
+ {
+ ASSERT(location_ == MEMORY);
+ return &data_;
+ }
+
+ /**
+ * Copy out a chunk of payload data into the supplied buffer.
+ * @return pointer to the buffer for convenience
+ */
+ const u_char* read_data(size_t offset, size_t len, u_char* buf);
+
+ /**
+ * Since read_data doesn't really change anything of substance in
+ * the payload class (just the internal bookkeeping fields), we
+ * define a "const" variant that just casts itself away and calls
+ * the normal variant.
+ */
+ const u_char* read_data(size_t offset, size_t len, u_char* buf) const
+ {
+ return const_cast<BundlePayload*>(this)->
+ read_data(offset, len, buf);
+ }
+
+ /**
+ * Virtual from SerializableObject
+ */
+ virtual void serialize(oasys::SerializeAction* a);
+
+ static bool test_no_remove_; ///< test: don't rm payload files
+
+protected:
+ void pin_file() const;
+ void unpin_file() const;
+ void internal_write(const u_char* bp, size_t offset, size_t len);
+
+ location_t location_; ///< location of the data
+ oasys::ScratchBuffer<u_char*> data_; ///< payload data if in memory
+ size_t length_; ///< the payload length
+ mutable oasys::FileIOClient file_; ///< file handle
+ mutable size_t cur_offset_; ///< cache of current fd position
+ size_t base_offset_; ///< for fragments, offset into the file (todo)
+ oasys::SpinLock* lock_; ///< the lock for the given bundle
+};
+
+} // namespace dtn
+
+#endif /* _BUNDLE_PAYLOAD_H_ */