initialize validbounds on ::init, log_debug sizes
[gnash.git] / libbase / SimpleBuffer.h
blob98c4c2c66b51add9dfe118188a7b38c64a3d3b96
1 //
2 // Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010 Free Software
3 // Foundation, Inc
4 //
5 // This program is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation; either version 3 of the License, or
8 // (at your option) any later version.
9 //
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with this program; if not, write to the Free Software
17 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 #ifndef GNASH_SIMPLEBUFFER_H
20 #define GNASH_SIMPLEBUFFER_H
23 #include <boost/cstdint.hpp> // for boost::uint8_t
24 #include <algorithm> // for std::copy
25 #include <boost/scoped_array.hpp>
26 #include <cassert>
29 namespace gnash {
31 /// A simple buffer of bytes
33 /// This class is fully inlined and just aiming to provide RIIA
34 /// and unified view of memory buffers.
35 /// It is a kind of a std::vector with a reduced interface
36 /// in the intentions of the author.
37 ///
38 class SimpleBuffer {
40 public:
42 /// Construct a SimpleBuffer with an optional initial capacity
44 /// @param capacity
45 /// The initial buffer capacity. This is the amount of
46 /// bytes you can append to the buffer before a new reallocation
47 /// will occur.
48 ///
49 SimpleBuffer(size_t capacity=0)
51 _size(0),
52 _capacity(capacity)
54 if ( _capacity )
56 _data.reset(new boost::uint8_t[_capacity]);
60 /// Copy constructor
62 /// The copy ctor will set capacity to be
63 /// as small as required to hold the size of the
64 /// model buffer.
65 ///
66 SimpleBuffer(const SimpleBuffer& b)
68 _size(b._size),
69 _capacity(b._size)
71 if ( _size )
73 _data.reset(new boost::uint8_t[_size]);
74 std::copy(b.data(), b.data()+b.size(), _data.get());
78 /// Assignment operator
80 /// The assignment op will not reset capacity
81 ///
82 SimpleBuffer& operator= (const SimpleBuffer& b)
84 if ( this != &b ) // don't waste time on self-assignment
86 resize(0); // shouldn't deallocate memory
87 append(b);
89 return *this;
92 /// Return true if buffer is empty
93 bool empty() const { return _size==0; }
95 /// Return size of the buffer
96 size_t size() const { return _size; }
98 /// Return capacity of the buffer
99 size_t capacity() const { return _capacity; }
101 /// Get a pointer to start of data. May be NULL if size==0.
102 boost::uint8_t* data() { return _data.get(); }
104 /// Get a pointer to start of data. May be NULL if size==0.
105 const boost::uint8_t* data() const { return _data.get(); }
107 /// Resize the buffer
108 void resize(size_t newSize)
110 reserve(newSize); // will set capacity
111 _size = newSize;
114 /// Ensure at least 'newCapacity' bytes are allocated for this buffer
115 void reserve(size_t newCapacity)
117 if ( _capacity >= newCapacity ) return;
119 // TODO: use smalles power of 2 bigger then newCapacity
120 _capacity = std::max(newCapacity, _capacity*2);
122 boost::scoped_array<boost::uint8_t> tmp;
123 tmp.swap(_data);
125 _data.reset(new boost::uint8_t[_capacity]);
127 if ( tmp.get() )
129 if ( _size ) std::copy(tmp.get(), tmp.get()+_size, _data.get());
133 /// Append data to the buffer
135 /// The buffer will be appropriately resized to have space for
136 /// the incoming data. The data will be copied.
138 /// @param inData
139 /// Data to append. Will be copied.
141 /// @param size
142 /// Size of data to append
144 void append(const void* inData, size_t size)
146 const boost::uint8_t* newData =
147 reinterpret_cast<const boost::uint8_t*>(inData);
148 size_t curSize = _size;
149 resize(curSize+size);
150 std::copy(newData, newData+size, _data.get()+curSize);
151 assert(_size == curSize+size);
154 /// Append a byte to the buffer
156 /// The buffer will be appropriately resized to have space.
158 /// @param b
159 /// Byte to append.
161 void appendByte(const boost::uint8_t b)
163 resize(_size + 1);
164 _data[_size - 1] = b;
167 /// Append 2 bytes to the buffer
169 /// The buffer will be appropriately resized to have space.
171 /// @param s
172 /// Short to append. Will be appended in network order. ie
173 /// with high order byte first.
175 void appendNetworkShort(const boost::uint16_t s)
177 resize(_size + 2);
178 _data[_size - 2] = s >> 8;
179 _data[_size - 1] = s & 0xff;
182 /// Append 4 bytes to the buffer
184 /// The buffer will be appropriately resized to have space.
186 /// @param l
187 /// Long to append. Will be appended in network order. ie
188 /// with high order bytes first.
190 void appendNetworkLong(const boost::uint32_t l)
192 resize(_size + 4);
193 _data[_size - 4] = l >> 24;
194 _data[_size - 3] = (l >> 16) & 0xff;
195 _data[_size - 2] = (l >> 8) & 0xff;
196 _data[_size - 1] = l & 0xff;
199 /// Append data to the buffer
201 /// The buffer will be appropriately resized to have space for
202 /// the incoming data. The data will be copied.
204 /// @param buf
205 /// SimpleBuffer containing data to append
207 void append(const SimpleBuffer& buf)
209 size_t incomingDataSize = buf.size();
210 const boost::uint8_t* incomingData = buf.data();
211 append(incomingData, incomingDataSize);
214 private:
215 size_t _size;
216 size_t _capacity;
218 boost::scoped_array<boost::uint8_t> _data;
222 } // namespace gnash
224 #endif // GNASH_SIMPLEBUFFER_H