diff --git a/include/hx/zip/Compress.hpp b/include/hx/zip/Compress.hpp new file mode 100644 index 000000000..85a9ef8f3 --- /dev/null +++ b/include/hx/zip/Compress.hpp @@ -0,0 +1,19 @@ +#pragma once + +#include "Zip.hpp" + +HX_DECLARE_CLASS2(hx, zip, Compress) + +namespace hx +{ + namespace zip + { + struct Compress_obj : Zip_obj + { + static Compress create(int level); + static Array run(cpp::marshal::View src, int level); + + virtual int getBounds(int length) = 0; + }; + } +} diff --git a/include/hx/zip/Uncompress.hpp b/include/hx/zip/Uncompress.hpp new file mode 100644 index 000000000..2a67827d2 --- /dev/null +++ b/include/hx/zip/Uncompress.hpp @@ -0,0 +1,17 @@ +#pragma once + +#include "Zip.hpp" + +HX_DECLARE_CLASS2(hx, zip, Uncompress) + +namespace hx +{ + namespace zip + { + struct Uncompress_obj : Zip_obj + { + static Uncompress create(int windowSize); + static Array run(cpp::marshal::View src, int bufferSize); + }; + } +} diff --git a/include/hx/zip/Zip.hpp b/include/hx/zip/Zip.hpp new file mode 100644 index 000000000..4b3342f3a --- /dev/null +++ b/include/hx/zip/Zip.hpp @@ -0,0 +1,36 @@ +#pragma once + +#ifndef HXCPP_H +#include +#endif + +HX_DECLARE_CLASS2(hx, zip, Zip) + +namespace hx +{ + namespace zip + { + enum Flush { + None, + Sync, + Full, + Finish, + Block + }; + + struct Result final { + const bool done; + const int read; + const int write; + + Result(int inDone, int inRead, int inWrite); + }; + + struct Zip_obj : hx::Object + { + virtual Result execute(cpp::marshal::View src, cpp::marshal::View dst) = 0; + virtual void setFlushMode(Flush mode) = 0; + virtual void close() = 0; + }; + } +} \ No newline at end of file diff --git a/include/hxString.h b/include/hxString.h index 280a8abba..e6cdf745e 100644 --- a/include/hxString.h +++ b/include/hxString.h @@ -46,10 +46,8 @@ class HXCPP_EXTERN_CLASS_ATTRIBUTES String static String create(const char16_t *inPtr,int inLen=-1); static String create(const char *inPtr,int inLen=-1); -#if (HXCPP_API_LEVEL>=500) static String create(const ::cpp::marshal::View& buffer); static String create(const ::cpp::marshal::View& buffer); -#endif // Uses non-gc memory and wont ever be collected static ::String createPermanent(const char *inUtf8, int inLen); @@ -173,10 +171,8 @@ class HXCPP_EXTERN_CLASS_ATTRIBUTES String const wchar_t *wchar_str(hx::IStringAlloc *inBuffer = 0) const; const char16_t *wc_str(hx::IStringAlloc *inBuffer = 0, int *outCharLength = 0) const; -#if (HXCPP_API_LEVEL >= 500) bool wc_str(::cpp::marshal::View buffer, int* outCharLength = nullptr) const; bool utf8_str(::cpp::marshal::View buffer, int* outByteLength = nullptr) const; -#endif const char *__CStr() const { return utf8_str(); }; const wchar_t *__WCStr() const { return wchar_str(0); } diff --git a/include/hxcpp.h b/include/hxcpp.h index 053a153b2..68824a682 100755 --- a/include/hxcpp.h +++ b/include/hxcpp.h @@ -351,15 +351,13 @@ typedef PropertyAccessMode PropertyAccess; #endif #include #include -#if (HXCPP_API_LEVEL>=500) - #include - #include - #include - #include - #include - #include - #include -#endif +#include +#include +#include +#include +#include +#include +#include #include #include #include diff --git a/src/String.cpp b/src/String.cpp index 280c8cdd4..fedef3873 100644 --- a/src/String.cpp +++ b/src/String.cpp @@ -788,7 +788,6 @@ String String::create(const char *inString,int inLength) return String(s,len); } -#if (HXCPP_API_LEVEL>=500) String String::create(const::cpp::marshal::View& buffer) { auto start = buffer.ptr.ptr; @@ -824,7 +823,6 @@ String String::create(const cpp::marshal::View& buffer) return String::create(buffer.ptr.ptr, buffer.length - (end - start) - extra); } -#endif String::String(const Dynamic &inRHS) { @@ -1794,8 +1792,6 @@ const char16_t * String::wc_str(hx::IStringAlloc *inBuffer, int *outCharLength) return str; } -#if (HXCPP_API_LEVEL >= 500) - bool String::wc_str(::cpp::marshal::View buffer, int* outCharLength) const { #ifdef HX_SMART_STRINGS @@ -1918,8 +1914,6 @@ bool String::utf8_str(::cpp::marshal::View buffer, int* outByteLength) con return true; } -#endif - const wchar_t * String::wchar_str(hx::IStringAlloc *inBuffer) const { if (!__s) diff --git a/src/hx/libs/zlib/Build.xml b/src/hx/libs/zlib/Build.xml index c7549ba6d..ab0b3ee41 100644 --- a/src/hx/libs/zlib/Build.xml +++ b/src/hx/libs/zlib/Build.xml @@ -1,42 +1,7 @@ - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - -
-
- - - - - -
+ + + + + + + \ No newline at end of file diff --git a/src/hx/libs/zlib/ZLib.cpp b/src/hx/libs/zlib/ZLib.cpp deleted file mode 100644 index a44a92fa3..000000000 --- a/src/hx/libs/zlib/ZLib.cpp +++ /dev/null @@ -1,284 +0,0 @@ -#include -#include -#include -#include - -/** - -

