Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/core/IronPython.Modules/zipimport.cs
Original file line number Diff line number Diff line change
Expand Up @@ -427,7 +427,7 @@ private byte[] GetData(CodeContext context, string archive, PythonTuple toc_entr
data = raw_data;
} else {
// decompress with zlib
data = ZlibModule.Decompress(raw_data, -15);
data = ZlibModule.Decompress(context, raw_data, -15);
}

} finally {
Expand Down
72 changes: 28 additions & 44 deletions src/core/IronPython.Modules/zlib/Compress.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,41 +6,41 @@
//

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;

using ComponentAce.Compression.Libs.ZLib;

using IronPython.Runtime;
using IronPython.Runtime.Operations;

using Microsoft.Scripting.Runtime;
using Microsoft.Scripting.Utils;

namespace IronPython.Zlib
{
namespace IronPython.Zlib {
[PythonType]
public class Compress
{
public class Compress {
private const int Z_OK = ZlibModule.Z_OK;
private const int Z_BUF_ERROR = ZlibModule.Z_BUF_ERROR;
private const int Z_STREAM_END = ZlibModule.Z_STREAM_END;

private const int Z_NO_FLUSH = ZlibModule.Z_NO_FLUSH;
private const int Z_FINISH = ZlibModule.Z_FINISH;

internal Compress(int level, int method, int wbits, int memlevel, int strategy)
{
private readonly CodeContext _context;
private ZStream zst;

internal Compress(CodeContext context, int level, int method, int wbits, int memlevel, int strategy) {
_context = context;
zst = new ZStream();
int err = zst.DeflateInit(level, wbits);
switch(err)
{
switch (err) {
case ZlibModule.Z_OK:
break;

case ZlibModule.Z_STREAM_ERROR:
throw PythonOps.ValueError("Invalid initialization option");

default:
throw ZlibModule.zlib_error(this.zst, err, "while creating compression object");
throw ZlibModule.zlib_error(_context, this.zst, err, "while creating compression object");
}
}

Expand All @@ -49,8 +49,7 @@ internal Compress(int level, int method, int wbits, int memlevel, int strategy)
After calling this function, some of the input data may still
be stored in internal buffers for later processing.
Call the flush() method to clear these buffers.")]
public Bytes compress([NotNone] IBufferProtocol data)
{
public Bytes compress([NotNone] IBufferProtocol data) {
using var buffer = data.GetBuffer();
byte[] input = buffer.AsUnsafeArray() ?? buffer.ToArray();
byte[] output = new byte[ZlibModule.DEFAULTALLOC];
Expand All @@ -65,8 +64,7 @@ public Bytes compress([NotNone] IBufferProtocol data)

int err = zst.deflate(Z_NO_FLUSH);

while(err == Z_OK && zst.avail_out == 0)
{
while (err == Z_OK && zst.avail_out == 0) {
int length = output.Length;
Array.Resize(ref output, output.Length * 2);

Expand All @@ -76,9 +74,8 @@ public Bytes compress([NotNone] IBufferProtocol data)
err = zst.deflate(Z_NO_FLUSH);
}

if(err != Z_OK && err != Z_BUF_ERROR)
{
throw ZlibModule.zlib_error(this.zst, err, "while compressing");
if (err != Z_OK && err != Z_BUF_ERROR) {
throw ZlibModule.zlib_error(_context, this.zst, err, "while compressing");
}

return GetBytes(output, 0, (int)(zst.total_out - start_total_out));
Expand All @@ -90,12 +87,10 @@ public Bytes compress([NotNone] IBufferProtocol data)
default value used when mode is not specified is Z_FINISH.
If mode == Z_FINISH, the compressor object can no longer be used after
calling the flush() method. Otherwise, more data can still be compressed.")]
public Bytes flush(int mode=Z_FINISH)
{
public Bytes flush(int mode = Z_FINISH) {
byte[] output = new byte[ZlibModule.DEFAULTALLOC];

if(mode == Z_NO_FLUSH)
{
if (mode == Z_NO_FLUSH) {
return Bytes.Empty;
}

Expand All @@ -106,8 +101,7 @@ public Bytes flush(int mode=Z_FINISH)
zst.avail_out = output.Length;

int err = zst.deflate((FlushStrategy)mode);
while(err == Z_OK && zst.avail_out == 0)
{
while (err == Z_OK && zst.avail_out == 0) {
int old_length = output.Length;
Array.Resize(ref output, output.Length * 2);

Expand All @@ -117,32 +111,22 @@ public Bytes flush(int mode=Z_FINISH)
err = zst.deflate((FlushStrategy)mode);
}

if(err == Z_STREAM_END && mode == Z_FINISH)
{
if (err == Z_STREAM_END && mode == Z_FINISH) {
err = zst.deflateEnd();
if(err != Z_OK)
{
throw ZlibModule.zlib_error(this.zst, err, "from deflateEnd()");
if (err != Z_OK) {
throw ZlibModule.zlib_error(_context, this.zst, err, "from deflateEnd()");
}
}
else if(err != Z_OK && err != Z_BUF_ERROR)
{
throw ZlibModule.zlib_error(this.zst, err, "while flushing");
} else if (err != Z_OK && err != Z_BUF_ERROR) {
throw ZlibModule.zlib_error(_context, this.zst, err, "while flushing");
}

return GetBytes(output, 0, (int)(zst.total_out - start_total_out));
}

//[Documentation("copy() -- Return a copy of the compression object.")]
//public Compress copy()
//{
// throw new NotImplementedException();
//}

private ZStream zst;
// TODO: needs a deep clone of ZStream (zlib.NET has no deflateCopy/inflateCopy)
//public Compress copy() => throw new NotImplementedException();

private static Bytes GetBytes(byte[] bytes, int index, int count)
{
private static Bytes GetBytes(byte[] bytes, int index, int count) {
var res = new byte[count];
Array.Copy(bytes, index, res, 0, count);
return Bytes.Make(res);
Expand Down
89 changes: 38 additions & 51 deletions src/core/IronPython.Modules/zlib/Decompress.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,41 +6,41 @@
//

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;

using ComponentAce.Compression.Libs.ZLib;

using IronPython.Runtime;
using IronPython.Runtime.Operations;

using Microsoft.Scripting.Runtime;
using Microsoft.Scripting.Utils;

namespace IronPython.Zlib
{
namespace IronPython.Zlib {
[PythonType]
public class Decompress
{
public class Decompress {
private const int Z_OK = ZlibModule.Z_OK;
private const int Z_STREAM_END = ZlibModule.Z_STREAM_END;
private const int Z_BUF_ERROR = ZlibModule.Z_BUF_ERROR;

private const int Z_SYNC_FLUSH = ZlibModule.Z_SYNC_FLUSH;
private const int Z_FINISH = ZlibModule.Z_FINISH;

internal Decompress(int wbits)
{
private readonly CodeContext _context;
private ZStream zst;

internal Decompress(CodeContext context, int wbits) {
_context = context;
zst = new ZStream();
int err = zst.inflateInit(wbits);
switch(err)
{
switch (err) {
case ZlibModule.Z_OK:
break;

case ZlibModule.Z_STREAM_ERROR:
throw PythonOps.ValueError("Invalid initialization option");

default:
throw ZlibModule.zlib_error(this.zst, err, "while creating decompression object");
throw ZlibModule.zlib_error(_context, this.zst, err, "while creating decompression object");
}

unused_data = Bytes.Empty;
Expand All @@ -59,9 +59,8 @@ Call the flush() method to clear these buffers.
If the max_length parameter is specified then the return value will be
no longer than max_length. Unconsumed input data will be stored in
the unconsumed_tail attribute.")]
public Bytes decompress([NotNone] IBufferProtocol data, int max_length=0)
{
if(max_length < 0) throw new ArgumentException("max_length must be greater than zero");
public Bytes decompress([NotNone] IBufferProtocol data, int max_length = 0) {
if (max_length < 0) throw new ArgumentException("max_length must be greater than zero");

using var buffer = data.GetBuffer();
byte[] input = buffer.AsUnsafeArray() ?? buffer.ToArray();
Expand All @@ -77,32 +76,30 @@ public Bytes decompress([NotNone] IBufferProtocol data, int max_length=0)

int err = zst.inflate(FlushStrategy.Z_SYNC_FLUSH);

while(err == Z_OK && zst.avail_out == 0)
{
if(max_length > 0 && output.Length >= max_length)
while (err == Z_OK && zst.avail_out == 0) {
if (max_length > 0 && output.Length >= max_length)
break;

int old_length = output.Length;
Array.Resize(ref output, output.Length * 2);
int new_length = output.Length * 2;
if (max_length > 0 && new_length > max_length) new_length = max_length;
Array.Resize(ref output, new_length);
zst.avail_out = new_length - old_length;
zst.next_out = output;
zst.avail_out = old_length;

err = zst.inflate(FlushStrategy.Z_SYNC_FLUSH);
}

if(max_length > 0)
{
unconsumed_tail = GetBytes(zst.next_in, zst.next_in_index, zst.avail_in);
}

if(err == Z_STREAM_END)
{
unused_data += GetBytes(zst.next_in, zst.next_in_index, zst.avail_in);
var remaining = GetBytes(zst.next_in, zst.next_in_index, zst.avail_in);
if (err == Z_STREAM_END) {
unused_data += remaining;
unconsumed_tail = Bytes.Empty;
eof = true;
}
else if(err != Z_OK && err != Z_BUF_ERROR)
{
throw ZlibModule.zlib_error(this.zst, err, "while decompressing");
} else {
unconsumed_tail = remaining;
if (err != Z_OK && err != Z_BUF_ERROR) {
throw ZlibModule.zlib_error(_context, this.zst, err, "while decompressing");
}
}

return GetBytes(output, 0, (int)(zst.total_out - start_total_out));
Expand All @@ -115,9 +112,8 @@ public Bytes decompress([NotNone] IBufferProtocol data, int max_length=0)
output buffer.

The decompressor object can no longer be used after this call.")]
public Bytes flush(int length=ZlibModule.DEFAULTALLOC)
{
if(length < 1)
public Bytes flush(int length = ZlibModule.DEFAULTALLOC) {
if (length < 1)
throw PythonOps.ValueError("length must be greater than 0.");

byte[] output = new byte[length];
Expand All @@ -129,8 +125,7 @@ public Bytes flush(int length=ZlibModule.DEFAULTALLOC)

int err = zst.inflate(FlushStrategy.Z_FINISH);

while((err == Z_OK || err == Z_BUF_ERROR) &&zst.avail_out == 0)
{
while ((err == Z_OK || err == Z_BUF_ERROR) && zst.avail_out == 0) {
int old_length = output.Length;
Array.Resize(ref output, output.Length * 2);
zst.next_out = output;
Expand All @@ -139,28 +134,20 @@ public Bytes flush(int length=ZlibModule.DEFAULTALLOC)
err = zst.inflate(FlushStrategy.Z_FINISH);
}

if(err == Z_STREAM_END)
{
if (err == Z_STREAM_END) {
err = zst.inflateEnd();
if(err != Z_OK)
{
throw ZlibModule.zlib_error(this.zst, err, "from inflateEnd()");
if (err != Z_OK) {
throw ZlibModule.zlib_error(_context, this.zst, err, "from inflateEnd()");
}
}

return GetBytes(output, 0, (int)(zst.total_out - start_total_out));
}

//[Documentation("copy() -- Return a copy of the decompression object.")]
//public Compress copy()
//{
// throw new NotImplementedException();
//}

private ZStream zst;
// TODO: needs a deep clone of ZStream (zlib.NET has no deflateCopy/inflateCopy)
//public Decompress copy() => throw new NotImplementedException();

private static Bytes GetBytes(byte[] bytes, int index, int count)
{
private static Bytes GetBytes(byte[] bytes, int index, int count) {
var res = new byte[count];
Array.Copy(bytes, index, res, 0, count);
return Bytes.Make(res);
Expand Down
Loading
Loading