From e0a6331142c0e79304ffe91f2ff00ac68d031f3c Mon Sep 17 00:00:00 2001 From: "Uwe L. Korn" Date: Sun, 16 Jun 2013 19:02:08 +0200 Subject: [PATCH] Pimple BufferIoDevice --- src/libtomahawk/network/BufferIoDevice.cpp | 109 +++++++++++++++------ src/libtomahawk/network/BufferIoDevice.h | 16 +-- src/libtomahawk/network/BufferIoDevice_p.h | 47 +++++++++ 3 files changed, 133 insertions(+), 39 deletions(-) create mode 100644 src/libtomahawk/network/BufferIoDevice_p.h diff --git a/src/libtomahawk/network/BufferIoDevice.cpp b/src/libtomahawk/network/BufferIoDevice.cpp index d8a7d622f..0f79c2a27 100644 --- a/src/libtomahawk/network/BufferIoDevice.cpp +++ b/src/libtomahawk/network/BufferIoDevice.cpp @@ -2,6 +2,7 @@ * * Copyright 2010-2011, Christian Muehlhaeuser * Copyright 2010-2011, Jeff Mitchell + * Copyright 2013, Uwe L. Korn * * Tomahawk is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -17,7 +18,7 @@ * along with Tomahawk. If not, see . */ -#include "BufferIoDevice.h" +#include "BufferIoDevice_p.h" #include #include @@ -30,18 +31,23 @@ BufferIODevice::BufferIODevice( unsigned int size, QObject* parent ) : QIODevice( parent ) - , m_size( size ) - , m_received( 0 ) - , m_pos( 0 ) + , d_ptr( new BufferIODevicePrivate( this, size ) ) { } +BufferIODevice::~BufferIODevice() +{ + delete d_ptr; +} + + bool BufferIODevice::open( OpenMode mode ) { + Q_D( BufferIODevice ); Q_UNUSED( mode ); - QMutexLocker lock( &m_mut ); + QMutexLocker lock( &d->mut ); qDebug() << Q_FUNC_INFO; QIODevice::open( QIODevice::ReadOnly | QIODevice::Unbuffered ); // FIXME? @@ -52,7 +58,8 @@ BufferIODevice::open( OpenMode mode ) void BufferIODevice::close() { - QMutexLocker lock( &m_mut ); + Q_D( BufferIODevice ); + QMutexLocker lock( &d->mut ); qDebug() << Q_FUNC_INFO; QIODevice::close(); @@ -62,16 +69,17 @@ BufferIODevice::close() bool BufferIODevice::seek( qint64 pos ) { - qDebug() << Q_FUNC_INFO << pos << m_size; + Q_D( BufferIODevice ); + qDebug() << Q_FUNC_INFO << pos << d->size; - if ( pos >= m_size ) + if ( pos >= d->size ) return false; int block = blockForPos( pos ); if ( isBlockEmpty( block ) ) emit blockRequest( block ); - m_pos = pos; + d->pos = pos; qDebug() << "Finished seeking"; return true; @@ -81,30 +89,40 @@ BufferIODevice::seek( qint64 pos ) void BufferIODevice::seeked( int block ) { - qDebug() << Q_FUNC_INFO << block << m_size; + Q_D( BufferIODevice ); + qDebug() << Q_FUNC_INFO << block << d->size; } void BufferIODevice::inputComplete( const QString& errmsg ) { + Q_D( BufferIODevice ); qDebug() << Q_FUNC_INFO; setErrorString( errmsg ); - m_size = m_received; + d->size = d->received; emit readChannelFinished(); } +bool +BufferIODevice::isSequential() const +{ + return false; +} + + void BufferIODevice::addData( int block, const QByteArray& ba ) { + Q_D( BufferIODevice ); { - QMutexLocker lock( &m_mut ); + QMutexLocker lock( &d->mut ); - while ( m_buffer.count() <= block ) - m_buffer << QByteArray(); + while ( d->buffer.count() <= block ) + d->buffer << QByteArray(); - m_buffer.replace( block, ba ); + d->buffer.replace( block, ba ); } // If this was the last block of the transfer, check if we need to fill up gaps @@ -116,7 +134,7 @@ BufferIODevice::addData( int block, const QByteArray& ba ) } } - m_received += ba.count(); + d->received += ba.count(); emit bytesWritten( ba.count() ); emit readyRead(); } @@ -125,21 +143,24 @@ BufferIODevice::addData( int block, const QByteArray& ba ) qint64 BufferIODevice::bytesAvailable() const { - return m_size - m_pos; + Q_D( const BufferIODevice ); + + return d->size - d->pos; } qint64 BufferIODevice::readData( char* data, qint64 maxSize ) { + Q_D( BufferIODevice ); // qDebug() << Q_FUNC_INFO << m_pos << maxSize << 1; if ( atEnd() ) return 0; QByteArray ba; - ba.append( getData( m_pos, maxSize ) ); - m_pos += ba.count(); + ba.append( getData( d->pos, maxSize ) ); + d->pos += ba.count(); // qDebug() << Q_FUNC_INFO << maxSize << ba.count() << 2; memcpy( data, ba.data(), ba.count() ); @@ -162,26 +183,44 @@ BufferIODevice::writeData( const char* data, qint64 maxSize ) qint64 BufferIODevice::size() const { - qDebug() << Q_FUNC_INFO << m_size; - return m_size; + Q_D( const BufferIODevice ); + qDebug() << Q_FUNC_INFO << d->size; + return d->size; } bool BufferIODevice::atEnd() const { + Q_D( const BufferIODevice ); // qDebug() << Q_FUNC_INFO << ( m_size <= m_pos ); - return ( m_size <= m_pos ); + return ( d->size <= d->pos ); +} + + +qint64 +BufferIODevice::pos() const +{ + Q_D( const BufferIODevice ); + return d->pos; } void BufferIODevice::clear() { - QMutexLocker lock( &m_mut ); + Q_D( BufferIODevice ); + QMutexLocker lock( &d->mut ); - m_pos = 0; - m_buffer.clear(); + d->pos = 0; + d->buffer.clear(); +} + + +QIODevice::OpenMode +BufferIODevice::openMode() const +{ + return QIODevice::ReadOnly | QIODevice::Unbuffered; } @@ -217,8 +256,10 @@ BufferIODevice::offsetForPos( qint64 pos ) const int BufferIODevice::nextEmptyBlock() const { + Q_D( const BufferIODevice ); + int i = 0; - foreach( const QByteArray& ba, m_buffer ) + foreach( const QByteArray& ba, d->buffer ) { if ( ba.isEmpty() ) return i; @@ -236,9 +277,11 @@ BufferIODevice::nextEmptyBlock() const int BufferIODevice::maxBlocks() const { - int i = m_size / BLOCKSIZE; + Q_D( const BufferIODevice ); - if ( ( m_size % BLOCKSIZE ) > 0 ) + int i = d->size / BLOCKSIZE; + + if ( ( d->size % BLOCKSIZE ) > 0 ) i++; return i; @@ -248,22 +291,24 @@ BufferIODevice::maxBlocks() const bool BufferIODevice::isBlockEmpty( int block ) const { - if ( block >= m_buffer.count() ) + Q_D( const BufferIODevice ); + if ( block >= d->buffer.count() ) return true; - return m_buffer.at( block ).isEmpty(); + return d->buffer.at( block ).isEmpty(); } QByteArray BufferIODevice::getData( qint64 pos, qint64 size ) { + Q_D( BufferIODevice ); // qDebug() << Q_FUNC_INFO << pos << size << 1; QByteArray ba; int block = blockForPos( pos ); int offset = offsetForPos( pos ); - QMutexLocker lock( &m_mut ); + QMutexLocker lock( &d->mut ); while( ba.count() < size ) { if ( block > maxBlocks() ) @@ -272,7 +317,7 @@ BufferIODevice::getData( qint64 pos, qint64 size ) if ( isBlockEmpty( block ) ) break; - ba.append( m_buffer.at( block++ ).mid( offset ) ); + ba.append( d->buffer.at( block++ ).mid( offset ) ); } // qDebug() << Q_FUNC_INFO << pos << size << 2; diff --git a/src/libtomahawk/network/BufferIoDevice.h b/src/libtomahawk/network/BufferIoDevice.h index a118b9edd..86c96c147 100644 --- a/src/libtomahawk/network/BufferIoDevice.h +++ b/src/libtomahawk/network/BufferIoDevice.h @@ -1,6 +1,7 @@ /* === This file is part of Tomahawk Player - === * * Copyright 2010-2011, Christian Muehlhaeuser + * Copyright 2013, Uwe L. Korn * * Tomahawk is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -23,12 +24,15 @@ #include #include +class BufferIODevicePrivate; + class BufferIODevice : public QIODevice { Q_OBJECT public: explicit BufferIODevice( unsigned int size = 0, QObject* parent = 0 ); + ~BufferIODevice(); virtual bool open( OpenMode mode ); virtual void close(); @@ -39,16 +43,16 @@ public: virtual qint64 bytesAvailable() const; virtual qint64 size() const; virtual bool atEnd() const; - virtual qint64 pos() const { return m_pos; } + virtual qint64 pos() const; void addData( int block, const QByteArray& ba ); void clear(); - OpenMode openMode() const { return QIODevice::ReadOnly | QIODevice::Unbuffered; } + OpenMode openMode() const; void inputComplete( const QString& errmsg = "" ); - virtual bool isSequential() const { return false; } + virtual bool isSequential() const; static unsigned int blockSize(); @@ -68,11 +72,9 @@ private: int offsetForPos( qint64 pos ) const; QByteArray getData( qint64 pos, qint64 size ); - QList m_buffer; - mutable QMutex m_mut; //const methods need to lock - unsigned int m_size, m_received; + Q_DECLARE_PRIVATE( BufferIODevice ) + BufferIODevicePrivate* d_ptr; - unsigned int m_pos; }; #endif // BUFFERIODEVICE_H diff --git a/src/libtomahawk/network/BufferIoDevice_p.h b/src/libtomahawk/network/BufferIoDevice_p.h new file mode 100644 index 000000000..c5170e64a --- /dev/null +++ b/src/libtomahawk/network/BufferIoDevice_p.h @@ -0,0 +1,47 @@ +/* === This file is part of Tomahawk Player - === + * + * Copyright 2010-2011, Christian Muehlhaeuser + * Copyright 2013, Uwe L. Korn + * + * Tomahawk is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Tomahawk is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Tomahawk. If not, see . + */ + +#ifndef BUFFERIODEVICE_P_H +#define BUFFERIODEVICE_P_H + +#include "BufferIoDevice.h" + +class BufferIODevicePrivate +{ +public: + BufferIODevicePrivate( BufferIODevice* q, unsigned int size = 0 ) + : q_ptr ( q ) + , size( size ) + , received( 0 ) + , pos( 0 ) + + { + } + BufferIODevice* q_ptr; + Q_DECLARE_PUBLIC ( BufferIODevice ) + +private: + QList buffer; + mutable QMutex mut; + unsigned int size; + unsigned int received; + unsigned int pos; +}; + +#endif // BUFFERIODEVICE_P_H