ZLib

-

- Give access to the popular ZLib compression library, used in several file - formats such as ZIP and PNG. -

-
-**/ - -namespace { - -struct ZipResult -{ - inline ZipResult(bool inOk, bool inDone, int inRead, int inWrite) - : ok(inOk) - , done(inDone) - , read(inRead) - , write(inWrite) { } - bool ok; - bool done; - int read; - int write; -}; - -struct ZStream : public hx::Object -{ - HX_IS_INSTANCE_OF enum { _hx_ClassId = hx::clsIdZLib }; - - z_stream *z; - bool isInflate; - int flush; - - void create(bool inIsInflate, int inParam) - { - isInflate = inIsInflate; - flush = Z_NO_FLUSH; - z = (z_stream*)malloc(sizeof(z_stream)); - memset(z,0,sizeof(z_stream)); - int err = 0; - if (!isInflate) - { - if( (err = deflateInit(z,inParam)) != Z_OK ) - { - free(z); - z = 0; - onError(err); - } - } - else - { - if( (err = inflateInit2(z,inParam)) != Z_OK ) - { - free(z); - z = 0; - onError(err); - } - } - - _hx_set_finalizer(this, finalize); - } - - static void finalize(Dynamic obj) - { - ((ZStream *)(obj.mPtr))->destroy(); - } - - void destroy() - { - if (z) - { - if (isInflate) - inflateEnd(z); - else - deflateEnd(z); - free(z); - z = 0; - } - } - - ZipResult deflate(Array src, int srcpos, Array dest, int dstpos) - { - if( srcpos < 0 || dstpos < 0 ) - return ZipResult( 0,0,0,0 ); - - int slen = src->length - srcpos; - int dlen = dest->length - dstpos; - if( slen < 0 || dlen < 0 ) - return ZipResult( 0,0,0,0 ); - - z->next_in = (Bytef*)(&src[srcpos]); - z->next_out = (Bytef*)(&dest[dstpos]); - z->avail_in = slen; - z->avail_out = dlen; - int err = 0; - if( (err = ::deflate(z,flush)) < 0 ) - onError(err); - - z->next_in = 0; - z->next_out = 0; - return ZipResult( true, err == Z_STREAM_END, (int)(slen - z->avail_in), (int)(dlen - z->avail_out) ); - } - - ZipResult inflate(Array src, int srcpos, Array dest, int dstpos) - { - int slen = src->length; - int dlen = dest->length; - - if( srcpos < 0 || dstpos < 0 ) - return ZipResult( 0,0,0,0 ); - slen -= srcpos; - dlen -= dstpos; - if( slen < 0 || dlen < 0 ) - return ZipResult( 0,0,0,0 ); - - z->next_in = (Bytef*)&src[srcpos]; - z->next_out = (Bytef*)&dest[dstpos]; - z->avail_in = slen; - z->avail_out = dlen; - int err = 0; - if( (err = ::inflate(z,flush)) < 0 ) - onError(err); - z->next_in = 0; - z->next_out = 0; - return ZipResult( true, err == Z_STREAM_END, (int)(slen - z->avail_in), (int)(dlen - z->avail_out) ); - } - - int getDeflateBound(int inLength) - { - return deflateBound(z,inLength); - } - - void setFlushMode(String inMode) - { - if( inMode == HX_CSTRING("NO") ) - flush = Z_NO_FLUSH; - else if( inMode==HX_CSTRING("SYNC")) - flush = Z_SYNC_FLUSH; - else if( inMode==HX_CSTRING("FULL")) - flush = Z_FULL_FLUSH; - else if( inMode==HX_CSTRING("FINISH")) - flush = Z_FINISH; - else if( inMode==HX_CSTRING("BLOCK")) - flush = Z_BLOCK; - } - - - void onError(int inCode) - { - String message = HX_CSTRING("ZLib Error : "); - if( z && z->msg ) - message += String(z->msg) + HX_CSTRING("(") + String(inCode) + HX_CSTRING(")"); - else - message += String(inCode); - hx::Throw(message); - } - - -}; - -ZStream *GetDeflateStream(Dynamic inHandle) -{ - ZStream *z = dynamic_cast(inHandle.mPtr); - if (!z || !z->z || z->isInflate) - hx::Throw( HX_CSTRING("ZLib: Not a valid deflate stream")); - return z; -} - - -ZStream *GetInflateStream(Dynamic inHandle) -{ - ZStream *z = dynamic_cast(inHandle.mPtr); - if (!z || !z->z || !z->isInflate) - hx::Throw( HX_CSTRING("ZLib: Not a valid inflate stream")); - return z; -} - -} // end namespace - - - - -/** - deflate_init : level:int -> 'dstream - Open a compression stream with the given level of compression -**/ -Dynamic _hx_deflate_init(int level) -{ - ZStream *zStream = new ZStream; - zStream->create(false, level); - return zStream; -} - -/** - deflate_buffer : 'dstream -> src:string -> srcpos:int -> dst:string -> dstpos:int -> { done => bool, read => int, write => int } -**/ -Dynamic _hx_deflate_buffer(Dynamic handle, Array src, int srcPos, Array dest, int destPos) -{ - ZipResult result = GetDeflateStream(handle)->deflate(src,srcPos,dest,destPos); - if (!result.ok) - return null(); - - return hx::Anon_obj::Create(3) - ->setFixed(0,HX_("write",df,6c,59,d0),result.write) - ->setFixed(1,HX_("done",82,f0,6d,42),result.done) - ->setFixed(2,HX_("read",56,4b,a7,4b),result.read); -} - - -/** - deflate_bound : 'dstream -> n:int -> int - Return the maximum buffer size needed to write [n] bytes -**/ -int _hx_deflate_bound(Dynamic handle,int length) -{ - return GetDeflateStream(handle)->getDeflateBound(length); -} - -void _hx_deflate_end(Dynamic handle) -{ - GetDeflateStream(handle)->destroy(); -} - - -/** - set_flush_mode : 'stream -> string -> void - Change the flush mode ("NO","SYNC","FULL","FINISH","BLOCK") -**/ -void _hx_zip_set_flush_mode(Dynamic handle, String flushMode) -{ - ZStream *zstream = dynamic_cast(handle.mPtr); - if (!zstream || !zstream->z) - hx::Throw( HX_CSTRING("ZLib flush: not a valid stream") ); - - zstream->setFlushMode(flushMode); -} - - - - -/** - inflate_init : window_size:int? -> 'istream - Open a decompression stream -**/ -Dynamic _hx_inflate_init(Dynamic windowBits) -{ - int bits = windowBits==null() ? MAX_WBITS : (int)windowBits; - - ZStream *zStream = new ZStream(); - zStream->create(true, bits); - return zStream; -} - -/** - inflate_buffer : 'istream -> src:string -> srcpos:int -> dst:string -> dstpos:int -> { done => bool, read => int, write => int } -**/ -Dynamic _hx_inflate_buffer(Dynamic handle, Array src, int srcPos, Array dest, int destPos) -{ - ZipResult result = GetInflateStream(handle)->inflate(src,srcPos,dest,destPos); - if (!result.ok) - return null(); - - return hx::Anon_obj::Create(3) - ->setFixed(0,HX_("write",df,6c,59,d0),result.write) - ->setFixed(1,HX_("done",82,f0,6d,42),result.done) - ->setFixed(2,HX_("read",56,4b,a7,4b),result.read); -} - -/** - inflate_end : 'istream -> void - Close a decompression stream -**/ -void _hx_inflate_end(Dynamic handle) -{ - GetInflateStream(handle)->destroy(); -} - - - diff --git a/src/hx/zip/Build.xml b/src/hx/zip/Build.xml new file mode 100644 index 000000000..0cf31265b --- /dev/null +++ b/src/hx/zip/Build.xml @@ -0,0 +1,22 @@ + + + +
+ +
+ + + + + + + + + + + + + + + +
\ No newline at end of file diff --git a/src/hx/zip/Zip.cpp b/src/hx/zip/Zip.cpp new file mode 100644 index 000000000..b3e38b33f --- /dev/null +++ b/src/hx/zip/Zip.cpp @@ -0,0 +1,129 @@ +#include +#include +#include +#include +#include + +/** + +

