#include "gats-qt/gatsstream.h" #include "gats-qt/object.h" #ifdef WIN32 #include #else #include #endif #include Gats::GatsStream::GatsStream( QIODevice &rStream ) : rStream( rStream ) { } Gats::GatsStream::~GatsStream() { } Gats::Object *Gats::GatsStream::readObject() { char buf[1500]; do { if( qbRead.size() < 5 ) { int iRead = rStream.read( buf, 5-qbRead.size() ); qbRead.append( buf, iRead ); if( qbRead.size() < 5 ) return NULL; } } while( !skipReadNulls() ); uint8_t uVer; uVer = qbRead[0]; int32_t iSize; memcpy( &iSize, qbRead.constData()+1, 4 ); iSize = ntohl( iSize ); while( qbRead.size() < iSize ) { int32_t iRead = iSize - qbRead.size(); if( iRead > 1500 ) iRead = 1500; int32_t iReal = rStream.read( buf, iRead ); qbRead.append( buf, iReal ); if( iReal < iRead ) { return NULL; } } if( qbRead.size() < iSize ) { return NULL; } QBuffer rTmp( &qbRead ); rTmp.open( QIODevice::ReadOnly ); rTmp.seek( 5 ); Gats::Object *pObj = Gats::Object::read( rTmp ); qbRead.clear(); emit objectRead( pObj ); return pObj; } void Gats::GatsStream::writeObject( Gats::Object *pObject ) { QIODevice *pTmp; if( rStream.isSequential() ) { pTmp = new QBuffer(); pTmp->open( QIODevice::WriteOnly ); } else { pTmp = &rStream; } uint8_t uBuf = 1; uint32_t iSize = 0; pTmp->write( (const char *)&uBuf, 1 ); uint64_t iSizePos = pTmp->pos(); pTmp->write( (const char *)&iSize, 4 ); pObject->write( *pTmp ); iSize = htonl( pTmp->pos() ); uint64_t iEndPos = pTmp->pos(); pTmp->seek( iSizePos ); pTmp->write( (const char *)&iSize, 4 ); if( rStream.isSequential() ) { pTmp->close(); rStream.write( ((QBuffer *)pTmp)->data() ); delete pTmp; } else { pTmp->seek( iSizePos ); } } bool Gats::GatsStream::skipReadNulls() { bool bHaveSeeked = false; for(;;) { if( qbRead.size() == 0 ) return false; if( qbRead.at(0) != 0 ) return !bHaveSeeked; //true; else { qbRead.remove( 0, 1 ); bHaveSeeked = true; } } }