mirror of
https://github.com/tomahawk-player/tomahawk.git
synced 2025-08-05 21:57:41 +02:00
Pimple BufferIoDevice
This commit is contained in:
@@ -2,6 +2,7 @@
|
|||||||
*
|
*
|
||||||
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
||||||
* Copyright 2010-2011, Jeff Mitchell <jeff@tomahawk-player.org>
|
* Copyright 2010-2011, Jeff Mitchell <jeff@tomahawk-player.org>
|
||||||
|
* Copyright 2013, Uwe L. Korn <uwelk@xhochy.com>
|
||||||
*
|
*
|
||||||
* Tomahawk is free software: you can redistribute it and/or modify
|
* Tomahawk is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -17,7 +18,7 @@
|
|||||||
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "BufferIoDevice.h"
|
#include "BufferIoDevice_p.h"
|
||||||
|
|
||||||
#include <QCoreApplication>
|
#include <QCoreApplication>
|
||||||
#include <QThread>
|
#include <QThread>
|
||||||
@@ -30,18 +31,23 @@
|
|||||||
|
|
||||||
BufferIODevice::BufferIODevice( unsigned int size, QObject* parent )
|
BufferIODevice::BufferIODevice( unsigned int size, QObject* parent )
|
||||||
: QIODevice( parent )
|
: QIODevice( parent )
|
||||||
, m_size( size )
|
, d_ptr( new BufferIODevicePrivate( this, size ) )
|
||||||
, m_received( 0 )
|
|
||||||
, m_pos( 0 )
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BufferIODevice::~BufferIODevice()
|
||||||
|
{
|
||||||
|
delete d_ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
BufferIODevice::open( OpenMode mode )
|
BufferIODevice::open( OpenMode mode )
|
||||||
{
|
{
|
||||||
|
Q_D( BufferIODevice );
|
||||||
Q_UNUSED( mode );
|
Q_UNUSED( mode );
|
||||||
QMutexLocker lock( &m_mut );
|
QMutexLocker lock( &d->mut );
|
||||||
|
|
||||||
qDebug() << Q_FUNC_INFO;
|
qDebug() << Q_FUNC_INFO;
|
||||||
QIODevice::open( QIODevice::ReadOnly | QIODevice::Unbuffered ); // FIXME?
|
QIODevice::open( QIODevice::ReadOnly | QIODevice::Unbuffered ); // FIXME?
|
||||||
@@ -52,7 +58,8 @@ BufferIODevice::open( OpenMode mode )
|
|||||||
void
|
void
|
||||||
BufferIODevice::close()
|
BufferIODevice::close()
|
||||||
{
|
{
|
||||||
QMutexLocker lock( &m_mut );
|
Q_D( BufferIODevice );
|
||||||
|
QMutexLocker lock( &d->mut );
|
||||||
|
|
||||||
qDebug() << Q_FUNC_INFO;
|
qDebug() << Q_FUNC_INFO;
|
||||||
QIODevice::close();
|
QIODevice::close();
|
||||||
@@ -62,16 +69,17 @@ BufferIODevice::close()
|
|||||||
bool
|
bool
|
||||||
BufferIODevice::seek( qint64 pos )
|
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;
|
return false;
|
||||||
|
|
||||||
int block = blockForPos( pos );
|
int block = blockForPos( pos );
|
||||||
if ( isBlockEmpty( block ) )
|
if ( isBlockEmpty( block ) )
|
||||||
emit blockRequest( block );
|
emit blockRequest( block );
|
||||||
|
|
||||||
m_pos = pos;
|
d->pos = pos;
|
||||||
qDebug() << "Finished seeking";
|
qDebug() << "Finished seeking";
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -81,30 +89,40 @@ BufferIODevice::seek( qint64 pos )
|
|||||||
void
|
void
|
||||||
BufferIODevice::seeked( int block )
|
BufferIODevice::seeked( int block )
|
||||||
{
|
{
|
||||||
qDebug() << Q_FUNC_INFO << block << m_size;
|
Q_D( BufferIODevice );
|
||||||
|
qDebug() << Q_FUNC_INFO << block << d->size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
BufferIODevice::inputComplete( const QString& errmsg )
|
BufferIODevice::inputComplete( const QString& errmsg )
|
||||||
{
|
{
|
||||||
|
Q_D( BufferIODevice );
|
||||||
qDebug() << Q_FUNC_INFO;
|
qDebug() << Q_FUNC_INFO;
|
||||||
setErrorString( errmsg );
|
setErrorString( errmsg );
|
||||||
m_size = m_received;
|
d->size = d->received;
|
||||||
emit readChannelFinished();
|
emit readChannelFinished();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
BufferIODevice::isSequential() const
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
BufferIODevice::addData( int block, const QByteArray& ba )
|
BufferIODevice::addData( int block, const QByteArray& ba )
|
||||||
{
|
{
|
||||||
|
Q_D( BufferIODevice );
|
||||||
{
|
{
|
||||||
QMutexLocker lock( &m_mut );
|
QMutexLocker lock( &d->mut );
|
||||||
|
|
||||||
while ( m_buffer.count() <= block )
|
while ( d->buffer.count() <= block )
|
||||||
m_buffer << QByteArray();
|
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
|
// 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 bytesWritten( ba.count() );
|
||||||
emit readyRead();
|
emit readyRead();
|
||||||
}
|
}
|
||||||
@@ -125,21 +143,24 @@ BufferIODevice::addData( int block, const QByteArray& ba )
|
|||||||
qint64
|
qint64
|
||||||
BufferIODevice::bytesAvailable() const
|
BufferIODevice::bytesAvailable() const
|
||||||
{
|
{
|
||||||
return m_size - m_pos;
|
Q_D( const BufferIODevice );
|
||||||
|
|
||||||
|
return d->size - d->pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
qint64
|
qint64
|
||||||
BufferIODevice::readData( char* data, qint64 maxSize )
|
BufferIODevice::readData( char* data, qint64 maxSize )
|
||||||
{
|
{
|
||||||
|
Q_D( BufferIODevice );
|
||||||
// qDebug() << Q_FUNC_INFO << m_pos << maxSize << 1;
|
// qDebug() << Q_FUNC_INFO << m_pos << maxSize << 1;
|
||||||
|
|
||||||
if ( atEnd() )
|
if ( atEnd() )
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
QByteArray ba;
|
QByteArray ba;
|
||||||
ba.append( getData( m_pos, maxSize ) );
|
ba.append( getData( d->pos, maxSize ) );
|
||||||
m_pos += ba.count();
|
d->pos += ba.count();
|
||||||
|
|
||||||
// qDebug() << Q_FUNC_INFO << maxSize << ba.count() << 2;
|
// qDebug() << Q_FUNC_INFO << maxSize << ba.count() << 2;
|
||||||
memcpy( data, ba.data(), ba.count() );
|
memcpy( data, ba.data(), ba.count() );
|
||||||
@@ -162,26 +183,44 @@ BufferIODevice::writeData( const char* data, qint64 maxSize )
|
|||||||
qint64
|
qint64
|
||||||
BufferIODevice::size() const
|
BufferIODevice::size() const
|
||||||
{
|
{
|
||||||
qDebug() << Q_FUNC_INFO << m_size;
|
Q_D( const BufferIODevice );
|
||||||
return m_size;
|
qDebug() << Q_FUNC_INFO << d->size;
|
||||||
|
return d->size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
BufferIODevice::atEnd() const
|
BufferIODevice::atEnd() const
|
||||||
{
|
{
|
||||||
|
Q_D( const BufferIODevice );
|
||||||
// qDebug() << Q_FUNC_INFO << ( m_size <= m_pos );
|
// 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
|
void
|
||||||
BufferIODevice::clear()
|
BufferIODevice::clear()
|
||||||
{
|
{
|
||||||
QMutexLocker lock( &m_mut );
|
Q_D( BufferIODevice );
|
||||||
|
QMutexLocker lock( &d->mut );
|
||||||
|
|
||||||
m_pos = 0;
|
d->pos = 0;
|
||||||
m_buffer.clear();
|
d->buffer.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
QIODevice::OpenMode
|
||||||
|
BufferIODevice::openMode() const
|
||||||
|
{
|
||||||
|
return QIODevice::ReadOnly | QIODevice::Unbuffered;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -217,8 +256,10 @@ BufferIODevice::offsetForPos( qint64 pos ) const
|
|||||||
int
|
int
|
||||||
BufferIODevice::nextEmptyBlock() const
|
BufferIODevice::nextEmptyBlock() const
|
||||||
{
|
{
|
||||||
|
Q_D( const BufferIODevice );
|
||||||
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
foreach( const QByteArray& ba, m_buffer )
|
foreach( const QByteArray& ba, d->buffer )
|
||||||
{
|
{
|
||||||
if ( ba.isEmpty() )
|
if ( ba.isEmpty() )
|
||||||
return i;
|
return i;
|
||||||
@@ -236,9 +277,11 @@ BufferIODevice::nextEmptyBlock() const
|
|||||||
int
|
int
|
||||||
BufferIODevice::maxBlocks() const
|
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++;
|
i++;
|
||||||
|
|
||||||
return i;
|
return i;
|
||||||
@@ -248,22 +291,24 @@ BufferIODevice::maxBlocks() const
|
|||||||
bool
|
bool
|
||||||
BufferIODevice::isBlockEmpty( int block ) const
|
BufferIODevice::isBlockEmpty( int block ) const
|
||||||
{
|
{
|
||||||
if ( block >= m_buffer.count() )
|
Q_D( const BufferIODevice );
|
||||||
|
if ( block >= d->buffer.count() )
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
return m_buffer.at( block ).isEmpty();
|
return d->buffer.at( block ).isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
QByteArray
|
QByteArray
|
||||||
BufferIODevice::getData( qint64 pos, qint64 size )
|
BufferIODevice::getData( qint64 pos, qint64 size )
|
||||||
{
|
{
|
||||||
|
Q_D( BufferIODevice );
|
||||||
// qDebug() << Q_FUNC_INFO << pos << size << 1;
|
// qDebug() << Q_FUNC_INFO << pos << size << 1;
|
||||||
QByteArray ba;
|
QByteArray ba;
|
||||||
int block = blockForPos( pos );
|
int block = blockForPos( pos );
|
||||||
int offset = offsetForPos( pos );
|
int offset = offsetForPos( pos );
|
||||||
|
|
||||||
QMutexLocker lock( &m_mut );
|
QMutexLocker lock( &d->mut );
|
||||||
while( ba.count() < size )
|
while( ba.count() < size )
|
||||||
{
|
{
|
||||||
if ( block > maxBlocks() )
|
if ( block > maxBlocks() )
|
||||||
@@ -272,7 +317,7 @@ BufferIODevice::getData( qint64 pos, qint64 size )
|
|||||||
if ( isBlockEmpty( block ) )
|
if ( isBlockEmpty( block ) )
|
||||||
break;
|
break;
|
||||||
|
|
||||||
ba.append( m_buffer.at( block++ ).mid( offset ) );
|
ba.append( d->buffer.at( block++ ).mid( offset ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
// qDebug() << Q_FUNC_INFO << pos << size << 2;
|
// qDebug() << Q_FUNC_INFO << pos << size << 2;
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||||
*
|
*
|
||||||
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
||||||
|
* Copyright 2013, Uwe L. Korn <uwelk@xhochy.com>
|
||||||
*
|
*
|
||||||
* Tomahawk is free software: you can redistribute it and/or modify
|
* Tomahawk is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -23,12 +24,15 @@
|
|||||||
#include <QMutexLocker>
|
#include <QMutexLocker>
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
|
|
||||||
|
class BufferIODevicePrivate;
|
||||||
|
|
||||||
class BufferIODevice : public QIODevice
|
class BufferIODevice : public QIODevice
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit BufferIODevice( unsigned int size = 0, QObject* parent = 0 );
|
explicit BufferIODevice( unsigned int size = 0, QObject* parent = 0 );
|
||||||
|
~BufferIODevice();
|
||||||
|
|
||||||
virtual bool open( OpenMode mode );
|
virtual bool open( OpenMode mode );
|
||||||
virtual void close();
|
virtual void close();
|
||||||
@@ -39,16 +43,16 @@ public:
|
|||||||
virtual qint64 bytesAvailable() const;
|
virtual qint64 bytesAvailable() const;
|
||||||
virtual qint64 size() const;
|
virtual qint64 size() const;
|
||||||
virtual bool atEnd() const;
|
virtual bool atEnd() const;
|
||||||
virtual qint64 pos() const { return m_pos; }
|
virtual qint64 pos() const;
|
||||||
|
|
||||||
void addData( int block, const QByteArray& ba );
|
void addData( int block, const QByteArray& ba );
|
||||||
void clear();
|
void clear();
|
||||||
|
|
||||||
OpenMode openMode() const { return QIODevice::ReadOnly | QIODevice::Unbuffered; }
|
OpenMode openMode() const;
|
||||||
|
|
||||||
void inputComplete( const QString& errmsg = "" );
|
void inputComplete( const QString& errmsg = "" );
|
||||||
|
|
||||||
virtual bool isSequential() const { return false; }
|
virtual bool isSequential() const;
|
||||||
|
|
||||||
static unsigned int blockSize();
|
static unsigned int blockSize();
|
||||||
|
|
||||||
@@ -68,11 +72,9 @@ private:
|
|||||||
int offsetForPos( qint64 pos ) const;
|
int offsetForPos( qint64 pos ) const;
|
||||||
QByteArray getData( qint64 pos, qint64 size );
|
QByteArray getData( qint64 pos, qint64 size );
|
||||||
|
|
||||||
QList<QByteArray> m_buffer;
|
Q_DECLARE_PRIVATE( BufferIODevice )
|
||||||
mutable QMutex m_mut; //const methods need to lock
|
BufferIODevicePrivate* d_ptr;
|
||||||
unsigned int m_size, m_received;
|
|
||||||
|
|
||||||
unsigned int m_pos;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // BUFFERIODEVICE_H
|
#endif // BUFFERIODEVICE_H
|
||||||
|
47
src/libtomahawk/network/BufferIoDevice_p.h
Normal file
47
src/libtomahawk/network/BufferIoDevice_p.h
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||||
|
*
|
||||||
|
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
||||||
|
* Copyright 2013, Uwe L. Korn <uwelk@xhochy.com>
|
||||||
|
*
|
||||||
|
* 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#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<QByteArray> buffer;
|
||||||
|
mutable QMutex mut;
|
||||||
|
unsigned int size;
|
||||||
|
unsigned int received;
|
||||||
|
unsigned int pos;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // BUFFERIODEVICE_P_H
|
Reference in New Issue
Block a user