wibble 0.1.28
|
00001 #ifndef WIBBLE_SYS_BUFFER_H 00002 #define WIBBLE_SYS_BUFFER_H 00003 00004 /* 00005 * Variable-size, reference-counted memory buffer 00006 * 00007 * Copyright (C) 2003--2006 Enrico Zini <enrico@debian.org> 00008 * 00009 * This library is free software; you can redistribute it and/or 00010 * modify it under the terms of the GNU Lesser General Public 00011 * License as published by the Free Software Foundation; either 00012 * version 2.1 of the License, or (at your option) any later version. 00013 * 00014 * This library is distributed in the hope that it will be useful, 00015 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00016 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00017 * Lesser General Public License for more details. 00018 * 00019 * You should have received a copy of the GNU Lesser General Public 00020 * License along with this library; if not, write to the Free Software 00021 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00022 */ 00023 00024 #include <stddef.h> // for size_t 00025 00026 namespace wibble { 00027 namespace sys { 00028 00032 class Buffer 00033 { 00034 public: 00035 class Data 00036 { 00037 protected: 00038 mutable int _ref; 00039 size_t _size; 00040 void* _data; 00041 00042 public: 00043 Data() throw () : _ref(0), _size(0), _data(0) {} 00044 Data(size_t size); 00045 // if own == true, take possession of the memory buffer, else copy it 00046 Data(void* buf, size_t size, bool own = true); 00047 Data(const void* buf, size_t size); 00048 ~Data(); 00049 00051 void ref() const throw () { ++_ref; } 00052 00055 bool unref() const throw () { return --_ref == 0; } 00056 00058 void resize(size_t size); 00059 00061 bool operator==(const Data& d) const throw(); 00062 00064 bool operator<(const Data& d) const throw(); 00065 00066 friend class Buffer; 00067 }; 00068 00069 Data* item; 00070 00071 public: 00073 Buffer() throw () : item(0) {} 00074 00076 Buffer(size_t size) : item(0) 00077 { 00078 if (size) 00079 { 00080 item = new Data(size); 00081 item->ref(); 00082 } 00083 } 00084 00095 Buffer(void* buf, size_t size, bool own = true) : item(0) 00096 { 00097 if (size) 00098 { 00099 item = new Data(buf, size, own); 00100 item->ref(); 00101 } 00102 } 00103 00109 Buffer(const void* buf, size_t size) : item(0) 00110 { 00111 if (size) 00112 { 00113 item = new Data(buf, size); 00114 item->ref(); 00115 } 00116 } 00117 00118 Buffer(const Buffer& buf) throw () 00119 { 00120 if (buf.item) 00121 buf.item->ref(); 00122 item = buf.item; 00123 } 00124 ~Buffer() 00125 { 00126 if (item && item->unref()) 00127 delete item; 00128 } 00129 Buffer& operator=(const Buffer& buf) 00130 { 00131 if (buf.item) 00132 buf.item->ref(); // Do it early to correctly handle the case of x = x; 00133 if (item && item->unref()) 00134 delete item; 00135 item = buf.item; 00136 return *this; 00137 } 00138 00140 void* data() throw () { return item ? item->_data : 0; } 00141 00143 const void* data() const throw () { return item ? item->_data : 0; } 00144 00146 size_t size() const throw () { return item ? item->_size : 0; } 00147 00149 void resize(size_t newSize) 00150 { 00151 if (size() == newSize) 00152 return; 00153 if (!newSize) 00154 { 00155 if (item && item->unref()) 00156 delete item; 00157 item = 0; 00158 } else if (item) { 00159 item->resize(newSize); 00160 } else { 00161 item = new Data(newSize); 00162 item->ref(); 00163 } 00164 } 00165 00167 bool operator==(const Buffer& buf) const throw () 00168 { 00169 if (item == 0 && buf.item == 0) 00170 return true; 00171 if (item == 0 || buf.item == 0) 00172 return false; 00173 return *item == *buf.item; 00174 } 00175 00176 bool operator!=(const Buffer& buf) const throw () 00177 { 00178 return !operator==(buf); 00179 } 00180 00182 bool operator<(const Buffer& buf) const throw () 00183 { 00184 if (item == 0 && buf.item == 0) 00185 return false; 00186 if (item == 0) 00187 return true; 00188 if (buf.item == 0) 00189 return false; 00190 return *item < *buf.item; 00191 } 00192 }; 00193 00194 } 00195 } 00196 00197 // vim:set ts=4 sw=4: 00198 #endif