From 91f9d6e8b371f339dbcc16541054f9cb371d0ec9 Mon Sep 17 00:00:00 2001 From: Mike Buland Date: Fri, 13 Apr 2012 23:34:27 +0000 Subject: Myriad is actually fine, I double checked it for cross-platformed-ness. It doesn't yet normalize the endian-ness, and I guess at this point to maintain compatibility I'll have to make it a little endian format. I would still like to add better thread-safety to it, but that's about it. --- src/stable/myriadstream.cpp | 309 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 309 insertions(+) create mode 100644 src/stable/myriadstream.cpp (limited to 'src/stable/myriadstream.cpp') diff --git a/src/stable/myriadstream.cpp b/src/stable/myriadstream.cpp new file mode 100644 index 0000000..e6e94bc --- /dev/null +++ b/src/stable/myriadstream.cpp @@ -0,0 +1,309 @@ +/* + * Copyright (C) 2007-2011 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/myriadstream.h" + +#include + +// #define MYRIAD_STREAM_DEBUG 1 + +#ifdef MYRIAD_STREAM_DEBUG +#include "bu/sio.h" + +using Bu::sio; +using Bu::Fmt; +#endif + +Bu::MyriadStream::MyriadStream( Bu::Myriad &rMyriad, + Bu::Myriad::Stream *pStream ) : + rMyriad( rMyriad ), + pStream( pStream ), + pCurBlock( NULL ), + iPos( 0 ) +{ +#ifdef MYRIAD_STREAM_DEBUG + sio << "MyriadStream: " << __LINE__ << ": Created, iId=" << pStream->iId << ", iSize=" + << pStream->iSize << sio.nl; +#endif + //pCurBlock = rMyriad.newBlock(); + //rMyriad.getBlock( uStream, pCurBlock ); + //uSize = pCurBlock->uBytesUsed; +} + +Bu::MyriadStream::~MyriadStream() +{ + if( pCurBlock ) + rMyriad.releaseBlock( pCurBlock ); + //rMyriad.updateStreamSize( uStream, uSize ); + //rMyriad.deleteBlock( pCurBlock ); +} + +void Bu::MyriadStream::close() +{ +} + +Bu::size Bu::MyriadStream::read( void *pBuf, Bu::size nBytes ) +{ +#ifdef MYRIAD_STREAM_DEBUG + sio << "MyriadStream: read: " << __LINE__ << ": Started, asked to read " << nBytes << "b." + << sio.nl; +#endif + if( nBytes > (Bu::size)pStream->iSize-iPos ) + nBytes = pStream->iSize-iPos; + if( nBytes <= 0 ) + return 0; + int iLeft = nBytes; +#ifdef MYRIAD_STREAM_DEBUG + sio << "MyriadStream: read: " << __LINE__ << ": Started, going to read " << nBytes << "b." + << sio.nl; +#endif + if( pCurBlock == NULL ) + { +#ifdef MYRIAD_STREAM_DEBUG + sio << "MyriadStream: read: " << __LINE__ << ": No block loaded, loading initial block." + << sio.nl; +#endif + pCurBlock = rMyriad.getBlock( + pStream->aBlocks[iPos/rMyriad.iBlockSize] + ); + } + while( iLeft > 0 ) + { + int iCurBlock = pStream->aBlocks[iPos/rMyriad.iBlockSize]; + if( pCurBlock->iBlockIndex != iCurBlock ) + { +#ifdef MYRIAD_STREAM_DEBUG + sio << "MyriadStream: read: " << __LINE__ << ": Loading new block " << iCurBlock << "." + << sio.nl; +#endif + rMyriad.releaseBlock( pCurBlock ); + pCurBlock = rMyriad.getBlock( iCurBlock ); + } + + int iAmnt = Bu::min( + Bu::min( + rMyriad.iBlockSize - iPos%rMyriad.iBlockSize, + iLeft + ), + pStream->iSize-iPos + ); +#ifdef MYRIAD_STREAM_DEBUG + sio << "MyriadStream: read: " << __LINE__ << ": Copying out bytes: " + << iPos << "(" << (iPos%rMyriad.iBlockSize) << ")+" + << iAmnt + << ", " << iLeft << "b left." << sio.nl; +#endif + memcpy( + pBuf, + pCurBlock->pData+(iPos%rMyriad.iBlockSize), + iAmnt + ); + iPos += iAmnt; + pBuf = &((char *)pBuf)[iAmnt]; + iLeft -= iAmnt; + } + return nBytes; +} + +Bu::size Bu::MyriadStream::write( const void *pBuf, Bu::size nBytes ) +{ + if( nBytes <= 0 ) + return 0; + +#ifdef MYRIAD_STREAM_DEBUG + sio << "MyriadStream: write: " << __LINE__ << ": Started, asked to write " << nBytes << "b." + << sio.nl; +#endif + if( nBytes <= 0 ) + return 0; + int iLeft = nBytes; + /* + if( pCurBlock == NULL ) + { +#ifdef MYRIAD_STREAM_DEBUG + sio << "MyriadStream: write: No block loaded, loading initial block." + << sio.nl; +#endif + pCurBlock = rMyriad.getBlock( + pStream->aBlocks[iPos/rMyriad.iBlockSize] + ); + }*/ + + while( iLeft > 0 ) + { + int iCurBlock; + if( iPos/rMyriad.iBlockSize < pStream->aBlocks.getSize() ) + { + iCurBlock = pStream->aBlocks[iPos/rMyriad.iBlockSize]; + } + else + { + iCurBlock = rMyriad.streamAddBlock( pStream ); +#ifdef MYRIAD_STREAM_DEBUG + sio << "MyriadStream: write: " << __LINE__ << ": New block allocated and appended: " + << iCurBlock << "." << sio.nl; + +#endif + } + if( !pCurBlock || pCurBlock->iBlockIndex != iCurBlock ) + { +#ifdef MYRIAD_STREAM_DEBUG + sio << "MyriadStream: write: " << __LINE__ << ": Loading new block " << iCurBlock << "." + << sio.nl; +#endif + rMyriad.releaseBlock( pCurBlock ); + pCurBlock = rMyriad.getBlock( iCurBlock ); + } + pCurBlock->bChanged = true; + + // There are two main writing modes when it comes down to it. + // Overwrite mode and append mode. Append is what pretty much always + // happens when creating a new stream. + if( iPos < pStream->iSize ) + { + int iAmnt = Bu::min( + Bu::min( + rMyriad.iBlockSize - iPos%rMyriad.iBlockSize, + iLeft + ), + pStream->iSize-iPos + ); +#ifdef MYRIAD_STREAM_DEBUG + sio << "MyriadStream: write (ovr): " << __LINE__ << ": Copying in bytes: " + << (iPos%rMyriad.iBlockSize) << "+" + << iAmnt + << ", " << iLeft << "b left." << sio.nl; +#endif + memcpy( + pCurBlock->pData+(iPos%rMyriad.iBlockSize), + pBuf, + iAmnt + ); + iPos += iAmnt; + pBuf = &((char *)pBuf)[iAmnt]; + iLeft -= iAmnt; + } + else + { + int iAmnt = Bu::min( + rMyriad.iBlockSize - iPos%rMyriad.iBlockSize, + iLeft + ); +#ifdef MYRIAD_STREAM_DEBUG + sio << "MyriadStream: write (app): " << __LINE__ << ": Copying in bytes: " + << (iPos%rMyriad.iBlockSize) << "+" + << iAmnt + << ", " << iLeft << "b left." << sio.nl; +#endif + memcpy( + pCurBlock->pData+(iPos%rMyriad.iBlockSize), + pBuf, + iAmnt + ); + iPos += iAmnt; + pStream->iSize += iAmnt; + rMyriad.headerChanged(); + pBuf = &((char *)pBuf)[iAmnt]; + iLeft -= iAmnt; + } + } + + return nBytes; +} + +Bu::size Bu::MyriadStream::tell() +{ + return iPos; +} + +void Bu::MyriadStream::seek( Bu::size offset ) +{ + iPos += offset; +} + +void Bu::MyriadStream::setPos( Bu::size pos ) +{ + iPos = pos; +} + +void Bu::MyriadStream::setPosEnd( Bu::size pos ) +{ + iPos = pStream->iSize-pos; +} + +bool Bu::MyriadStream::isEos() +{ + return iPos >= pStream->iSize; +} + +bool Bu::MyriadStream::isOpen() +{ + return true; +} + +void Bu::MyriadStream::flush() +{ +} + +bool Bu::MyriadStream::canRead() +{ + return true; +} + +bool Bu::MyriadStream::canWrite() +{ + return true; +} + +bool Bu::MyriadStream::isReadable() +{ + return true; +} + +bool Bu::MyriadStream::isWritable() +{ + return true; +} + +bool Bu::MyriadStream::isSeekable() +{ + return true; +} + +bool Bu::MyriadStream::isBlocking() +{ + return true; +} + +void Bu::MyriadStream::setBlocking( bool /*bBlocking*/ ) +{ +} + +void Bu::MyriadStream::setSize( Bu::size iSize ) +{ + if( iSize < 0 ) + iSize = 0; + rMyriad.setStreamSize( pStream, iSize ); + if( iPos > iSize ) + iPos = iSize; +} + +Bu::size Bu::MyriadStream::getSize() const +{ + return pStream->iSize; +} + +Bu::size Bu::MyriadStream::getBlockSize() const +{ + return rMyriad.getBlockSize(); +} + +Bu::String Bu::MyriadStream::getLocation() const +{ + return Bu::String("%1").arg( pStream->iId ); +} + -- cgit v1.2.3