LogCabin
|
00001 /* Copyright (c) 2012 Stanford University 00002 * 00003 * Permission to use, copy, modify, and distribute this software for any 00004 * purpose with or without fee is hereby granted, provided that the above 00005 * copyright notice and this permission notice appear in all copies. 00006 * 00007 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR(S) DISCLAIM ALL WARRANTIES 00008 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 00009 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL AUTHORS BE LIABLE FOR 00010 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 00011 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 00012 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 00013 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 00014 */ 00015 00016 #include <cinttypes> 00017 #include <cstdlib> 00018 00019 #ifndef LOGCABIN_CORE_BUFFER_H 00020 #define LOGCABIN_CORE_BUFFER_H 00021 00022 namespace LogCabin { 00023 namespace Core { 00024 00025 /** 00026 * A container for opaque data. This makes it easy for code to operate on data 00027 * without having to explicitly pass around its length and whether and how to 00028 * free its memory. 00029 */ 00030 class Buffer { 00031 public: 00032 /** 00033 * A deleter is a function that can free the memory contained in the 00034 * Buffer. Examples include C's free() function for memory allocated with 00035 * malloc(), and deleteObjectFn() and deleteArrayFn() defined in this 00036 * class. 00037 * \param data 00038 * The memory that should be reclaimed. 00039 */ 00040 typedef void (*Deleter)(void* data); 00041 00042 /** 00043 * A Deleter that uses C++'s delete keyword. 00044 * This should be used with data that was allocated with C++'s new keyword. 00045 * For new[] and delete[], see deleteArrayFn. 00046 * \param data 00047 * The memory that should be reclaimed. 00048 * \tparam T 00049 * The type of the object as it was allocated with new. 00050 */ 00051 template<typename T> 00052 static void deleteObjectFn(void* data) { 00053 delete static_cast<T>(data); 00054 } 00055 00056 /** 00057 * A Deleter that uses C++'s array delete[] keyword. 00058 * This should be used with data that was allocated with C++'s array new[] 00059 * keyword. For new and delete on individual objects, see deleteArray. 00060 * \param data 00061 * The memory that should be reclaimed. 00062 * \tparam T 00063 * The type of each element of the array as it was allocated with 00064 * new[]. 00065 */ 00066 template<typename T> 00067 static void deleteArrayFn(void* data) { 00068 delete[] static_cast<T*>(data); 00069 } 00070 00071 /** 00072 * Default constructor. 00073 */ 00074 Buffer(); 00075 00076 /** 00077 * Construct a non-empty buffer. This is equivalent to using the default 00078 * constructor and then calling setData(). 00079 * \param data 00080 * A pointer to the first byte of data to be contained in the Buffer. 00081 * \param length 00082 * The length in bytes of data. 00083 * \param deleter 00084 * Describes how to release the memory for 'data' when this Buffer is 00085 * destroyed or its data is replaced. NULL indicates that the caller 00086 * owns the memory and guarantees its lifetime will extend beyond that 00087 * of the Buffer. 00088 */ 00089 Buffer(void* data, uint64_t length, Deleter deleter); 00090 00091 /** 00092 * Move constructor. 00093 */ 00094 Buffer(Buffer&& other); 00095 00096 /** 00097 * Destructor. The memory for the existing data, if any, will be reclaimed 00098 * according to its deleter. 00099 */ 00100 ~Buffer(); 00101 00102 /** 00103 * Move assignment. 00104 */ 00105 Buffer& operator=(Buffer&& other); 00106 00107 /** 00108 * Return a pointer to the first byte of data. 00109 */ 00110 void* getData() { return data; } 00111 00112 /** 00113 * Return a pointer to the first byte of data (const variant). 00114 */ 00115 const void* getData() const { return data; } 00116 00117 /** 00118 * Return the number of bytes that make up the data. 00119 */ 00120 uint64_t getLength() const { return length; } 00121 00122 /** 00123 * Replace the data contained in this Buffer. 00124 * The memory for the previously existing data, if any, will be reclaimed 00125 * according to the previous deleter. 00126 * \param data 00127 * A pointer to the first byte of data to be contained in the Buffer. 00128 * \param length 00129 * The length in bytes of data. 00130 * \param deleter 00131 * Describes how to release the memory for 'data' when this Buffer is 00132 * destroyed or its data is replaced. NULL indicates that the caller 00133 * owns the memory and guarantees its lifetime will extend beyond that 00134 * of the Buffer. 00135 */ 00136 void setData(void* data, uint64_t length, Deleter deleter); 00137 00138 /** 00139 * Empty the Buffer. The memory for the existing data, if any, will be 00140 * reclaimed according to its deleter. 00141 */ 00142 void reset(); 00143 00144 private: 00145 /** 00146 * A pointer to the data or NULL if none has been set. 00147 */ 00148 void* data; 00149 00150 /** 00151 * The number of bytes that make up data or 0 if none has been set. 00152 */ 00153 uint64_t length; 00154 00155 /** 00156 * Describes how to release the memory for 'data' when this Buffer is 00157 * destroyed or its data is replaced. 00158 * This may be NULL, in which case it is not called (the memory is managed 00159 * externally). 00160 */ 00161 Deleter deleter; 00162 00163 // Buffer is non-copyable. 00164 Buffer(const Buffer&) = delete; 00165 Buffer& operator=(const Buffer&) = delete; 00166 00167 }; // class Buffer 00168 00169 } // namespace LogCabin::Core 00170 } // namespace LogCabin 00171 00172 #endif /* LOGCABIN_CORE_BUFFER_H */