From 8baf7e1e75a185c742dc6d5b27e50058635e5522 Mon Sep 17 00:00:00 2001 From: Mike Buland Date: Mon, 10 May 2010 03:31:08 +0000 Subject: Added the new QueueBuf. It's brilliant, and I've wanted it for a long time. ...I mean brilliant as in cool. --- src/queuebuf.cpp | 233 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 233 insertions(+) create mode 100644 src/queuebuf.cpp (limited to 'src/queuebuf.cpp') diff --git a/src/queuebuf.cpp b/src/queuebuf.cpp new file mode 100644 index 0000000..9404164 --- /dev/null +++ b/src/queuebuf.cpp @@ -0,0 +1,233 @@ +/* + * Copyright (C) 2007-2010 Xagasoft, All rights reserved. + * + * This file is part of the libbu++ library and is released under the + * terms of the license contained in the file LICENSE. + */ + +#include "bu/queuebuf.h" + +#include "bu/sio.h" +using Bu::sio; + +Bu::QueueBuf::QueueBuf( int iBlockSize /*=256*/ ) : + iBlockSize( iBlockSize ), + iReadOffset( 0 ), + iWriteOffset( 0 ), + iTotalSize( 0 ) +{ +} + +Bu::QueueBuf::~QueueBuf() +{ + for( BlockList::iterator i = lBlocks.begin(); i; i++ ) + delete[] *i; +} + +int Bu::QueueBuf::getSize() +{ + return iTotalSize; +} + +void Bu::QueueBuf::close() +{ + for( BlockList::iterator i = lBlocks.begin(); i; i++ ) + delete[] *i; + lBlocks.clear(); + iReadOffset = iWriteOffset = iTotalSize = 0; +} + +size_t Bu::QueueBuf::read( void *pRawBuf, size_t nBytes ) +{ + if( nBytes <= 0 ) + return 0; + + if( lBlocks.isEmpty() ) + return 0; + + size_t iLeft = nBytes; + char *pBuf = (char *)pRawBuf; + + while( iLeft > 0 && iTotalSize > 0 ) + { + if( iReadOffset == iBlockSize ) + { + removeBlock(); + if( lBlocks.isEmpty() ) + { + return nBytes-iLeft; + } + iReadOffset = 0; + } + char *pBlock = lBlocks.first(); + size_t iCopy = iBlockSize-iReadOffset; + if( iLeft < iCopy ) + iCopy = iLeft; + if( iTotalSize < iCopy ) + iCopy = iTotalSize; + memcpy( pBuf, pBlock+iReadOffset, iCopy ); + iReadOffset += iCopy; + iLeft -= iCopy; + pBuf += iCopy; + iTotalSize -= iCopy; + sio << "Read " << iCopy << " bytes, new size: " << iTotalSize << sio.nl; + } + + return nBytes - iLeft; +} + +size_t QueueBuf::peek( void *pBuf, size_t nBytes ) +{ + if( nBytes <= 0 ) + return 0; + + if( lBlocks.isEmpty() ) + return 0; + + size_t iLeft = nBytes; + char *pBuf = (char *)pRawBuf; + + int iTmpReadOffset = iReadOffset; + int iTmpRemSize = iTotalSize; + while( iLeft > 0 && iTmpRemSize > 0 ) + { + + // Switching to use temp variables instead of iReadOffset and iTotalSize + if( iReadOffset == iBlockSize ) + { + if( lBlocks.isEmpty() ) + { + return nBytes-iLeft; + } + iReadOffset = 0; + } + char *pBlock = lBlocks.first(); + size_t iCopy = iBlockSize-iReadOffset; + if( iLeft < iCopy ) + iCopy = iLeft; + if( iTotalSize < iCopy ) + iCopy = iTotalSize; + memcpy( pBuf, pBlock+iReadOffset, iCopy ); + iReadOffset += iCopy; + iLeft -= iCopy; + pBuf += iCopy; + iTotalSize -= iCopy; + sio << "Read " << iCopy << " bytes, new size: " << iTotalSize << sio.nl; + } + + return nBytes - iLeft; +} + +size_t Bu::QueueBuf::write( const void *pRawBuf, size_t nBytes ) +{ + if( nBytes <= 0 ) + return 0; + + if( lBlocks.isEmpty() ) + { + addBlock(); + iWriteOffset = 0; + } + size_t iLeft = nBytes; + const char *pBuf = (const char *)pRawBuf; + + while( iLeft > 0 ) + { + if( iWriteOffset == iBlockSize ) + { + addBlock(); + iWriteOffset = 0; + } + char *pBlock = lBlocks.last(); + size_t iCopy = iBlockSize-iWriteOffset; + if( iLeft < iCopy ) + iCopy = iLeft; + memcpy( pBlock+iWriteOffset, pBuf, iCopy ); + iWriteOffset += iCopy; + iLeft -= iCopy; + pBuf += iCopy; + iTotalSize += iCopy; + sio << "Wrote " << iCopy << " bytes, new size: " << iTotalSize << sio.nl; + } + + return nBytes; +} + +long Bu::QueueBuf::tell() +{ + return -1; +} + +void Bu::QueueBuf::seek( long ) +{ +} + +void Bu::QueueBuf::setPos( long ) +{ +} + +void Bu::QueueBuf::setPosEnd( long ) +{ +} + +bool Bu::QueueBuf::isEos() +{ + return iTotalSize == 0; +} + +bool Bu::QueueBuf::isOpen() +{ + return true; +} + +void Bu::QueueBuf::flush() +{ +} + +bool Bu::QueueBuf::canRead() +{ + return iTotalSize > 0; +} + +bool Bu::QueueBuf::canWrite() +{ + return true; +} + +bool Bu::QueueBuf::isReadable() +{ + return true; +} + +bool Bu::QueueBuf::isWritable() +{ + return true; +} + +bool Bu::QueueBuf::isSeekable() +{ + return false; +} + +bool Bu::QueueBuf::isBlocking() +{ + return false; +} + +void Bu::QueueBuf::setBlocking( bool ) +{ +} + +void Bu::QueueBuf::addBlock() +{ + lBlocks.append( new char[iBlockSize] ); + sio << "Added new block." << sio.nl; +} + +void Bu::QueueBuf::removeBlock() +{ + delete[] lBlocks.first(); + lBlocks.erase( lBlocks.begin() ); + sio << "Removed block." << sio.nl; +} + -- cgit v1.2.3