mirror of
https://github.com/Xevion/easy7zip.git
synced 2025-12-14 02:11:40 -06:00
3.13
This commit is contained in:
125
7zip/Compress/BZip2/BZip2Decoder.cpp
Executable file
125
7zip/Compress/BZip2/BZip2Decoder.cpp
Executable file
@@ -0,0 +1,125 @@
|
||||
// BZip2Decoder.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "BZip2Decoder.h"
|
||||
|
||||
#include "Windows/Defs.h"
|
||||
#include "Original/bzlib.h"
|
||||
|
||||
namespace NCompress {
|
||||
namespace NBZip2 {
|
||||
|
||||
static const UINT32 kBufferSize = (1 << 20);
|
||||
|
||||
CDecoder::CDecoder()
|
||||
{
|
||||
m_InBuffer = new BYTE[kBufferSize];
|
||||
m_OutBuffer = new BYTE[kBufferSize];
|
||||
}
|
||||
|
||||
CDecoder::~CDecoder()
|
||||
{
|
||||
delete []m_OutBuffer;
|
||||
delete []m_InBuffer;
|
||||
}
|
||||
|
||||
struct CBZip2Decompressor: public bz_stream
|
||||
{
|
||||
// bz_stream m_Object;
|
||||
public:
|
||||
int Init(int verbosity, int small) { return BZ2_bzDecompressInit(this, verbosity, small); }
|
||||
int Decompress() { return BZ2_bzDecompress(this); }
|
||||
int End() { return BZ2_bzDecompressEnd(this); }
|
||||
UINT64 GetTotalIn() const { return (UINT64(total_in_hi32) << 32) + total_in_lo32; }
|
||||
UINT64 GetTotalOut() const { return (UINT64(total_out_hi32) << 32) + total_out_lo32; }
|
||||
};
|
||||
|
||||
class CBZip2DecompressorReleaser
|
||||
{
|
||||
CBZip2Decompressor *m_Decompressor;
|
||||
public:
|
||||
CBZip2DecompressorReleaser(CBZip2Decompressor *aDecompressor): m_Decompressor(aDecompressor) {}
|
||||
void Diable() { m_Decompressor = NULL; }
|
||||
~CBZip2DecompressorReleaser() { if (m_Decompressor != NULL) m_Decompressor->End(); }
|
||||
};
|
||||
|
||||
STDMETHODIMP CDecoder::CodeReal(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize,
|
||||
ICompressProgressInfo *progress)
|
||||
{
|
||||
CBZip2Decompressor bzStream;
|
||||
bzStream.bzalloc = NULL;
|
||||
bzStream.bzfree = NULL;
|
||||
bzStream.opaque = NULL;
|
||||
|
||||
|
||||
int result = bzStream.Init(0, 0);
|
||||
switch(result)
|
||||
{
|
||||
case BZ_OK:
|
||||
break;
|
||||
case BZ_MEM_ERROR:
|
||||
return E_OUTOFMEMORY;
|
||||
default:
|
||||
return E_FAIL;
|
||||
}
|
||||
CBZip2DecompressorReleaser releaser(&bzStream);
|
||||
bzStream.avail_in = 0;
|
||||
while (true)
|
||||
{
|
||||
if (bzStream.avail_in == 0)
|
||||
{
|
||||
bzStream.next_in = (char *)m_InBuffer;
|
||||
UINT32 processedSize;
|
||||
RINOK(inStream->Read(m_InBuffer, kBufferSize, &processedSize));
|
||||
bzStream.avail_in = processedSize;
|
||||
}
|
||||
|
||||
bzStream.next_out = (char *)m_OutBuffer;
|
||||
bzStream.avail_out = kBufferSize;
|
||||
result = bzStream.Decompress();
|
||||
UINT32 numBytesToWrite = kBufferSize - bzStream.avail_out;
|
||||
if (numBytesToWrite > 0)
|
||||
{
|
||||
UINT32 processedSize;
|
||||
RINOK(outStream->Write(m_OutBuffer, numBytesToWrite, &processedSize));
|
||||
if (numBytesToWrite != processedSize)
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
if (result == BZ_STREAM_END)
|
||||
break;
|
||||
switch(result)
|
||||
{
|
||||
case BZ_DATA_ERROR:
|
||||
case BZ_DATA_ERROR_MAGIC:
|
||||
return S_FALSE;
|
||||
case BZ_OK:
|
||||
break;
|
||||
case BZ_MEM_ERROR:
|
||||
return E_OUTOFMEMORY;
|
||||
default:
|
||||
return E_FAIL;
|
||||
}
|
||||
if (progress != NULL)
|
||||
{
|
||||
UINT64 totalIn = bzStream.GetTotalIn();
|
||||
UINT64 totalOut = bzStream.GetTotalOut();
|
||||
RINOK(progress->SetRatioInfo(&totalIn, &totalOut));
|
||||
}
|
||||
}
|
||||
// result = bzStream.End();
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize,
|
||||
ICompressProgressInfo *progress)
|
||||
{
|
||||
try { return CodeReal(inStream, outStream, inSize, outSize, progress); }
|
||||
catch(...) { return S_FALSE; }
|
||||
}
|
||||
|
||||
}}
|
||||
Reference in New Issue
Block a user