ZLib

+

+ Give access to the popular ZLib compression library, used in several file + formats such as ZIP and PNG. +

+
+**/ + +using namespace hx::zip; +using namespace cpp::marshal; + +hx::zip::Result::Result(int inDone, int inRead, int inWrite) : done(inDone), read(inRead), write(inWrite) {} + +/** + deflate_init : level:int -> 'dstream + Open a compression stream with the given level of compression +**/ +Dynamic _hx_deflate_init(int level) +{ + return Compress_obj::create(level); +} + +/** + deflate_buffer : 'dstream -> src:string -> srcpos:int -> dst:string -> dstpos:int -> { done => bool, read => int, write => int } +**/ +Dynamic _hx_deflate_buffer(Dynamic handle, Array src, int srcPos, Array dest, int destPos) +{ + auto srcView = View(src->getBase(), src->length).slice(srcPos); + auto dstView = View(dest->getBase(), dest->length).slice(destPos); + auto result = handle.StaticCast()->execute(srcView, dstView); + + return + hx::Anon_obj::Create(3) + ->setFixed(0,HX_("write",df,6c,59,d0),result.write) + ->setFixed(1,HX_("done",82,f0,6d,42),result.done) + ->setFixed(2,HX_("read",56,4b,a7,4b),result.read); +} + + +/** + deflate_bound : 'dstream -> n:int -> int + Return the maximum buffer size needed to write [n] bytes +**/ +int _hx_deflate_bound(Dynamic handle,int length) +{ + return handle.StaticCast()->getBounds(length); +} + +void _hx_deflate_end(Dynamic handle) +{ + handle.StaticCast()->close(); +} + + +/** + set_flush_mode : 'stream -> string -> void + Change the flush mode ("NO","SYNC","FULL","FINISH","BLOCK") +**/ +void _hx_zip_set_flush_mode(Dynamic handle, String flushMode) +{ + Flush flush; + if (flushMode == HX_CSTRING("NO")) + { + flush = Flush::None; + } + if (flushMode == HX_CSTRING("SYNC")) + { + flush = Flush::Sync; + } + if (flushMode == HX_CSTRING("FULL")) + { + flush = Flush::Full; + } + if (flushMode == HX_CSTRING("FINISH")) + { + flush = Flush::Finish; + } + if (flushMode == HX_CSTRING("BLOCK")) + { + flush = Flush::Block; + } + + handle.StaticCast()->setFlushMode(flush); +} + + + + +/** + inflate_init : window_size:int? -> 'istream + Open a decompression stream +**/ +Dynamic _hx_inflate_init(Dynamic windowBits) +{ + return Uncompress_obj::create(windowBits == null() ? 15 : (int)windowBits); +} + +/** + inflate_buffer : 'istream -> src:string -> srcpos:int -> dst:string -> dstpos:int -> { done => bool, read => int, write => int } +**/ +Dynamic _hx_inflate_buffer(Dynamic handle, Array src, int srcPos, Array dest, int destPos) +{ + auto srcView = View(src->getBase(), src->length).slice(srcPos); + auto dstView = View(dest->getBase(), dest->length).slice(destPos); + auto result = handle.StaticCast()->execute(srcView, dstView); + + return + hx::Anon_obj::Create(3) + ->setFixed(0,HX_("write",df,6c,59,d0),result.write) + ->setFixed(1,HX_("done",82,f0,6d,42),result.done) + ->setFixed(2,HX_("read",56,4b,a7,4b),result.read); +} + +/** + inflate_end : 'istream -> void + Close a decompression stream +**/ +void _hx_inflate_end(Dynamic handle) +{ + handle.StaticCast()->close(); +} diff --git a/src/hx/zip/zlib/Build.xml b/src/hx/zip/zlib/Build.xml new file mode 100644 index 000000000..5cf210ed6 --- /dev/null +++ b/src/hx/zip/zlib/Build.xml @@ -0,0 +1,52 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/hx/zip/zlib/ZLibCompress.cpp b/src/hx/zip/zlib/ZLibCompress.cpp new file mode 100644 index 000000000..1d11148ac --- /dev/null +++ b/src/hx/zip/zlib/ZLibCompress.cpp @@ -0,0 +1,144 @@ +#include +#include "ZLibCompress.hpp" + +#include +#include + +#define ZLIB_OBJ_CLOSED ::hx::Throw(HX_CSTRING("Compress closed")) + +hx::zip::Compress hx::zip::Compress_obj::create(int level) +{ + auto handle = std::unique_ptr(new z_stream()); + auto error = deflateInit(handle.get(), level); + + if (error != Z_OK) + { + hx::Throw(HX_CSTRING("ZLib Error")); + } + + return new hx::zip::zlib::ZLibCompress(handle.release()); +} + +Array hx::zip::Compress_obj::run(cpp::marshal::View src, int level) +{ + auto error = 0; + auto handle = std::unique_ptr(new z_stream()); + + if (Z_OK != (error = deflateInit(handle.get(), level))) + { + hx::Throw(HX_CSTRING("ZLib Error")); + } + + auto bounds = deflateBound(handle.get(), src.length); + if (bounds > std::numeric_limits::max()) { + hx::Throw(HX_CSTRING("Size Error")); + } + + auto output = Array(bounds, bounds); + auto dst = cpp::marshal::View(output->getBase(), bounds); + + handle->next_in = src.ptr; + handle->next_out = dst.ptr; + handle->avail_in = src.length; + handle->avail_out = dst.length; + + EnterGCFreeZone(); + error = deflate(handle.get(), Z_FINISH); + ExitGCFreeZone(); + + if (Z_STREAM_END != error) { + hx::Throw(HX_CSTRING("Compression failed")); + } + + deflateEnd(handle.get()); + + return output->slice(0, static_cast(handle->total_out)); +} + +hx::zip::zlib::ZLibCompress::ZLibCompress(z_stream* inHandle) : handle(inHandle), flush(0) +{ + _hx_set_finalizer(this, [](Dynamic obj) { reinterpret_cast(obj.mPtr)->close(); }); +} + +hx::zip::Result hx::zip::zlib::ZLibCompress::execute(cpp::marshal::View src, cpp::marshal::View dst) +{ + if (handle == nullptr) + { + ZLIB_OBJ_CLOSED; + } + + handle->next_in = src.ptr; + handle->next_out = dst.ptr; + handle->avail_in = src.length; + handle->avail_out = dst.length; + + EnterGCFreeZone(); + auto error = deflate(handle, flush); + ExitGCFreeZone(); + + if (error < 0) + { + hx::Throw(HX_CSTRING("ZLib Error")); + } + + return + Result( + error == Z_STREAM_END, + static_cast(handle->total_in), + static_cast(handle->total_out)); +} + +void hx::zip::zlib::ZLibCompress::setFlushMode(Flush mode) +{ + if (handle == nullptr) + { + ZLIB_OBJ_CLOSED; + } + + switch (mode) + { + case Flush::None: + flush = Z_NO_FLUSH; + break; + + case Flush::Sync: + flush = Z_SYNC_FLUSH; + break; + + case Flush::Full: + flush = Z_FULL_FLUSH; + break; + + case Flush::Finish: + flush = Z_FINISH; + break; + + case Flush::Block: + flush = Z_BLOCK; + break; + } +} + +int hx::zip::zlib::ZLibCompress::getBounds(const int length) +{ + if (handle == nullptr) + { + ZLIB_OBJ_CLOSED; + } + + return static_cast(deflateBound(handle, length)); +} + +void hx::zip::zlib::ZLibCompress::close() +{ + if (nullptr == handle) + { + return; + } + + deflateEnd(handle); + + handle = nullptr; + + _hx_set_finalizer(this, nullptr); +} diff --git a/src/hx/zip/zlib/ZLibCompress.hpp b/src/hx/zip/zlib/ZLibCompress.hpp new file mode 100644 index 000000000..a77361826 --- /dev/null +++ b/src/hx/zip/zlib/ZLibCompress.hpp @@ -0,0 +1,27 @@ +#pragma once + +#include +#include +#include + +namespace hx +{ + namespace zip + { + namespace zlib + { + struct ZLibCompress final : Compress_obj + { + z_stream* handle; + int flush; + + ZLibCompress(z_stream* inHandle); + + Result execute(cpp::marshal::View src, cpp::marshal::View dst) override; + void setFlushMode(Flush mode) override; + int getBounds(int length) override; + void close() override; + }; + } + } +} \ No newline at end of file diff --git a/src/hx/zip/zlib/ZLibUncompress.cpp b/src/hx/zip/zlib/ZLibUncompress.cpp new file mode 100644 index 000000000..0ddc93706 --- /dev/null +++ b/src/hx/zip/zlib/ZLibUncompress.cpp @@ -0,0 +1,138 @@ +#include +#include "ZLibUncompress.hpp" + +#include +#include + +#define ZLIB_OBJ_CLOSED ::hx::Throw(HX_CSTRING("Compress closed")) + +hx::zip::Uncompress hx::zip::Uncompress_obj::create(int windowSize) +{ + auto handle = std::unique_ptr(new z_stream()); + auto error = inflateInit2(handle.get(), windowSize); + + if (error != Z_OK) + { + hx::Throw(HX_CSTRING("ZLib Error")); + } + + return new hx::zip::zlib::ZLibUncompress(handle.release()); +} + +Array hx::zip::Uncompress_obj::run(cpp::marshal::View src, int bufferSize) +{ + auto handle = std::unique_ptr(new z_stream()); + auto error = inflateInit2(handle.get(), 15); + + if (error != Z_OK) + { + hx::Throw(HX_CSTRING("ZLib Error")); + } + + auto buffer = std::vector(bufferSize); + auto output = Array(0, 0); + auto srcCursor = 0; + + while (Z_STREAM_END != error) + { + auto srcView = src.slice(srcCursor); + + handle->next_in = srcView.ptr; + handle->next_out = buffer.data(); + handle->avail_in = srcView.length; + handle->avail_out = buffer.size(); + + EnterGCFreeZone(); + error = inflate(handle.get(), Z_SYNC_FLUSH); + ExitGCFreeZone(); + + if (error < 0) + { + hx::Throw(HX_CSTRING("ZLib Error")); + } + + output->memcpy(output->length, buffer.data(), buffer.size() - handle->avail_out); + + srcCursor += srcView.length - handle->avail_in; + } + + return output; +} + +hx::zip::zlib::ZLibUncompress::ZLibUncompress(z_stream* inHandle) : handle(inHandle), flush(0) +{ + _hx_set_finalizer(this, [](Dynamic obj) { reinterpret_cast(obj.mPtr)->close(); }); +} + +hx::zip::Result hx::zip::zlib::ZLibUncompress::execute(cpp::marshal::View src, cpp::marshal::View dst) +{ + if (handle == nullptr) + { + ZLIB_OBJ_CLOSED; + } + + handle->next_in = src.ptr; + handle->next_out = dst.ptr; + handle->avail_in = src.length; + handle->avail_out = dst.length; + + EnterGCFreeZone(); + auto error = inflate(handle, flush); + ExitGCFreeZone(); + + if (error < 0) + { + hx::Throw(HX_CSTRING("ZLib Error")); + } + + return + Result( + error == Z_STREAM_END, + static_cast(handle->total_in), + static_cast(handle->total_out)); +} + +void hx::zip::zlib::ZLibUncompress::setFlushMode(Flush mode) +{ + if (handle == nullptr) + { + ZLIB_OBJ_CLOSED; + } + + switch (mode) + { + case Flush::None: + flush = Z_NO_FLUSH; + break; + + case Flush::Sync: + flush = Z_SYNC_FLUSH; + break; + + case Flush::Full: + flush = Z_FULL_FLUSH; + break; + + case Flush::Finish: + flush = Z_FINISH; + break; + + case Flush::Block: + flush = Z_BLOCK; + break; + } +} + +void hx::zip::zlib::ZLibUncompress::close() +{ + if (nullptr == handle) + { + return; + } + + inflateEnd(handle); + + handle = nullptr; + + _hx_set_finalizer(this, nullptr); +} diff --git a/src/hx/zip/zlib/ZLibUncompress.hpp b/src/hx/zip/zlib/ZLibUncompress.hpp new file mode 100644 index 000000000..65f51d557 --- /dev/null +++ b/src/hx/zip/zlib/ZLibUncompress.hpp @@ -0,0 +1,26 @@ +#pragma once + +#include +#include +#include + +namespace hx +{ + namespace zip + { + namespace zlib + { + struct ZLibUncompress final : Uncompress_obj + { + z_stream* handle; + int flush; + + ZLibUncompress(z_stream* inHandle); + + Result execute(cpp::marshal::View src, cpp::marshal::View dst) override; + void setFlushMode(Flush mode) override; + void close() override; + }; + } + } +} diff --git a/test/std/Test.hx b/test/std/Test.hx index e505926da..4923bfce3 100644 --- a/test/std/Test.hx +++ b/test/std/Test.hx @@ -147,7 +147,7 @@ class Test extends utest.Test v("compressed size " + compressed.length ); v("try closing too many times..."); - Assert.exception(() -> compress.close(), String, null, "Zlib closed without throwing error"); + compress.close(); var decompressed = Uncompress.run(compressed); v("decompressed size:" + decompressed.length + "/" + bytes.length); diff --git a/toolchain/haxe-target.xml b/toolchain/haxe-target.xml index a5aa5ea5d..8d7362e12 100644 --- a/toolchain/haxe-target.xml +++ b/toolchain/haxe-target.xml @@ -69,6 +69,9 @@ + + +