186 lines
3.2 KiB
C++
186 lines
3.2 KiB
C++
#include "stdafx.h"
|
|
#include "SplitFile.h"
|
|
|
|
|
|
CSplitFile::CSplitFile(const QString &name, quint64 size)
|
|
{
|
|
m_PartSize = size;
|
|
m_FileName = name;
|
|
|
|
m_Position = 0;
|
|
m_Index = -1;
|
|
}
|
|
|
|
CSplitFile::~CSplitFile()
|
|
{
|
|
QIODevice::close();
|
|
}
|
|
|
|
QString CSplitFile::GetPartName(int Index)
|
|
{
|
|
QString Ext = QString::number(Index+1);
|
|
while(Ext.length() < 3)
|
|
Ext.prepend("0");
|
|
return m_FileName + "." + Ext;
|
|
}
|
|
|
|
bool CSplitFile::open(OpenMode flags)
|
|
{
|
|
if(flags & ReadOnly)
|
|
{
|
|
for(int i = 0;; i++)
|
|
{
|
|
QString PartName = GetPartName(i);
|
|
if(!QFile::exists(PartName))
|
|
break;
|
|
|
|
QFile* pFile = new QFile(PartName, this);
|
|
pFile->open(flags);
|
|
m_FileParts.append(pFile);
|
|
}
|
|
}
|
|
|
|
m_Index = 0; // we are open for business
|
|
return QIODevice::open(flags);
|
|
}
|
|
|
|
void CSplitFile::close()
|
|
{
|
|
m_Position = 0;
|
|
m_Index = -1;
|
|
foreach(QFile* pPart, m_FileParts)
|
|
{
|
|
pPart->close();
|
|
delete pPart;
|
|
}
|
|
m_FileParts.clear();
|
|
QIODevice::close();
|
|
}
|
|
|
|
qint64 CSplitFile::size() const
|
|
{
|
|
quint64 uSize = 0;
|
|
foreach(QFile* pPart, m_FileParts)
|
|
uSize += pPart->size();
|
|
return uSize;
|
|
}
|
|
|
|
qint64 CSplitFile::pos() const
|
|
{
|
|
return m_Position;
|
|
}
|
|
|
|
bool CSplitFile::seek(qint64 offset)
|
|
{
|
|
if(m_Index == -1)
|
|
return false;
|
|
|
|
qint64 iToGo = offset - m_Position;
|
|
int i = m_Index;
|
|
|
|
while(iToGo)
|
|
{
|
|
if(iToGo > 0)
|
|
{
|
|
qint64 tmp = m_FileParts[i]->pos();
|
|
if(tmp + iToGo < (qint64)m_PartSize)
|
|
{
|
|
m_FileParts[i]->seek(tmp + iToGo);
|
|
//iToGo = 0;
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
if(++i == m_FileParts.count())
|
|
{
|
|
QFile* pFile = new QFile(GetPartName(m_Index), this);
|
|
pFile->open(openMode());
|
|
m_FileParts.append(pFile);
|
|
}
|
|
iToGo -= tmp;
|
|
m_FileParts[i]->seek(0);
|
|
}
|
|
}
|
|
else if(iToGo < 0)
|
|
{
|
|
qint64 tmp = m_FileParts[i]->pos();
|
|
if(tmp -iToGo >= 0)
|
|
{
|
|
m_FileParts[i]->seek(tmp + iToGo);
|
|
//iToGo = 0;
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
if(--i == -1)
|
|
return false;
|
|
iToGo += tmp;
|
|
m_FileParts[i]->seek(m_FileParts[i]->size()-1);
|
|
}
|
|
}
|
|
}
|
|
|
|
m_Index = i;
|
|
m_Position = offset;
|
|
return true;
|
|
}
|
|
|
|
qint64 CSplitFile::readData(char *data, qint64 maxlen)
|
|
{
|
|
if(m_Index == -1)
|
|
return -1;
|
|
|
|
quint64 read = 0;
|
|
while(maxlen - read)
|
|
{
|
|
if(m_Index >= m_FileParts.count())
|
|
break;
|
|
|
|
quint64 uToGo = maxlen - read;
|
|
quint64 uAvail = m_FileParts[m_Index]->size() - m_FileParts[m_Index]->pos();
|
|
if(uToGo > uAvail)
|
|
uToGo = uAvail;
|
|
|
|
quint64 Tmp = m_FileParts[m_Index]->read(data + read, uToGo);
|
|
if(Tmp == -1)
|
|
return -1;
|
|
read += Tmp;
|
|
m_Position += Tmp;
|
|
|
|
if(m_FileParts[m_Index]->pos() >= m_FileParts[m_Index]->size())
|
|
m_Index++;
|
|
}
|
|
return read;
|
|
}
|
|
|
|
qint64 CSplitFile::writeData(const char *data, qint64 len)
|
|
{
|
|
if(m_Index == -1)
|
|
return -1;
|
|
|
|
quint64 writen = 0;
|
|
while(len - writen)
|
|
{
|
|
if(m_Index >= m_FileParts.count())
|
|
{
|
|
QFile* pFile = new QFile(GetPartName(m_Index), this);
|
|
pFile->open(openMode());
|
|
m_FileParts.append(pFile);
|
|
}
|
|
|
|
quint64 uToGo = len - writen;
|
|
quint64 uAvail = m_PartSize - m_FileParts[m_Index]->pos();
|
|
if(uToGo > uAvail)
|
|
uToGo = uAvail;
|
|
|
|
quint64 Tmp = m_FileParts[m_Index]->write(data + writen, uToGo);
|
|
if(Tmp == -1)
|
|
return -1;
|
|
writen += Tmp;
|
|
m_Position += Tmp;
|
|
|
|
if(m_FileParts[m_Index]->pos() >= (qint64)m_PartSize)
|
|
m_Index++;
|
|
}
|
|
return writen;
|
|
} |