Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/kornelski/7z.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'CPP/7zip/Compress/BZip2Original/BZip2Encoder.cpp')
-rwxr-xr-xCPP/7zip/Compress/BZip2Original/BZip2Encoder.cpp120
1 files changed, 120 insertions, 0 deletions
diff --git a/CPP/7zip/Compress/BZip2Original/BZip2Encoder.cpp b/CPP/7zip/Compress/BZip2Original/BZip2Encoder.cpp
new file mode 100755
index 00000000..bcd7dec0
--- /dev/null
+++ b/CPP/7zip/Compress/BZip2Original/BZip2Encoder.cpp
@@ -0,0 +1,120 @@
+// BZip2Encoder.cpp
+
+#include "StdAfx.h"
+
+#include "BZip2Encoder.h"
+
+#include "../../../Common/Alloc.h"
+#include "Original/bzlib.h"
+
+namespace NCompress {
+namespace NBZip2 {
+
+static const UInt32 kBufferSize = (1 << 20);
+
+CEncoder::~CEncoder()
+{
+ BigFree(m_InBuffer);
+}
+
+struct CBZip2Compressor: public bz_stream
+{
+ int Init(int blockSize100k, int verbosity, int small)
+ { return BZ2_bzCompressInit(this, blockSize100k, verbosity, small); }
+ int Compress(int action ) { return BZ2_bzCompress(this, action ); }
+ int End() { return BZ2_bzCompressEnd(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 CBZip2CompressorReleaser
+{
+ CBZip2Compressor *m_Compressor;
+public:
+ CBZip2CompressorReleaser(CBZip2Compressor *compressor): m_Compressor(compressor) {}
+ void Disable() { m_Compressor = NULL; }
+ ~CBZip2CompressorReleaser() { if (m_Compressor != NULL) m_Compressor->End(); }
+};
+
+
+STDMETHODIMP CEncoder::Code(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
+ ICompressProgressInfo *progress)
+{
+ if (m_InBuffer == 0)
+ {
+ m_InBuffer = (Byte *)BigAlloc(kBufferSize * 2);
+ if (m_InBuffer == 0)
+ return E_OUTOFMEMORY;
+ }
+ Byte *outBuffer = m_InBuffer + kBufferSize;
+
+ CBZip2Compressor bzStream;
+ bzStream.bzalloc = NULL;
+ bzStream.bzfree = NULL;
+ bzStream.opaque = NULL;
+
+ int result = bzStream.Init(9, 0, 0);
+ switch(result)
+ {
+ case BZ_OK:
+ break;
+ case BZ_MEM_ERROR:
+ return E_OUTOFMEMORY;
+ default:
+ return E_FAIL;
+ }
+ CBZip2CompressorReleaser releaser(&bzStream);
+ bzStream.avail_in = 0;
+ for (;;)
+ {
+ 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 *)outBuffer;
+ bzStream.avail_out = kBufferSize;
+ bool askFinish = (bzStream.avail_in == 0);
+ result = bzStream.Compress(askFinish ? BZ_FINISH : BZ_RUN);
+ UInt32 numBytesToWrite = kBufferSize - bzStream.avail_out;
+ if (numBytesToWrite > 0)
+ {
+ UInt32 processedSize;
+ RINOK(outStream->Write(outBuffer, numBytesToWrite, &processedSize));
+ if (numBytesToWrite != processedSize)
+ return E_FAIL;
+ }
+
+ if (result == BZ_STREAM_END)
+ break;
+ switch(result)
+ {
+ case BZ_RUN_OK:
+ if (!askFinish)
+ break;
+ return E_FAIL;
+ case BZ_FINISH_OK:
+ if (askFinish)
+ break;
+ return E_FAIL;
+ 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;
+}
+
+}}