/* * IOBuffer.cpp * * Created on: Sep 28, 2010 * Author: daniele */ #include #include #include #include #include #include "BufferObserver.h" #include "IOBuffer.h" #include "Chunk.h" std::size_t IOBuffer::append( Chunk &a ) { _push_back(a); _notify(); return a.size(); } std::size_t IOBuffer::prepend( Chunk &a ) { _push_front(a); _offset -= a.size(); return a.size(); } void IOBuffer::_push_back( Chunk &a ) { _data.insert( _data.end(), a.ptr(), a.ptr() + a.size() ); } void IOBuffer::_push_front( Chunk &a ) { _data.insert( _data.begin(), a.ptr(), a.ptr() + a.size() ); } Chunk IOBuffer::pop( std::size_t size ) { if(!size) return 0; if ( available(_offset) < size ) return Chunk( _offset ); Chunk c = Chunk( &_data[0], BufferDescriptor(_offset, size) ); _data.erase( _data.begin(), _data.begin() + size ); _offset += size; return c; } Chunk IOBuffer::range( BufferDescriptor descriptor ) { if ( ! this->descriptor().contains( descriptor ) ) return Chunk( "", BufferDescriptor( descriptor.offset(), 0)); std::size_t index = descriptor.offset() - _offset; return Chunk(&_data[index], BufferDescriptor(descriptor.offset(), descriptor.size()) ); } Chunk IOBuffer::range( std::size_t start_offset, std::size_t size ) { return range( BufferDescriptor(start_offset, size) ); } std::size_t IOBuffer::flush( std::size_t to_offset ) { assert( to_offset >= _offset ); std::size_t size = to_offset - _offset; // if we don't have enough data for flushing, flush what's available if (size > this->size()) size = this->size(); _data.erase( _data.begin(), _data.begin() + size); _offset += size; return size; } std::size_t IOBuffer::available(std::size_t start_offset) { // if the starting offset falls outside our buffer, return 0 if (start_offset < _offset || start_offset > _offset + this->size()) return 0; else return (_offset + _data.size()) - start_offset; } void IOBuffer::register_observer( ::prototype::BufferObserver& observer ) { //std::cout << "[IOBuffer] registering observer for source buffer." << std::endl; _observers.push_front( &observer ); } void IOBuffer::remove_observer( ::prototype::BufferObserver& observer ) { _observers.remove( &observer ); } void IOBuffer::_notify() { BOOST_FOREACH( ::prototype::BufferObserver* observer, _observers ) observer->update(); } IOBuffer::IOBuffer() : _offset(0) { } IOBuffer::~IOBuffer() { } .