wibble  0.1.28
buffer.h
Go to the documentation of this file.
1 #ifndef WIBBLE_SYS_BUFFER_H
2 #define WIBBLE_SYS_BUFFER_H
3 
4 /*
5  * Variable-size, reference-counted memory buffer
6  *
7  * Copyright (C) 2003--2006 Enrico Zini <enrico@debian.org>
8  *
9  * This library is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License as published by the Free Software Foundation; either
12  * version 2.1 of the License, or (at your option) any later version.
13  *
14  * This library is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with this library; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22  */
23 
24 #include <stddef.h> // for size_t
25 
26 namespace wibble {
27 namespace sys {
28 
32 class Buffer
33 {
34 public:
35  class Data
36  {
37  protected:
38  mutable int _ref;
39  size_t _size;
40  void* _data;
41 
42  public:
43  Data() throw () : _ref(0), _size(0), _data(0) {}
44  Data(size_t size);
45  // if own == true, take possession of the memory buffer, else copy it
46  Data(void* buf, size_t size, bool own = true);
47  Data(const void* buf, size_t size);
48  ~Data();
49 
51  void ref() const throw () { ++_ref; }
52 
55  bool unref() const throw () { return --_ref == 0; }
56 
58  void resize(size_t size);
59 
61  bool operator==(const Data& d) const throw();
62 
64  bool operator<(const Data& d) const throw();
65 
66  friend class Buffer;
67  };
68 
70 
71 public:
73  Buffer() throw () : item(0) {}
74 
76  Buffer(size_t size) : item(0)
77  {
78  if (size)
79  {
80  item = new Data(size);
81  item->ref();
82  }
83  }
84 
95  Buffer(void* buf, size_t size, bool own = true) : item(0)
96  {
97  if (size)
98  {
99  item = new Data(buf, size, own);
100  item->ref();
101  }
102  }
103 
109  Buffer(const void* buf, size_t size) : item(0)
110  {
111  if (size)
112  {
113  item = new Data(buf, size);
114  item->ref();
115  }
116  }
117 
118  Buffer(const Buffer& buf) throw ()
119  {
120  if (buf.item)
121  buf.item->ref();
122  item = buf.item;
123  }
125  {
126  if (item && item->unref())
127  delete item;
128  }
129  Buffer& operator=(const Buffer& buf)
130  {
131  if (buf.item)
132  buf.item->ref(); // Do it early to correctly handle the case of x = x;
133  if (item && item->unref())
134  delete item;
135  item = buf.item;
136  return *this;
137  }
138 
140  void* data() throw () { return item ? item->_data : 0; }
141 
143  const void* data() const throw () { return item ? item->_data : 0; }
144 
146  size_t size() const throw () { return item ? item->_size : 0; }
147 
149  void resize(size_t newSize)
150  {
151  if (size() == newSize)
152  return;
153  if (!newSize)
154  {
155  if (item && item->unref())
156  delete item;
157  item = 0;
158  } else if (item) {
159  item->resize(newSize);
160  } else {
161  item = new Data(newSize);
162  item->ref();
163  }
164  }
165 
167  bool operator==(const Buffer& buf) const throw ()
168  {
169  if (item == 0 && buf.item == 0)
170  return true;
171  if (item == 0 || buf.item == 0)
172  return false;
173  return *item == *buf.item;
174  }
175 
176  bool operator!=(const Buffer& buf) const throw ()
177  {
178  return !operator==(buf);
179  }
180 
182  bool operator<(const Buffer& buf) const throw ()
183  {
184  if (item == 0 && buf.item == 0)
185  return false;
186  if (item == 0)
187  return true;
188  if (buf.item == 0)
189  return false;
190  return *item < *buf.item;
191  }
192 };
193 
194 }
195 }
196 
197 // vim:set ts=4 sw=4:
198 #endif