-
Notifications
You must be signed in to change notification settings - Fork 60
Expand file tree
/
Copy pathZlibModule.java
More file actions
169 lines (148 loc) · 5.95 KB
/
Copy pathZlibModule.java
File metadata and controls
169 lines (148 loc) · 5.95 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
package org.python.modules.zlib;
import com.jcraft.jzlib.JZlib;
import org.python.core.ArgParser;
import org.python.core.BufferProtocol;
import org.python.core.Py;
import org.python.core.PyBytes;
import org.python.core.PyException;
import org.python.core.PyLong;
import org.python.core.PyObject;
import org.python.core.PyStringMap;
import org.python.expose.ExposedConst;
import org.python.expose.ExposedFunction;
import org.python.expose.ExposedModule;
import org.python.expose.ModuleInit;
import org.python.modules.binascii;
import java.util.zip.Adler32;
import java.util.zip.DataFormatException;
import java.util.zip.Deflater;
import java.util.zip.Inflater;
@ExposedModule(name = "zlib")
public class ZlibModule {
@ExposedConst
public static final int DEFLATED = Deflater.DEFLATED;
@ExposedConst
public static final int DEF_BUF_SIZE = 16384;
@ExposedConst
public static final int DEF_MEM_LEVEL = 8;
@ExposedConst
public static final int MAX_WBITS = 15;
@ExposedConst
public static final int Z_DEFAULT_STRATEGY = Deflater.DEFAULT_STRATEGY;
@ExposedConst
public static final int Z_FILTERED = Deflater.FILTERED;
@ExposedConst
public static final int Z_HUFFMAN_ONLY = Deflater.HUFFMAN_ONLY;
@ExposedConst
public static final int Z_DEFAULT_COMPRESSION = Deflater.DEFAULT_COMPRESSION;
@ExposedConst
public static final int Z_BEST_COMPRESSION = Deflater.BEST_COMPRESSION;
@ExposedConst
public static final int Z_BEST_SPEED = Deflater.BEST_SPEED;
@ExposedConst
public static final int Z_NO_FLUSH = Deflater.NO_FLUSH;
@ExposedConst
public static final int Z_SYNC_FLUSH = Deflater.SYNC_FLUSH;
@ExposedConst
public static final int Z_FULL_FLUSH = Deflater.FULL_FLUSH;
@ExposedConst
public static final int Z_FINISH = 4;
@ExposedConst
public static final String ZLIB_VERSION = "1.2.8";
@ExposedConst
public static final String ZLIB_RUNTIME_VERSION = "1.2.8";
public static final PyObject error = Py.makeClass("zlib.error", Py.BaseException, new PyStringMap());
@ModuleInit
public static void init(PyObject dict) {
dict.__setitem__("error", error);
dict.__setitem__("compressobj", PyCompress.TYPE);
dict.__setitem__("decompressobj", PyDecompress.TYPE);
}
@ExposedFunction
public static final PyObject adler32(PyObject[] args, String[] keywords) {
ArgParser ap = new ArgParser("adler32", args, keywords, "data", "value");
long start = ap.getLong(1, 1);
PyObject data = ap.getPyObject(0);
if (data instanceof BufferProtocol) {
Adler32 checksum = new Adler32();
byte[] bytes = Py.unwrapBuffer(data);
checksum.update(bytes);
long result = checksum.getValue();
if (start != 1) {
result = JZlib.adler32_combine(start, result, bytes.length);
}
return new PyLong(result);
}
throw Py.TypeError(String.format("a bytes-like object expected, not '%s'", data.getType().getName()));
}
@ExposedFunction
public static final long crc32(PyObject[] args, String[] keywords) {
ArgParser ap = new ArgParser("crc32", args, keywords, "data", "value");
PyObject data = ap.getPyObject(0);
long value = ap.getLong(1, 0);
return binascii.crc32(data, value);
}
@ExposedFunction
public static final PyObject compress(PyObject[] args, String[] keywords) {
ArgParser ap = new ArgParser("compress", args, keywords, "bytes", "level");
PyObject bytes = ap.getPyObject(0);
int level = ap.getInt(1, 6); // not used, always 1
if (level > 9 || level < 0) {
throw new PyException(error, "Bad compress level");
}
Deflater deflater = new Deflater(level);
deflater.setInput(Py.unwrapBuffer(bytes));
return deflate(deflater, Deflater.SYNC_FLUSH);
}
@ExposedFunction
public static final PyObject decompress(PyObject[] args, String[] keywords) {
ArgParser ap = new ArgParser("decompress", args, keywords, "data", "wbits", "bufsize");
PyObject data = ap.getPyObject(0);
// unused
int wbits = ap.getInt(1, 15);
int bufsize = ap.getInt(2, 16384);
Inflater inflater = new Inflater();
inflater.setInput(Py.unwrapBuffer(data));
return inflate(inflater);
}
protected static final PyBytes deflate(Deflater deflater, int mode) {
byte[] buf = new byte[DEF_BUF_SIZE];
deflater.finish();
int len = deflater.deflate(buf, 0, buf.length, mode);
int totalLen = len;
while (len == DEF_BUF_SIZE) {
byte[] tmp = buf;
buf = new byte[tmp.length + DEF_BUF_SIZE ];
System.arraycopy(tmp, 0, buf, 0, tmp.length);
len = deflater.deflate(buf, tmp.length, DEF_BUF_SIZE, mode);
totalLen += len;
if (len < DEF_BUF_SIZE) break;
}
deflater.end();
return new PyBytes(buf, 0, totalLen);
}
protected static final PyBytes inflate(Inflater inflater) {
byte[] buf = new byte[DEF_BUF_SIZE];
try {
int len = inflater.inflate(buf);
int totalLen = len;
while (len == DEF_BUF_SIZE) {
byte[] tmp = buf;
buf = new byte[tmp.length + DEF_BUF_SIZE];
System.arraycopy(tmp, 0, buf, 0, tmp.length);
len = inflater.inflate(buf, tmp.length, DEF_BUF_SIZE);
totalLen += len;
if (len < DEF_BUF_SIZE) break;
}
inflater.end();
return new PyBytes(buf, 0, totalLen);
} catch (DataFormatException e) {
throw new PyException(error, e.getMessage());
}
}
protected static final void validateWbits(int wbits) {
if ((wbits > -9 && wbits < 0) || (wbits >= 0 && wbits < 9) || wbits > MAX_WBITS) {
throw Py.ValueError("Invalid initialization option");
}
}
}