Gnash  0.8.10
SimpleBuffer.h
Go to the documentation of this file.
00001 // 
00002 //   Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
00003 //   Free Software Foundation, Inc
00004 // 
00005 // This program is free software; you can redistribute it and/or modify
00006 // it under the terms of the GNU General Public License as published by
00007 // the Free Software Foundation; either version 3 of the License, or
00008 // (at your option) any later version.
00009 // 
00010 // This program is distributed in the hope that it will be useful,
00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013 // GNU General Public License for more details.
00014 // 
00015 // You should have received a copy of the GNU General Public License
00016 // along with this program; if not, write to the Free Software
00017 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00018 
00019 #ifndef GNASH_SIMPLEBUFFER_H
00020 #define GNASH_SIMPLEBUFFER_H
00021 
00022 
00023 #include <boost/cstdint.hpp> // for boost::uint8_t
00024 #include <algorithm> // for std::copy
00025 #include <boost/scoped_array.hpp>
00026 #include <cassert>
00027 
00028 
00029 namespace gnash {
00030 
00032 //
00038 class SimpleBuffer {
00039 
00040 public:
00041 
00043         //
00049         SimpleBuffer(size_t capacity=0)
00050                 :
00051                 _size(0),
00052                 _capacity(capacity)
00053         {
00054                 if ( _capacity )
00055                 {
00056                         _data.reset(new boost::uint8_t[_capacity]);
00057                 }
00058         }
00059 
00061         //
00066         SimpleBuffer(const SimpleBuffer& b)
00067                 :
00068                 _size(b._size),
00069                 _capacity(b._size)
00070         {
00071                 if ( _size )
00072                 {
00073                         _data.reset(new boost::uint8_t[_size]);
00074                         std::copy(b.data(), b.data()+b.size(), _data.get());
00075                 }
00076         }
00077 
00079         //
00082         SimpleBuffer& operator= (const SimpleBuffer& b)
00083         {
00084                 if ( this != &b )  // don't waste time on self-assignment
00085                 {
00086                         resize(0); // shouldn't deallocate memory
00087                         append(b);
00088                 }
00089                 return *this;
00090         }
00091 
00093         bool empty() const { return _size==0; }
00094 
00096         size_t size() const { return _size; }
00097 
00099         size_t capacity() const { return _capacity; }
00100 
00102         boost::uint8_t* data() { return _data.get(); }
00103 
00105         const boost::uint8_t* data() const { return _data.get(); }
00106 
00108         void resize(size_t newSize)
00109         {
00110                 reserve(newSize); // will set capacity
00111                 _size = newSize;
00112         }
00113 
00115         void reserve(size_t newCapacity)
00116         {
00117                 if ( _capacity >= newCapacity ) return;
00118 
00119                 // TODO: use smalles power of 2 bigger then newCapacity
00120                 _capacity = std::max(newCapacity, _capacity*2);
00121 
00122                 boost::scoped_array<boost::uint8_t> tmp;
00123                 tmp.swap(_data);
00124                 
00125                 _data.reset(new boost::uint8_t[_capacity]);
00126 
00127                 if ( tmp.get() )
00128                 {
00129                         if ( _size ) std::copy(tmp.get(), tmp.get()+_size, _data.get());
00130                 }
00131         }
00132 
00134         //
00144         void append(const void* inData, size_t size)
00145         {
00146                 const boost::uint8_t* newData = 
00147             reinterpret_cast<const boost::uint8_t*>(inData);
00148                 size_t curSize = _size;
00149                 resize(curSize+size);
00150                 std::copy(newData, newData+size, _data.get()+curSize);
00151                 assert(_size == curSize+size);
00152         }
00153 
00155         //
00161         void appendByte(const boost::uint8_t b)
00162         {
00163                 resize(_size + 1);
00164                 _data[_size - 1] = b;
00165         }
00166 
00168         //
00175         void appendNetworkShort(const boost::uint16_t s)
00176         {
00177                 resize(_size + 2);
00178                 _data[_size - 2] = s >> 8;
00179                 _data[_size - 1] = s & 0xff;
00180         }
00181 
00183         //
00190         void appendNetworkLong(const boost::uint32_t l)
00191         {
00192                 resize(_size + 4);
00193                 _data[_size - 4] = l >> 24;
00194                 _data[_size - 3] = (l >> 16) & 0xff;
00195                 _data[_size - 2] = (l >> 8) & 0xff;
00196                 _data[_size - 1] = l & 0xff;
00197         }
00198 
00200         //
00207         void append(const SimpleBuffer& buf)
00208         {
00209                 size_t incomingDataSize = buf.size();
00210                 const boost::uint8_t* incomingData = buf.data();
00211                 append(incomingData, incomingDataSize);
00212         }
00213 
00214 private:
00215         size_t _size;
00216         size_t _capacity;
00217 
00218         boost::scoped_array<boost::uint8_t> _data;
00219 };
00220 
00221 
00222 }       // namespace gnash
00223 
00224 #endif // GNASH_SIMPLEBUFFER_H