1
4
5# define ZLIB_CONST 1
6
7# include "luametatex.h"
8
9
15
16# define ziplib_in_char_ptr const unsigned char *
17# define ziplib_out_char_ptr unsigned char *
18
19# define ziplib_buffer_size 16*1024
20
21static int ziplib_aux_compress(
22 lua_State *L,
23 const char *data,
24 int size,
25 int level,
26 int method,
27 int window,
28 int memory,
29 int strategy,
30 int buffersize
31)
32{
33 int state;
34 z_stream zipstream;
35 zipstream.zalloc = &lmt_zlib_alloc;
36 zipstream.zfree = &lmt_zlib_free;
37 zipstream.next_out = Z_NULL;
38 zipstream.avail_out = 0;
39 zipstream.next_in = Z_NULL;
40 zipstream.avail_in = 0;
41 state = deflateInit2(&zipstream, level, method, window, memory, strategy);
42 if (state == Z_OK) {
43 luaL_Buffer buffer;
44 luaL_buffinit(L, &buffer);
45 zipstream.next_in = (ziplib_in_char_ptr) data;
46 zipstream.avail_in = size;
47 while (1) {
48 zipstream.next_out = (ziplib_out_char_ptr) luaL_prepbuffsize(&buffer, buffersize);
49 zipstream.avail_out = buffersize;
50 state = deflate(&zipstream, Z_FINISH);
51 if (state != Z_OK && state != Z_STREAM_END) {
52 lua_pushnil(L);
53 break;
54 } else {
55 luaL_addsize(&buffer, buffersize - zipstream.avail_out);
56 if (zipstream.avail_out != 0) {
57 luaL_pushresult(&buffer);
58 break;
59 }
60 }
61 }
62 deflateEnd(&zipstream);
63 } else {
64 lua_pushnil(L);
65 }
66 return 1;
67}
68
69static int ziplib_compress(lua_State *L)
70{
71 const char *data = luaL_checkstring(L, 1);
72 int size = (int) lua_rawlen(L, 1);
73 int level = lmt_optinteger(L, 2, Z_DEFAULT_COMPRESSION);
74 int method = lmt_optinteger(L, 3, Z_DEFLATED);
75 int window = lmt_optinteger(L, 4, 15);
76 int memory = lmt_optinteger(L, 5, 8);
77 int strategy = lmt_optinteger(L, 6, Z_DEFAULT_STRATEGY);
78 return ziplib_aux_compress(L, data, size, level, method, window, memory, strategy, ziplib_buffer_size);
79}
80
81static int ziplib_compresssize(lua_State *L)
82{
83 const char *data = luaL_checkstring(L, 1);
84 int size = (int) lua_rawlen(L, 1);
85 int level = lmt_optinteger(L, 2, Z_DEFAULT_COMPRESSION);
86 int buffersize = lmt_optinteger(L, 3, ziplib_buffer_size);
87 int window = lmt_optinteger(L, 4, 15);
88 return ziplib_aux_compress(L, data, size, level, Z_DEFLATED, window, 8, Z_DEFAULT_STRATEGY, buffersize);
89}
90
91static int ziplib_decompress(lua_State *L)
92{
93 const char *data = luaL_checkstring(L, 1);
94 int size = (int) lua_rawlen(L, 1);
95 int window = lmt_optinteger(L, 2, 15);
96 int state;
97 z_stream zipstream;
98 zipstream.zalloc = &lmt_zlib_alloc;
99 zipstream.zfree = &lmt_zlib_free;
100 zipstream.next_out = Z_NULL;
101 zipstream.avail_out = 0;
102 zipstream.next_in = Z_NULL;
103 zipstream.avail_in = 0;
104 state = inflateInit2(&zipstream, window);
105 if (state == Z_OK) {
106 luaL_Buffer buffer;
107 luaL_buffinit(L, &buffer);
108 zipstream.next_in = (ziplib_in_char_ptr) data;
109 zipstream.avail_in = size;
110 while (1) {
111 zipstream.next_out = (ziplib_out_char_ptr) luaL_prepbuffsize(&buffer, ziplib_buffer_size);
112 zipstream.avail_out = ziplib_buffer_size;
113 state = inflate(&zipstream, Z_NO_FLUSH);
114 luaL_addsize(&buffer, ziplib_buffer_size - zipstream.avail_out);
115 if (state == Z_STREAM_END) {
116 luaL_pushresult(&buffer);
117 break;
118 } else if (state != Z_OK) {
119 lua_pushnil(L);
120 break;
121 } else if (zipstream.avail_out == 0) {
122 continue;
123 } else if (zipstream.avail_in == 0) {
124 luaL_pushresult(&buffer);
125 break;
126 }
127 }
128 inflateEnd(&zipstream);
129 } else {
130 lua_pushnil(L);
131 }
132 return 1;
133}
134
135static int ziplib_decompresssize(lua_State *L)
136{
137 const char *data = luaL_checkstring(L, 1);
138 int size = (int) lua_rawlen(L, 1);
139 int targetsize = lmt_tointeger(L, 2);
140 int window = lmt_optinteger(L, 3, 15);
141 int state;
142 z_stream zipstream;
143 zipstream.zalloc = &lmt_zlib_alloc;
144 zipstream.zfree = &lmt_zlib_free;
145 zipstream.next_out = Z_NULL;
146 zipstream.avail_out = 0;
147 zipstream.next_in = Z_NULL;
148 zipstream.avail_in = 0;
149 state = inflateInit2(&zipstream, window);
150 if (state == Z_OK) {
151 luaL_Buffer buffer;
152 zipstream.next_in = (ziplib_in_char_ptr) data;
153 zipstream.avail_in = size;
154 zipstream.next_out = (ziplib_out_char_ptr) luaL_buffinitsize(L, &buffer, (lua_Integer) targetsize + 100);
155 zipstream.avail_out = targetsize + 100;
156 state = inflate(&zipstream, Z_NO_FLUSH);
157 if (state != Z_OK && state != Z_STREAM_END) {
158 lua_pushnil(L);
159 } else if (zipstream.avail_in == 0) {
160 luaL_pushresultsize(&buffer, targetsize);
161 } else {
162 lua_pushnil(L);
163 }
164 inflateEnd(&zipstream);
165 } else {
166 lua_pushnil(L);
167 }
168 return 1;
169}
170
171static int ziplib_adler32(lua_State *L)
172{
173 int checksum = lmt_optinteger(L, 2, 0);
174 size_t buffersize = 0;
175 const char *buffer = lua_tolstring(L, 1, &buffersize);
176 checksum = adler32(checksum, (ziplib_in_char_ptr) buffer, (unsigned int) buffersize);
177 lua_pushinteger(L, checksum);
178 return 1;
179}
180
181static int ziplib_crc32(lua_State *L)
182{
183 int checksum = lmt_optinteger(L, 2, 0);
184 size_t buffersize = 0;
185 const char *buffer = lua_tolstring(L, 1, &buffersize);
186 checksum = crc32(checksum, (ziplib_in_char_ptr) buffer, (unsigned int) buffersize);
187 lua_pushinteger(L, checksum);
188 return 1;
189}
190
191static struct luaL_Reg ziplib_function_list[] = {
192 { "compress", ziplib_compress },
193 { "compresssize", ziplib_compresssize },
194 { "decompress", ziplib_decompress },
195 { "decompresssize", ziplib_decompresssize },
196 { "adler32", ziplib_adler32 },
197 { "crc32", ziplib_crc32 },
198 { NULL, NULL },
199};
200
201int luaopen_xzip(lua_State *L) {
202 lua_newtable(L);
203 luaL_setfuncs(L, ziplib_function_list, 0);
204 return 1;
205}
206
207 |