mirror of
https://github.com/Xevion/easy7zip.git
synced 2025-12-08 10:07:02 -06:00
9.38
This commit is contained in:
committed by
Kornel Lesiński
parent
7e021179cd
commit
0713a3ab80
@@ -19,7 +19,7 @@ static SRes CompressProgress(void *pp, UInt64 inSize, UInt64 outSize) throw()
|
||||
return (SRes)p->Res;
|
||||
}
|
||||
|
||||
CCompressProgressWrap::CCompressProgressWrap(ICompressProgressInfo *progress)
|
||||
CCompressProgressWrap::CCompressProgressWrap(ICompressProgressInfo *progress) throw()
|
||||
{
|
||||
p.Progress = CompressProgress;
|
||||
Progress = progress;
|
||||
@@ -69,14 +69,14 @@ static size_t MyWrite(void *object, const void *data, size_t size) throw()
|
||||
return size;
|
||||
}
|
||||
|
||||
CSeqInStreamWrap::CSeqInStreamWrap(ISequentialInStream *stream)
|
||||
CSeqInStreamWrap::CSeqInStreamWrap(ISequentialInStream *stream) throw()
|
||||
{
|
||||
p.Read = MyRead;
|
||||
Stream = stream;
|
||||
Processed = 0;
|
||||
}
|
||||
|
||||
CSeqOutStreamWrap::CSeqOutStreamWrap(ISequentialOutStream *stream)
|
||||
CSeqOutStreamWrap::CSeqOutStreamWrap(ISequentialOutStream *stream) throw()
|
||||
{
|
||||
p.Write = MyWrite;
|
||||
Stream = stream;
|
||||
@@ -84,7 +84,7 @@ CSeqOutStreamWrap::CSeqOutStreamWrap(ISequentialOutStream *stream)
|
||||
Processed = 0;
|
||||
}
|
||||
|
||||
HRESULT SResToHRESULT(SRes res)
|
||||
HRESULT SResToHRESULT(SRes res) throw()
|
||||
{
|
||||
switch(res)
|
||||
{
|
||||
@@ -124,7 +124,7 @@ static SRes InStreamWrap_Seek(void *pp, Int64 *offset, ESzSeek origin) throw()
|
||||
return (p->Res == S_OK) ? SZ_OK : SZ_ERROR_READ;
|
||||
}
|
||||
|
||||
CSeekInStreamWrap::CSeekInStreamWrap(IInStream *stream)
|
||||
CSeekInStreamWrap::CSeekInStreamWrap(IInStream *stream) throw()
|
||||
{
|
||||
Stream = stream;
|
||||
p.Read = InStreamWrap_Read;
|
||||
@@ -135,13 +135,13 @@ CSeekInStreamWrap::CSeekInStreamWrap(IInStream *stream)
|
||||
|
||||
/* ---------- CByteInBufWrap ---------- */
|
||||
|
||||
void CByteInBufWrap::Free()
|
||||
void CByteInBufWrap::Free() throw()
|
||||
{
|
||||
::MidFree(Buf);
|
||||
Buf = 0;
|
||||
}
|
||||
|
||||
bool CByteInBufWrap::Alloc(UInt32 size)
|
||||
bool CByteInBufWrap::Alloc(UInt32 size) throw()
|
||||
{
|
||||
if (Buf == 0 || size != Size)
|
||||
{
|
||||
@@ -152,7 +152,7 @@ bool CByteInBufWrap::Alloc(UInt32 size)
|
||||
return (Buf != 0);
|
||||
}
|
||||
|
||||
Byte CByteInBufWrap::ReadByteFromNewBlock()
|
||||
Byte CByteInBufWrap::ReadByteFromNewBlock() throw()
|
||||
{
|
||||
if (Res == S_OK)
|
||||
{
|
||||
@@ -184,13 +184,13 @@ CByteInBufWrap::CByteInBufWrap(): Buf(0)
|
||||
|
||||
/* ---------- CByteOutBufWrap ---------- */
|
||||
|
||||
void CByteOutBufWrap::Free()
|
||||
void CByteOutBufWrap::Free() throw()
|
||||
{
|
||||
::MidFree(Buf);
|
||||
Buf = 0;
|
||||
}
|
||||
|
||||
bool CByteOutBufWrap::Alloc(size_t size)
|
||||
bool CByteOutBufWrap::Alloc(size_t size) throw()
|
||||
{
|
||||
if (Buf == 0 || size != Size)
|
||||
{
|
||||
@@ -201,7 +201,7 @@ bool CByteOutBufWrap::Alloc(size_t size)
|
||||
return (Buf != 0);
|
||||
}
|
||||
|
||||
HRESULT CByteOutBufWrap::Flush()
|
||||
HRESULT CByteOutBufWrap::Flush() throw()
|
||||
{
|
||||
if (Res == S_OK)
|
||||
{
|
||||
@@ -224,7 +224,7 @@ static void Wrap_WriteByte(void *pp, Byte b) throw()
|
||||
p->Flush();
|
||||
}
|
||||
|
||||
CByteOutBufWrap::CByteOutBufWrap(): Buf(0)
|
||||
CByteOutBufWrap::CByteOutBufWrap() throw(): Buf(0)
|
||||
{
|
||||
p.Write = Wrap_WriteByte;
|
||||
}
|
||||
|
||||
@@ -90,7 +90,7 @@ HRESULT CExternalCodecs::LoadCodecs()
|
||||
}
|
||||
if (GetHashers)
|
||||
{
|
||||
UInt32 num = num = GetHashers->GetNumHashers();
|
||||
UInt32 num = GetHashers->GetNumHashers();
|
||||
for (UInt32 i = 0; i < num; i++)
|
||||
{
|
||||
CHasherInfoEx info;
|
||||
@@ -226,7 +226,6 @@ HRESULT CreateCoder(
|
||||
CMyComPtr<ICompressCoder2> &coder2,
|
||||
bool encode, bool onlyCoder)
|
||||
{
|
||||
bool created = false;
|
||||
UInt32 i;
|
||||
for (i = 0; i < g_NumCodecs; i++)
|
||||
{
|
||||
@@ -241,7 +240,6 @@ HRESULT CreateCoder(
|
||||
if (codec.IsFilter) filter = (ICompressFilter *)p;
|
||||
else if (codec.NumInStreams == 1) coder = (ICompressCoder *)p;
|
||||
else coder2 = (ICompressCoder2 *)p;
|
||||
created = (p != 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -252,14 +250,13 @@ HRESULT CreateCoder(
|
||||
if (codec.IsFilter) filter = (ICompressFilter *)p;
|
||||
else if (codec.NumInStreams == 1) coder = (ICompressCoder *)p;
|
||||
else coder2 = (ICompressCoder2 *)p;
|
||||
created = (p != 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef EXTERNAL_CODECS
|
||||
if (!created && __externalCodecs)
|
||||
if (!filter && !coder && !coder2 && __externalCodecs)
|
||||
for (i = 0; i < (UInt32)__externalCodecs->Codecs.Size(); i++)
|
||||
{
|
||||
const CCodecInfoEx &codec = __externalCodecs->Codecs[i];
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/ FileStreams.cpp
|
||||
// FileStreams.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
#include "InBuffer.h"
|
||||
|
||||
CInBufferBase::CInBufferBase():
|
||||
CInBufferBase::CInBufferBase() throw():
|
||||
_buf(0),
|
||||
_bufLim(0),
|
||||
_bufBase(0),
|
||||
@@ -17,7 +17,7 @@ CInBufferBase::CInBufferBase():
|
||||
NumExtraBytes(0)
|
||||
{}
|
||||
|
||||
bool CInBuffer::Create(size_t bufSize)
|
||||
bool CInBuffer::Create(size_t bufSize) throw()
|
||||
{
|
||||
const unsigned kMinBlockSize = 1;
|
||||
if (bufSize < kMinBlockSize)
|
||||
@@ -30,13 +30,13 @@ bool CInBuffer::Create(size_t bufSize)
|
||||
return (_bufBase != 0);
|
||||
}
|
||||
|
||||
void CInBuffer::Free()
|
||||
void CInBuffer::Free() throw()
|
||||
{
|
||||
::MidFree(_bufBase);
|
||||
_bufBase = 0;
|
||||
}
|
||||
|
||||
void CInBufferBase::Init()
|
||||
void CInBufferBase::Init() throw()
|
||||
{
|
||||
_processedSize = 0;
|
||||
_buf = _bufBase;
|
||||
|
||||
@@ -1,222 +0,0 @@
|
||||
// InMemStream.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "Windows/Thread.h"
|
||||
|
||||
#include "InMemStream.h"
|
||||
#include "../../Common/Defs.h"
|
||||
|
||||
void CStreamInfo::Free(IInMemStreamMtCallback *callback)
|
||||
{
|
||||
for (int i = 0; i < Blocks.Size(); i++)
|
||||
{
|
||||
callback->FreeBlock(Blocks[i]);
|
||||
Blocks[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
bool CInMemStreamMt::Create(int numSubStreams, UInt64 subStreamSize)
|
||||
{
|
||||
Free();
|
||||
_subStreamSize = subStreamSize;
|
||||
size_t blockSize = Callback->GetBlockSize();
|
||||
for (int i = 0; i < numSubStreams; i++)
|
||||
{
|
||||
_streams.Add(CStreamInfo());
|
||||
CStreamInfo &blocks = _streams.Back();
|
||||
blocks.Create();
|
||||
for (UInt64 j = 0; (UInt64)j * blockSize < _subStreamSize; j++)
|
||||
blocks.Blocks.Add(0);
|
||||
}
|
||||
if (!_streamIndexAllocator.AllocateList(numSubStreams))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void CInMemStreamMt::Free()
|
||||
{
|
||||
while(_streams.Size() > 0)
|
||||
{
|
||||
_streams.Back().Free(Callback);
|
||||
_streams.DeleteBack();
|
||||
}
|
||||
}
|
||||
|
||||
HRESULT CInMemStreamMt::Read()
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
// printf("\n_streamIndexAllocator.AllocateItem\n");
|
||||
int index = _streamIndexAllocator.AllocateItem();
|
||||
/*
|
||||
if (_stopReading)
|
||||
return E_ABORT;
|
||||
*/
|
||||
// printf("\nread Index = %d\n", index);
|
||||
CStreamInfo &blocks = _streams[index];
|
||||
blocks.Init();
|
||||
Callback->AddStreamIndexToQueue(index);
|
||||
|
||||
for (;;)
|
||||
{
|
||||
const Byte *p = (const Byte *)blocks.Blocks[blocks.LastBlockIndex];
|
||||
if (p == 0)
|
||||
{
|
||||
void **pp = &blocks.Blocks[blocks.LastBlockIndex];
|
||||
HRESULT res = Callback->AllocateBlock(pp);
|
||||
p = (const Byte *)*pp;
|
||||
RINOK(res);
|
||||
if (p == 0)
|
||||
return E_FAIL;
|
||||
}
|
||||
size_t blockSize = Callback->GetBlockSize();
|
||||
UInt32 curSize = (UInt32)(blockSize - blocks.LastBlockPos);
|
||||
UInt32 realProcessedSize;
|
||||
UInt64 pos64 = (UInt64)blocks.LastBlockIndex * blockSize + blocks.LastBlockPos;
|
||||
if (curSize > _subStreamSize - pos64)
|
||||
curSize = (UInt32)(_subStreamSize - pos64);
|
||||
RINOK(_stream->Read((void *)(p + blocks.LastBlockPos), curSize, &realProcessedSize));
|
||||
|
||||
blocks.Cs->Enter();
|
||||
if (realProcessedSize == 0)
|
||||
{
|
||||
blocks.StreamWasFinished = true;
|
||||
blocks.CanReadEvent->Set();
|
||||
blocks.Cs->Leave();
|
||||
|
||||
Callback->AddStreamIndexToQueue(-1);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
blocks.LastBlockPos += realProcessedSize;
|
||||
if (blocks.LastBlockPos == blockSize)
|
||||
{
|
||||
blocks.LastBlockPos = 0;
|
||||
blocks.LastBlockIndex++;
|
||||
}
|
||||
pos64 += realProcessedSize;
|
||||
if (pos64 >= _subStreamSize)
|
||||
blocks.StreamWasFinished = true;
|
||||
blocks.CanReadEvent->Set();
|
||||
blocks.Cs->Leave();
|
||||
if (pos64 >= _subStreamSize)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static THREAD_FUNC_DECL CoderThread(void *threadCoderInfo)
|
||||
{
|
||||
((CInMemStreamMt *)threadCoderInfo)->ReadResult = ((CInMemStreamMt *)threadCoderInfo)->Read();
|
||||
return 0;
|
||||
}
|
||||
|
||||
HRes CInMemStreamMt::StartReadThread()
|
||||
{
|
||||
// _stopReading = false;
|
||||
NWindows::CThread Thread;
|
||||
return Thread.Create(CoderThread, this);
|
||||
}
|
||||
|
||||
void CInMemStreamMt::FreeSubStream(int subStreamIndex)
|
||||
{
|
||||
// printf("\nFreeSubStream\n");
|
||||
_streams[subStreamIndex].Free(Callback);
|
||||
_streamIndexAllocator.FreeItem(subStreamIndex);
|
||||
// printf("\nFreeSubStream end\n");
|
||||
}
|
||||
|
||||
HRESULT CInMemStreamMt::ReadSubStream(int subStreamIndex, void *data, UInt32 size, UInt32 *processedSize, bool keepData)
|
||||
{
|
||||
if (processedSize != NULL)
|
||||
*processedSize = 0;
|
||||
CStreamInfo &blocks = _streams[subStreamIndex];
|
||||
while (size > 0)
|
||||
{
|
||||
if (blocks.CurBlockPos == Callback->GetBlockSize())
|
||||
{
|
||||
blocks.CurBlockPos = 0;
|
||||
blocks.CurBlockIndex++;
|
||||
}
|
||||
UInt32 curSize;
|
||||
UInt32 curPos = blocks.CurBlockPos;
|
||||
|
||||
blocks.Cs->Enter();
|
||||
if (blocks.CurBlockIndex == blocks.LastBlockIndex)
|
||||
{
|
||||
curSize = blocks.LastBlockPos - curPos;
|
||||
if (curSize == 0)
|
||||
{
|
||||
if (blocks.StreamWasFinished)
|
||||
{
|
||||
blocks.Cs->Leave();
|
||||
void *p = blocks.Blocks[blocks.CurBlockIndex];
|
||||
if (p != 0 && !keepData)
|
||||
{
|
||||
Callback->FreeBlock(p);
|
||||
blocks.Blocks[blocks.CurBlockIndex] = 0;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
blocks.CanReadEvent->Reset();
|
||||
blocks.Cs->Leave();
|
||||
// printf("\nBlock Lock\n");
|
||||
blocks.CanReadEvent->Lock();
|
||||
// printf("\nAfter Lock\n");
|
||||
if (blocks.ExitResult != S_OK)
|
||||
return blocks.ExitResult;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else
|
||||
curSize = Callback->GetBlockSize() - curPos;
|
||||
blocks.Cs->Leave();
|
||||
|
||||
if (curSize > size)
|
||||
curSize = size;
|
||||
void *p = blocks.Blocks[blocks.CurBlockIndex];
|
||||
memcpy(data, (const Byte *)p + curPos, curSize);
|
||||
data = (void *)((Byte *)data + curSize);
|
||||
size -= curSize;
|
||||
if (processedSize != NULL)
|
||||
*processedSize += curSize;
|
||||
curPos += curSize;
|
||||
|
||||
bool needFree = false;
|
||||
blocks.CurBlockPos = curPos;
|
||||
|
||||
if (curPos == Callback->GetBlockSize())
|
||||
needFree = true;
|
||||
blocks.Cs->Enter();
|
||||
if (blocks.CurBlockIndex == blocks.LastBlockIndex &&
|
||||
blocks.CurBlockPos == blocks.LastBlockPos &&
|
||||
blocks.StreamWasFinished)
|
||||
needFree = true;
|
||||
blocks.Cs->Leave();
|
||||
|
||||
if (needFree && !keepData)
|
||||
{
|
||||
Callback->FreeBlock(p);
|
||||
blocks.Blocks[blocks.CurBlockIndex] = 0;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CInMemStream::Read(void *data, UInt32 size, UInt32 *processedSize)
|
||||
{
|
||||
UInt32 realProcessedSize;
|
||||
HRESULT result = mtStream->ReadSubStream(Index, data, size, &realProcessedSize, _keepData);
|
||||
if (processedSize != NULL)
|
||||
*processedSize = realProcessedSize;
|
||||
if (realProcessedSize != 0)
|
||||
{
|
||||
// printf("\ns = %d\n", Index);
|
||||
}
|
||||
_size += realProcessedSize;
|
||||
return result;
|
||||
}
|
||||
@@ -1,284 +0,0 @@
|
||||
// InMemStream.h
|
||||
|
||||
#ifndef __IN_MEM_STREAM_H
|
||||
#define __IN_MEM_STREAM_H
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "../../../C/Alloc.h"
|
||||
|
||||
#include "../../Common/MyCom.h"
|
||||
|
||||
#include "MemBlocks.h"
|
||||
|
||||
class CIntListCheck
|
||||
{
|
||||
protected:
|
||||
int *_data;
|
||||
public:
|
||||
CIntListCheck(): _data(0) {}
|
||||
~CIntListCheck() { FreeList(); }
|
||||
|
||||
bool AllocateList(int numItems)
|
||||
{
|
||||
FreeList();
|
||||
if (numItems == 0)
|
||||
return true;
|
||||
_data = (int *)::MyAlloc(numItems * sizeof(int));
|
||||
return (_data != 0);
|
||||
}
|
||||
|
||||
void FreeList()
|
||||
{
|
||||
::MyFree(_data);
|
||||
_data = 0;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class CResourceList : public CIntListCheck
|
||||
{
|
||||
int _headFree;
|
||||
public:
|
||||
CResourceList(): _headFree(-1) {}
|
||||
|
||||
bool AllocateList(int numItems)
|
||||
{
|
||||
FreeList();
|
||||
if (numItems == 0)
|
||||
return true;
|
||||
if (!CIntListCheck::AllocateList(numItems))
|
||||
return false;
|
||||
for (int i = 0; i < numItems; i++)
|
||||
_data[i] = i + 1;
|
||||
_data[numItems - 1] = -1;
|
||||
_headFree = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
void FreeList()
|
||||
{
|
||||
CIntListCheck::FreeList();
|
||||
_headFree = -1;
|
||||
}
|
||||
|
||||
int AllocateItem()
|
||||
{
|
||||
int res = _headFree;
|
||||
if (res >= 0)
|
||||
_headFree = _data[res];
|
||||
return res;
|
||||
}
|
||||
|
||||
void FreeItem(int index)
|
||||
{
|
||||
if (index < 0)
|
||||
return;
|
||||
_data[index] = _headFree;
|
||||
_headFree = index;
|
||||
}
|
||||
};
|
||||
|
||||
class CResourceListMt: public CResourceList
|
||||
{
|
||||
NWindows::NSynchronization::CCriticalSection _criticalSection;
|
||||
public:
|
||||
NWindows::NSynchronization::CSemaphore Semaphore;
|
||||
|
||||
HRes AllocateList(int numItems)
|
||||
{
|
||||
if (!CResourceList::AllocateList(numItems))
|
||||
return E_OUTOFMEMORY;
|
||||
Semaphore.Close();
|
||||
return Semaphore.Create(numItems, numItems);
|
||||
}
|
||||
|
||||
int AllocateItem()
|
||||
{
|
||||
Semaphore.Lock();
|
||||
_criticalSection.Enter();
|
||||
int res = CResourceList::AllocateItem();
|
||||
_criticalSection.Leave();
|
||||
return res;
|
||||
}
|
||||
|
||||
void FreeItem(int index)
|
||||
{
|
||||
if (index < 0)
|
||||
return;
|
||||
_criticalSection.Enter();
|
||||
CResourceList::FreeItem(index);
|
||||
_criticalSection.Leave();
|
||||
Semaphore.Release();
|
||||
}
|
||||
};
|
||||
|
||||
class CIntQueueMt: public CIntListCheck
|
||||
{
|
||||
int _numItems;
|
||||
int _head;
|
||||
int _cur;
|
||||
public:
|
||||
CIntQueueMt(): _numItems(0), _head(0), _cur(0) {}
|
||||
NWindows::NSynchronization::CSemaphore Semaphore;
|
||||
|
||||
HRes AllocateList(int numItems)
|
||||
{
|
||||
FreeList();
|
||||
if (numItems == 0)
|
||||
return S_OK;
|
||||
if (!CIntListCheck::AllocateList(numItems))
|
||||
return E_OUTOFMEMORY;
|
||||
_numItems = numItems;
|
||||
return Semaphore.Create(0, numItems);
|
||||
}
|
||||
|
||||
void FreeList()
|
||||
{
|
||||
CIntListCheck::FreeList();
|
||||
_numItems = 0;
|
||||
_head = 0;
|
||||
_cur = 0;
|
||||
}
|
||||
|
||||
void AddItem(int value)
|
||||
{
|
||||
_data[_head++] = value;
|
||||
if (_head == _numItems)
|
||||
_head = 0;
|
||||
Semaphore.Release();
|
||||
// printf("\nRelease prev = %d\n", previousCount);
|
||||
}
|
||||
|
||||
int GetItem()
|
||||
{
|
||||
// Semaphore.Lock();
|
||||
int res = _data[_cur++];
|
||||
if (_cur == _numItems)
|
||||
_cur = 0;
|
||||
return res;
|
||||
}
|
||||
};
|
||||
|
||||
struct IInMemStreamMtCallback
|
||||
{
|
||||
// must be same for all calls
|
||||
virtual size_t GetBlockSize() = 0;
|
||||
|
||||
// Out:
|
||||
// result != S_OK stops Reading
|
||||
// if *p = 0, result must be != S_OK;
|
||||
// Locking is allowed
|
||||
virtual HRESULT AllocateBlock(void **p) = 0;
|
||||
|
||||
virtual void FreeBlock(void *p) = 0;
|
||||
|
||||
// It must allow to add at least numSubStreams + 1 ,
|
||||
// where numSubStreams is value from CInMemStreamMt::Create
|
||||
// value -1 means End of stream
|
||||
// Locking is not allowed
|
||||
virtual void AddStreamIndexToQueue(int index) = 0;
|
||||
};
|
||||
|
||||
struct CStreamInfo
|
||||
{
|
||||
CRecordVector<void *> Blocks;
|
||||
|
||||
int LastBlockIndex;
|
||||
size_t LastBlockPos;
|
||||
bool StreamWasFinished;
|
||||
|
||||
int CurBlockIndex;
|
||||
size_t CurBlockPos;
|
||||
|
||||
NWindows::NSynchronization::CCriticalSection *Cs;
|
||||
NWindows::NSynchronization::CManualResetEvent *CanReadEvent;
|
||||
|
||||
HRESULT ExitResult;
|
||||
|
||||
CStreamInfo(): Cs(0), CanReadEvent(0), StreamWasFinished(false) { }
|
||||
~CStreamInfo()
|
||||
{
|
||||
delete Cs;
|
||||
delete CanReadEvent;
|
||||
// Free();
|
||||
}
|
||||
void Create()
|
||||
{
|
||||
Cs = new NWindows::NSynchronization::CCriticalSection;
|
||||
CanReadEvent = new NWindows::NSynchronization::CManualResetEvent;
|
||||
}
|
||||
|
||||
void Free(IInMemStreamMtCallback *callback);
|
||||
void Init()
|
||||
{
|
||||
LastBlockIndex = CurBlockIndex = 0;
|
||||
CurBlockPos = LastBlockPos = 0;
|
||||
StreamWasFinished = false;
|
||||
ExitResult = S_OK;
|
||||
}
|
||||
|
||||
// res must be != S_OK
|
||||
void Exit(HRESULT res)
|
||||
{
|
||||
ExitResult = res;
|
||||
CanReadEvent->Set();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class CInMemStreamMt
|
||||
{
|
||||
CMyComPtr<ISequentialInStream> _stream;
|
||||
NWindows::NSynchronization::CCriticalSection CS;
|
||||
CObjectVector<CStreamInfo> _streams;
|
||||
int _nextFreeStreamIndex;
|
||||
int _currentStreamIndex;
|
||||
UInt64 _subStreamSize;
|
||||
|
||||
CResourceListMt _streamIndexAllocator;
|
||||
|
||||
// bool _stopReading;
|
||||
|
||||
public:
|
||||
HRESULT Read();
|
||||
HRESULT ReadResult;
|
||||
IInMemStreamMtCallback *Callback;
|
||||
void FreeSubStream(int subStreamIndex);
|
||||
HRESULT ReadSubStream(int subStreamIndex, void *data, UInt32 size, UInt32 *processedSize, bool keepData);
|
||||
|
||||
// numSubStreams: min = 1, good min = numThreads
|
||||
bool Create(int numSubStreams, UInt64 subStreamSize);
|
||||
~CInMemStreamMt() { Free(); }
|
||||
void SetStream(ISequentialInStream *stream) { _stream = stream; }
|
||||
|
||||
// to stop reading you must implement
|
||||
// returning Error in IInMemStreamMtCallback::AllocateBlock
|
||||
// and then you must free at least one substream
|
||||
HRes StartReadThread();
|
||||
|
||||
void Free();
|
||||
|
||||
// you must free at least one substream after that function to unlock waiting.
|
||||
// void StopReading() { _stopReading = true; }
|
||||
};
|
||||
|
||||
class CInMemStream:
|
||||
public ISequentialInStream,
|
||||
public CMyUnknownImp
|
||||
{
|
||||
UInt64 _size;
|
||||
bool _keepData;
|
||||
public:
|
||||
int Index;
|
||||
CInMemStreamMt *mtStream;
|
||||
void Init(bool keepData = false)
|
||||
{
|
||||
_size = 0; _keepData = keepData ;
|
||||
}
|
||||
MY_UNKNOWN_IMP
|
||||
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
|
||||
UInt64 GetSize() const { return _size; }
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
#include "OutBuffer.h"
|
||||
|
||||
bool COutBuffer::Create(UInt32 bufSize)
|
||||
bool COutBuffer::Create(UInt32 bufSize) throw()
|
||||
{
|
||||
const UInt32 kMinBlockSize = 1;
|
||||
if (bufSize < kMinBlockSize)
|
||||
@@ -19,13 +19,13 @@ bool COutBuffer::Create(UInt32 bufSize)
|
||||
return (_buf != 0);
|
||||
}
|
||||
|
||||
void COutBuffer::Free()
|
||||
void COutBuffer::Free() throw()
|
||||
{
|
||||
::MidFree(_buf);
|
||||
_buf = 0;
|
||||
}
|
||||
|
||||
void COutBuffer::Init()
|
||||
void COutBuffer::Init() throw()
|
||||
{
|
||||
_streamPos = 0;
|
||||
_limitPos = _bufSize;
|
||||
@@ -37,7 +37,7 @@ void COutBuffer::Init()
|
||||
#endif
|
||||
}
|
||||
|
||||
UInt64 COutBuffer::GetProcessedSize() const
|
||||
UInt64 COutBuffer::GetProcessedSize() const throw()
|
||||
{
|
||||
UInt64 res = _processedSize + _pos - _streamPos;
|
||||
if (_streamPos > _pos)
|
||||
@@ -46,7 +46,7 @@ UInt64 COutBuffer::GetProcessedSize() const
|
||||
}
|
||||
|
||||
|
||||
HRESULT COutBuffer::FlushPart()
|
||||
HRESULT COutBuffer::FlushPart() throw()
|
||||
{
|
||||
// _streamPos < _bufSize
|
||||
UInt32 size = (_streamPos >= _pos) ? (_bufSize - _streamPos) : (_pos - _streamPos);
|
||||
@@ -83,7 +83,7 @@ HRESULT COutBuffer::FlushPart()
|
||||
return result;
|
||||
}
|
||||
|
||||
HRESULT COutBuffer::Flush()
|
||||
HRESULT COutBuffer::Flush() throw()
|
||||
{
|
||||
#ifdef _NO_EXCEPTIONS
|
||||
if (ErrorCode != S_OK)
|
||||
|
||||
@@ -65,14 +65,14 @@ void Create_BufInStream_WithNewBuf(const void *data, size_t size, ISequentialInS
|
||||
*stream = streamTemp.Detach();
|
||||
}
|
||||
|
||||
void CByteDynBuffer::Free()
|
||||
void CByteDynBuffer::Free() throw()
|
||||
{
|
||||
free(_buf);
|
||||
_buf = 0;
|
||||
_capacity = 0;
|
||||
}
|
||||
|
||||
bool CByteDynBuffer::EnsureCapacity(size_t cap)
|
||||
bool CByteDynBuffer::EnsureCapacity(size_t cap) throw()
|
||||
{
|
||||
if (cap <= _capacity)
|
||||
return true;
|
||||
@@ -147,7 +147,7 @@ STDMETHODIMP CSequentialOutStreamSizeCount::Write(const void *data, UInt32 size,
|
||||
|
||||
static const UInt64 kEmptyTag = (UInt64)(Int64)-1;
|
||||
|
||||
void CCachedInStream::Free()
|
||||
void CCachedInStream::Free() throw()
|
||||
{
|
||||
MyFree(_tags);
|
||||
_tags = 0;
|
||||
@@ -155,7 +155,7 @@ void CCachedInStream::Free()
|
||||
_data = 0;
|
||||
}
|
||||
|
||||
bool CCachedInStream::Alloc(unsigned blockSizeLog, unsigned numBlocksLog)
|
||||
bool CCachedInStream::Alloc(unsigned blockSizeLog, unsigned numBlocksLog) throw()
|
||||
{
|
||||
unsigned sizeLog = blockSizeLog + numBlocksLog;
|
||||
if (sizeLog >= sizeof(size_t) * 8)
|
||||
@@ -181,7 +181,7 @@ bool CCachedInStream::Alloc(unsigned blockSizeLog, unsigned numBlocksLog)
|
||||
return true;
|
||||
}
|
||||
|
||||
void CCachedInStream::Init(UInt64 size)
|
||||
void CCachedInStream::Init(UInt64 size) throw()
|
||||
{
|
||||
_size = size;
|
||||
_pos = 0;
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
static const UInt32 kBlockSize = ((UInt32)1 << 31);
|
||||
|
||||
HRESULT ReadStream(ISequentialInStream *stream, void *data, size_t *processedSize)
|
||||
HRESULT ReadStream(ISequentialInStream *stream, void *data, size_t *processedSize) throw()
|
||||
{
|
||||
size_t size = *processedSize;
|
||||
*processedSize = 0;
|
||||
@@ -25,21 +25,21 @@ HRESULT ReadStream(ISequentialInStream *stream, void *data, size_t *processedSiz
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT ReadStream_FALSE(ISequentialInStream *stream, void *data, size_t size)
|
||||
HRESULT ReadStream_FALSE(ISequentialInStream *stream, void *data, size_t size) throw()
|
||||
{
|
||||
size_t processedSize = size;
|
||||
RINOK(ReadStream(stream, data, &processedSize));
|
||||
return (size == processedSize) ? S_OK : S_FALSE;
|
||||
}
|
||||
|
||||
HRESULT ReadStream_FAIL(ISequentialInStream *stream, void *data, size_t size)
|
||||
HRESULT ReadStream_FAIL(ISequentialInStream *stream, void *data, size_t size) throw()
|
||||
{
|
||||
size_t processedSize = size;
|
||||
RINOK(ReadStream(stream, data, &processedSize));
|
||||
return (size == processedSize) ? S_OK : E_FAIL;
|
||||
}
|
||||
|
||||
HRESULT WriteStream(ISequentialOutStream *stream, const void *data, size_t size)
|
||||
HRESULT WriteStream(ISequentialOutStream *stream, const void *data, size_t size) throw()
|
||||
{
|
||||
while (size != 0)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user