2 // Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010 Free Software
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.
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.
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>
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.
42 /// Construct a SimpleBuffer with an optional initial capacity
45 /// The initial buffer capacity. This is the amount of
46 /// bytes you can append to the buffer before a new reallocation
49 SimpleBuffer(size_t capacity
=0)
56 _data
.reset(new boost::uint8_t[_capacity
]);
62 /// The copy ctor will set capacity to be
63 /// as small as required to hold the size of the
66 SimpleBuffer(const SimpleBuffer
& b
)
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
82 SimpleBuffer
& operator= (const SimpleBuffer
& b
)
84 if ( this != &b
) // don't waste time on self-assignment
86 resize(0); // shouldn't deallocate memory
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
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
;
125 _data
.reset(new boost::uint8_t[_capacity
]);
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.
139 /// Data to append. Will be copied.
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.
161 void appendByte(const boost::uint8_t b
)
164 _data
[_size
- 1] = b
;
167 /// Append 2 bytes to the buffer
169 /// The buffer will be appropriately resized to have space.
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
)
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.
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
)
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.
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
);
218 boost::scoped_array
<boost::uint8_t> _data
;
224 #endif // GNASH_SIMPLEBUFFER_H