From 1e7e5887d2d84f305bd8e1c18fc8d3b47672c50c Mon Sep 17 00:00:00 2001 From: Phillip Stephens Date: Mon, 5 Dec 2022 21:30:20 -0800 Subject: [PATCH] Restore CZipOutputStream from MP3 prototype Former-commit-id: 529c359935b2f6de9686f6b8e4121dd50b1c00c7 --- configure.py | 1 + include/Kyoto/Streams/COutputStream.hpp | 6 +-- include/Kyoto/Streams/CZipOutputStream.hpp | 27 +++++++++++ src/Kyoto/Streams/CZipOutputStream.cpp | 53 ++++++++++++++++++++++ 4 files changed, 83 insertions(+), 4 deletions(-) create mode 100644 include/Kyoto/Streams/CZipOutputStream.hpp create mode 100644 src/Kyoto/Streams/CZipOutputStream.cpp diff --git a/configure.py b/configure.py index 1bf5e2f8..078912ac 100755 --- a/configure.py +++ b/configure.py @@ -608,6 +608,7 @@ LIBS = [ ["Kyoto/Streams/CMemoryStreamOut", True], ["Kyoto/Streams/COutputStream", True], ["Kyoto/Streams/CZipInputStream", True], + ["Kyoto/Streams/CZipOutputStream", True], ["Kyoto/Streams/CZipSupport", True], "Kyoto/CFactoryStore", "Kyoto/CObjectReference", diff --git a/include/Kyoto/Streams/COutputStream.hpp b/include/Kyoto/Streams/COutputStream.hpp index a5a8de41..0c92ce13 100644 --- a/include/Kyoto/Streams/COutputStream.hpp +++ b/include/Kyoto/Streams/COutputStream.hpp @@ -11,15 +11,14 @@ template < typename T > void coutput_stream_helper(const T& t, COutputStream& out); class COutputStream { - void DoPut(const void* ptr, size_t len); - void DoFlush(); - public: COutputStream(int len); virtual ~COutputStream(); virtual void Write(const void* ptr, size_t len) = 0; void WriteBits(uint val, uint bitCount); + void DoPut(const void* ptr, size_t len); + void DoFlush(); void Flush(); void FlushShiftRegister(); void Put(const void* ptr, size_t len) { @@ -48,7 +47,6 @@ public: *(reinterpret_cast< u8* >(mBufPtr) + mUnwrittenLen++) = c; } - private: uint mUnwrittenLen; uint mBufLen; diff --git a/include/Kyoto/Streams/CZipOutputStream.hpp b/include/Kyoto/Streams/CZipOutputStream.hpp new file mode 100644 index 00000000..3a652ebd --- /dev/null +++ b/include/Kyoto/Streams/CZipOutputStream.hpp @@ -0,0 +1,27 @@ +#ifndef _CZIPOUTPUTSTREAM +#define _CZIPOUTPUTSTREAM + + +#include "Kyoto/Streams/COutputStream.hpp" + +#include "rstl/auto_ptr.hpp" + +#include "zlib/zlib.h" + +class CZipOutputStream : public COutputStream { +public: + CZipOutputStream(COutputStream* out, int level); + ~CZipOutputStream(); + + void Finish(); + bool Process(bool v); + void Write(const void* ptr, size_t len); +private: + COutputStream* mOutput; + int mCompressedBytesWritten; + rstl::auto_ptr mZStream; + int mUnk; +}; + + +#endif // _CZIPOUTPUTSTREAM diff --git a/src/Kyoto/Streams/CZipOutputStream.cpp b/src/Kyoto/Streams/CZipOutputStream.cpp new file mode 100644 index 00000000..bc033b07 --- /dev/null +++ b/src/Kyoto/Streams/CZipOutputStream.cpp @@ -0,0 +1,53 @@ +#include "Kyoto/Streams/CZipOutputStream.hpp" + +#include "rstl/math.hpp" + +#include "Kyoto/Streams/CZipSupport.hpp" + +CZipOutputStream::CZipOutputStream(COutputStream* out, int level) +: COutputStream(1024) +, mOutput(out) +, mCompressedBytesWritten(0) +, mZStream(new z_stream) +, mUnk(0) { + mZStream->zalloc = CZipSupport::Alloc; + mZStream->zfree = CZipSupport::Free; + mZStream->opaque = nullptr; + + int useLevel = 9; + if (level < 10) { + useLevel = level; + } + deflateInit(mZStream.get(), level); +} + +CZipOutputStream::~CZipOutputStream() { + DoFlush(); + while (!Process(true)) + ; +} + +void CZipOutputStream::Write(const void* buf, size_t len) { + mZStream->next_in = (Bytef*)buf; + mZStream->avail_in = len; + + while (mZStream->avail_in != 0) { + Process(false); + } +} + + +bool CZipOutputStream::Process(bool flush) { + Bytef outBuf[1024]; + mZStream->avail_out = 1024; + mZStream->next_out = outBuf; + int ret = deflate(mZStream.get(), flush); + /* assertion failure logic */ + + if (mZStream->avail_out != 1024) { + mOutput->DoPut(outBuf, 1024 - mZStream->avail_out); + mCompressedBytesWritten += 1024 - mZStream->avail_out; + } + + return ret == Z_STREAM_END; +}