// // Buffer.h // // $Id: //poco/1.4/Foundation/include/Poco/Buffer.h#2 $ // // Library: Foundation // Package: Core // Module: Buffer // // Definition of the Buffer class. // // Copyright (c) 2006, Applied Informatics Software Engineering GmbH. // and Contributors. // // Permission is hereby granted, free of charge, to any person or organization // obtaining a copy of the software and accompanying documentation covered by // this license (the "Software") to use, reproduce, display, distribute, // execute, and transmit the Software, and to prepare derivative works of the // Software, and to permit third-parties to whom the Software is furnished to // do so, all subject to the following: // // The copyright notices in the Software and this entire statement, including // the above license grant, this restriction and the following disclaimer, // must be included in all copies of the Software, in whole or in part, and // all derivative works of the Software, unless such copies or derivative // works are solely in the form of machine-executable object code generated by // a source language processor. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT // SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE // FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. // #ifndef Foundation_Buffer_INCLUDED #define Foundation_Buffer_INCLUDED #include "Poco/Foundation.h" #include #include namespace Poco { template class Buffer /// A buffer class that allocates a buffer of a given type and size. /// Buffer can be zero-size, resized, copy-constructed and assigned. /// Memory allocation, resizing and deallocation is managed automatically. /// /// This class is useful everywhere where a temporary buffer /// is needed. { public: Buffer(std::size_t size): _size(size), _ptr(size ? new T[size] : 0) /// Creates and allocates the Buffer. { } Buffer(): _size(0), _ptr(0) /// Creates the Buffer. { } Buffer(const Buffer& other): /// Copy constructor. _size(other._size), _ptr(other._size ? new T[other._size] : 0) { if (_size) std::memcpy(_ptr, other._ptr, _size * sizeof(T)); } Buffer& operator = (const Buffer& other) /// Assignment operator. { if (this != &other) { Buffer tmp(other); swap(tmp); } return *this; } ~Buffer() /// Destroys the Buffer. { delete [] _ptr; } void swap(Buffer& other) /// Swaps the buffer with another one. { using std::swap; swap(_ptr, other._ptr); swap(_size, other._size); } std::size_t size() const /// Returns the size of the buffer. { return _size; } void clear() /// Sets the contents of the bufer to zero. { std::memset(_ptr, 0, _size * sizeof(T)); } void resize(std::size_t newSize, bool preserve = false) /// Resizes the buffer. If preserve is true, the contents /// of the buffer is preserved. If the newSize is smaller /// than the current size, data truncation will occur. /// /// For efficiency sake, the default behavior is not to /// preserve the contents. { if (preserve) { if (_size == newSize) return; Buffer tmp; tmp = *this; recreate(newSize); std::size_t size = _size < tmp._size ? _size : tmp._size; std::memcpy(_ptr, tmp._ptr, size * sizeof(T)); return; } else if (_size == newSize) { clear(); return; } recreate(newSize); } void append(const T* buf, std::size_t sz) /// Resizes this buffer and appends the argument buffer. { if (0 == sz) return; std::size_t oldSize = _size; resize(_size + sz, true); std::memcpy(_ptr + oldSize, buf, sz); } void append(const Buffer& buf) /// Resizes this buffer and appends the argument buffer. { append(buf.begin(), buf.size()); } std::size_t elementSize() const /// Returns the size of the buffer element. { return sizeof(T); } std::size_t byteCount() const /// Returns the total length of the buffer in bytes. { return _size * sizeof(T); } T* begin() /// Returns a pointer to the beginning of the buffer. { return _ptr; } const T* begin() const /// Returns a pointer to the beginning of the buffer. { return _ptr; } T* end() /// Returns a pointer to end of the buffer. { return _ptr + _size; } const T* end() const /// Returns a pointer to the end of the buffer. { return _ptr + _size; } bool isEmpty() const /// Return true if buffer is empty. { return 0 == _size; } T& operator [] (std::size_t index) { poco_assert (index < _size); return _ptr[index]; } const T& operator [] (std::size_t index) const { poco_assert (index < _size); return _ptr[index]; } private: void recreate(std::size_t newSize) { if (newSize != _size) { delete [] _ptr; if (0 == newSize) _ptr = 0; else _ptr = new T[newSize]; _size = newSize; } } std::size_t _size; T* _ptr; }; } // namespace Poco #endif // Foundation_Buffer_INCLUDED