~ubuntu-branches/ubuntu/jaunty/luatex/jaunty

« back to all changes in this revision

Viewing changes to src/libs/luazlib/lzlib.c

  • Committer: Bazaar Package Importer
  • Author(s): Norbert Preining
  • Date: 2007-09-24 12:56:11 UTC
  • Revision ID: james.westby@ubuntu.com-20070924125611-a8ge689azbptxvla
Tags: upstream-0.11.2
ImportĀ upstreamĀ versionĀ 0.11.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/************************************************************************
 
2
* Author    : Tiago Dionizio (tngd@mega.ist.utl.pt)                     *
 
3
* Library   : lzlib - Lua 5 interface to access zlib library functions  *
 
4
*                                                                       *
 
5
* Permission is hereby granted, free of charge, to any person obtaining *
 
6
* a copy of this software and associated documentation files (the       *
 
7
* "Software"), to deal in the Software without restriction, including   *
 
8
* without limitation the rights to use, copy, modify, merge, publish,   *
 
9
* distribute, sublicense, and/or sell copies of the Software, and to    *
 
10
* permit persons to whom the Software is furnished to do so, subject to *
 
11
* the following conditions:                                             *
 
12
*                                                                       *
 
13
* The above copyright notice and this permission notice shall be        *
 
14
* included in all copies or substantial portions of the Software.       *
 
15
*                                                                       *
 
16
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       *
 
17
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    *
 
18
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*
 
19
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  *
 
20
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  *
 
21
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     *
 
22
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                *
 
23
************************************************************************/
 
24
 
 
25
/************************************************************************
 
26
$Id: lzlib.c,v 1.3 2004/07/22 19:10:47 tngd Exp $
 
27
Changes:
 
28
************************************************************************/
 
29
#include <stdlib.h>
 
30
#include <string.h>
 
31
 
 
32
#include "lua.h"
 
33
#include "lauxlib.h"
 
34
 
 
35
#include "zlib.h"
 
36
 
 
37
 
 
38
/*
 
39
** =========================================================================
 
40
** compile time options wich determine available functionality
 
41
** =========================================================================
 
42
*/
 
43
 
 
44
 
 
45
/*
 
46
** =========================================================================
 
47
** zlib stream metamethods
 
48
** =========================================================================
 
49
*/
 
50
#define ZSTREAMMETA "zlib:zstream"
 
51
 
 
52
#define LZANY     (void*)-1
 
53
#define LZNONE    (void*)0
 
54
#define LZDEFLATE (void*)1
 
55
#define LZINFLATE (void*)2
 
56
 
 
57
static z_stream *lzstream_new(lua_State *L)
 
58
{
 
59
    z_stream *s = (z_stream*)lua_newuserdata(L, sizeof(z_stream));
 
60
 
 
61
    luaL_getmetatable(L, ZSTREAMMETA);
 
62
    lua_setmetatable(L, -2);        /* set metatable */
 
63
 
 
64
    s->zalloc = Z_NULL;
 
65
    s->zfree = Z_NULL;
 
66
 
 
67
    s->next_out = Z_NULL;
 
68
    s->avail_out = 0;
 
69
    s->next_in = Z_NULL;
 
70
    s->avail_in = 0;
 
71
 
 
72
    s->opaque = LZNONE;
 
73
 
 
74
    return s;
 
75
}
 
76
 
 
77
static void lzstream_cleanup(lua_State *L, z_stream *s)
 
78
{
 
79
    if (s && s->opaque != LZNONE)
 
80
    {
 
81
        if (s->opaque == LZINFLATE)
 
82
            inflateEnd(s);
 
83
        if (s->opaque == LZDEFLATE)
 
84
            deflateEnd(s);
 
85
        s->opaque = LZNONE;
 
86
    }
 
87
}
 
88
 
 
89
/* ====================================================================== */
 
90
 
 
91
static z_stream *lzstream_get(lua_State *L, int index)
 
92
{
 
93
    z_stream *s = (z_stream*)luaL_checkudata(L, index, ZSTREAMMETA);
 
94
    if (s == NULL) luaL_argerror(L, index, "bad zlib stream");
 
95
    return s;
 
96
}
 
97
 
 
98
static z_stream *lzstream_check(lua_State *L, int index, void *state)
 
99
{
 
100
    z_stream *s = lzstream_get(L, index);
 
101
    if ((state != LZANY && s->opaque != state) || s->opaque == LZNONE)
 
102
        luaL_argerror(L, index, "attempt to use invalid zlib stream");
 
103
    return s;
 
104
}
 
105
 
 
106
/* ====================================================================== */
 
107
 
 
108
static int lzstream_tostring(lua_State *L)
 
109
{
 
110
    char buf[100];
 
111
    z_stream *s = (z_stream*)luaL_checkudata(L, 1, ZSTREAMMETA);
 
112
    if (s == NULL) luaL_argerror(L, 1, "bad zlib stream");
 
113
 
 
114
    if (s->opaque == LZNONE)
 
115
        strncpy(buf, "zlib stream (closed)", 100);
 
116
    else if (s->opaque == LZDEFLATE)
 
117
        snprintf(buf, 100, "zlib deflate stream (%p)", s);
 
118
    else if (s->opaque == LZINFLATE)
 
119
        snprintf(buf, 100, "zlib inflate stream (%p)", s);
 
120
    else
 
121
        snprintf(buf, 100, "%p", s);
 
122
 
 
123
    lua_pushstring(L, buf);
 
124
    return 1;
 
125
}
 
126
 
 
127
/* ====================================================================== */
 
128
 
 
129
static int lzstream_gc(lua_State *L)
 
130
{
 
131
    z_stream *s = lzstream_get(L, 1);
 
132
    lzstream_cleanup(L, s);
 
133
    return 0;
 
134
}
 
135
 
 
136
/* ====================================================================== */
 
137
 
 
138
static int lzstream_close(lua_State *L)
 
139
{
 
140
    z_stream *s = lzstream_check(L, 1, LZANY);
 
141
    lzstream_cleanup(L, s);
 
142
    return 0;
 
143
}
 
144
 
 
145
/* ====================================================================== */
 
146
 
 
147
static int lzstream_adler(lua_State *L)
 
148
{
 
149
    z_stream *s = lzstream_check(L, 1, LZANY);
 
150
    lua_pushnumber(L, s->adler);
 
151
    return 1;
 
152
}
 
153
 
 
154
/* ====================================================================== */
 
155
 
 
156
static int lzlib_deflate(lua_State *L)
 
157
{
 
158
    int level = luaL_optint(L, 1, Z_DEFAULT_COMPRESSION);
 
159
    int method = luaL_optint(L, 2, Z_DEFLATED);
 
160
    int windowBits = luaL_optint(L, 3, 15);
 
161
    int memLevel = luaL_optint(L, 4, 8);
 
162
    int strategy = luaL_optint(L, 5, Z_DEFAULT_STRATEGY);
 
163
 
 
164
    z_stream *s = lzstream_new(L);
 
165
 
 
166
    if (deflateInit2(s, level, method, windowBits, memLevel, strategy) != Z_OK)
 
167
    {
 
168
        lua_pushliteral(L, "failed to start decompressing");
 
169
        lua_error(L);
 
170
    }
 
171
    s->opaque = LZDEFLATE;
 
172
    return 1;
 
173
}
 
174
 
 
175
/* ====================================================================== */
 
176
 
 
177
static int lzlib_inflate(lua_State *L)
 
178
{
 
179
    int windowBits = luaL_optint(L, 1, 15);
 
180
 
 
181
    z_stream *s = lzstream_new(L);
 
182
 
 
183
    if (inflateInit2(s, windowBits) != Z_OK)
 
184
    {
 
185
        lua_pushliteral(L, "failed to start compressing");
 
186
        lua_error(L);
 
187
    }
 
188
 
 
189
    s->opaque = LZINFLATE;
 
190
    return 1;
 
191
}
 
192
 
 
193
/* ====================================================================== */
 
194
 
 
195
static int lzstream_decompress(lua_State *L)
 
196
{
 
197
    z_stream *s = lzstream_check(L, 1, LZINFLATE);
 
198
    s->next_in = (char*)luaL_checkstring(L, 2);
 
199
    s->avail_in = lua_strlen(L, 2);
 
200
 
 
201
    {
 
202
        luaL_Buffer b;
 
203
        luaL_buffinit(L, &b);
 
204
        int r;
 
205
 
 
206
        do {
 
207
            s->next_out = luaL_prepbuffer(&b);
 
208
            s->avail_out = LUAL_BUFFERSIZE;
 
209
 
 
210
            /* munch some more */
 
211
            r = inflate(s, Z_SYNC_FLUSH);
 
212
            if (r != Z_OK && r != Z_STREAM_END) {
 
213
                lua_pushfstring(L, "failed to decompress [%d]", r);
 
214
                lua_error(L);
 
215
            }
 
216
 
 
217
            /* push gathered data */
 
218
            luaL_addsize(&b, LUAL_BUFFERSIZE - s->avail_out);
 
219
 
 
220
            /* until we have free space in the output buffer - meaning we are done */
 
221
        } while (s->avail_in > 0 || s->avail_out == 0);
 
222
 
 
223
        /* send gathered data if any */
 
224
        luaL_pushresult(&b);
 
225
    }
 
226
    return 1;
 
227
}
 
228
 
 
229
/* ====================================================================== */
 
230
 
 
231
static int lzstream_compress(lua_State *L)
 
232
{
 
233
    z_stream *s = lzstream_check(L, 1, LZDEFLATE);
 
234
    s->next_in = (char*)luaL_checkstring(L, 2);
 
235
    s->avail_in = lua_strlen(L, 2);
 
236
 
 
237
    {
 
238
        luaL_Buffer b;
 
239
        luaL_buffinit(L, &b);
 
240
        int r;
 
241
 
 
242
        do {
 
243
            s->next_out = luaL_prepbuffer(&b);
 
244
            s->avail_out = LUAL_BUFFERSIZE;
 
245
 
 
246
            /* bake some more */
 
247
            if ((r = deflate(s, Z_NO_FLUSH)) != Z_OK)
 
248
            {
 
249
                lua_pushfstring(L, "failed to compress [%d]", r);
 
250
                lua_error(L);
 
251
            }
 
252
 
 
253
            /* push gathered data */
 
254
            luaL_addsize(&b, LUAL_BUFFERSIZE - s->avail_out);
 
255
 
 
256
            /* until we have free space in the output buffer - meaning we are done */
 
257
        } while (s->avail_out == 0);
 
258
 
 
259
        /* send gathered data if any */
 
260
        luaL_pushresult(&b);
 
261
    }
 
262
    return 1;
 
263
}
 
264
 
 
265
/* ====================================================================== */
 
266
 
 
267
static int lzstream_flush(lua_State *L)
 
268
{
 
269
    z_stream *s = lzstream_check(L, 1, LZANY);
 
270
 
 
271
    if (s->opaque == LZINFLATE) {
 
272
        lua_pushliteral(L, "");
 
273
        return 1;
 
274
    }
 
275
 
 
276
    s->next_in = "";
 
277
    s->avail_in = 0;
 
278
 
 
279
    {
 
280
        int r = 0;
 
281
        luaL_Buffer b;
 
282
        luaL_buffinit(L, &b);
 
283
 
 
284
        do {
 
285
            s->next_out = luaL_prepbuffer(&b);
 
286
            s->avail_out = LUAL_BUFFERSIZE;
 
287
 
 
288
            r = deflate(s, Z_FINISH);
 
289
 
 
290
            if (r != Z_OK && r != Z_STREAM_END) {
 
291
                lua_pushfstring(L, "failed to flush [%d]", r);
 
292
                lua_error(L);
 
293
            }
 
294
 
 
295
            /* push gathered data */
 
296
            luaL_addsize(&b, LUAL_BUFFERSIZE - s->avail_out);
 
297
        } while (r != Z_STREAM_END);
 
298
 
 
299
        /* send gathered data if any */
 
300
        luaL_pushresult(&b);
 
301
    }
 
302
    return 1;
 
303
}
 
304
 
 
305
/* ====================================================================== */
 
306
 
 
307
static int lzstream_reset(lua_State *L)
 
308
{
 
309
    z_stream *s = lzstream_check(L, 1, LZANY);
 
310
 
 
311
    if (s->state == LZDEFLATE)
 
312
        lua_pushnumber(L, deflateReset(s));
 
313
    else if (s->opaque == LZINFLATE)
 
314
        lua_pushnumber(L, inflateReset(s));
 
315
    else
 
316
    {
 
317
        lua_pushliteral(L, "invalid zlib stream state");
 
318
        lua_error(L);
 
319
    }
 
320
 
 
321
    return 1;
 
322
}
 
323
 
 
324
 
 
325
/*
 
326
** =========================================================================
 
327
** zlib functions
 
328
** =========================================================================
 
329
*/
 
330
 
 
331
static int lzlib_version(lua_State *L)
 
332
{
 
333
    lua_pushstring(L, zlibVersion());
 
334
    return 1;
 
335
}
 
336
 
 
337
/* ====================================================================== */
 
338
static int lzlib_adler32(lua_State *L)
 
339
{
 
340
    if (lua_gettop(L) == 0)
 
341
    {
 
342
        /* adler32 initial value */
 
343
        lua_pushnumber(L, adler32(0L, Z_NULL, 0));
 
344
    }
 
345
    else
 
346
    {
 
347
        /* update adler32 checksum */
 
348
        int adler = luaL_checkint(L, 1);
 
349
        const char* buf = luaL_checkstring(L, 2);
 
350
        int len = lua_strlen(L, 2);
 
351
 
 
352
        lua_pushnumber(L, adler32(adler, buf, len));
 
353
    }
 
354
    return 1;
 
355
}
 
356
 
 
357
/* ====================================================================== */
 
358
static int lzlib_crc32(lua_State *L)
 
359
{
 
360
    if (lua_gettop(L) == 0)
 
361
    {
 
362
        /* crc32 initial value */
 
363
        lua_pushnumber(L, crc32(0L, Z_NULL, 0));
 
364
    }
 
365
    else
 
366
    {
 
367
        /* update crc32 checksum */
 
368
        int crc = luaL_checkint(L, 1);
 
369
        const char* buf = luaL_checkstring(L, 2);
 
370
        int len = lua_strlen(L, 2);
 
371
 
 
372
        lua_pushnumber(L, crc32(crc, buf, len));
 
373
    }
 
374
    return 1;
 
375
}
 
376
 
 
377
/* ====================================================================== */
 
378
 
 
379
 
 
380
static int lzlib_compress(lua_State *L)
 
381
{
 
382
    const char *next_in = luaL_checkstring(L, 1);
 
383
    int avail_in = lua_strlen(L, 1);
 
384
    int level = luaL_optint(L, 2, Z_DEFAULT_COMPRESSION);
 
385
    int method = luaL_optint(L, 3, Z_DEFLATED);
 
386
    int windowBits = luaL_optint(L, 4, 15);
 
387
    int memLevel = luaL_optint(L, 5, 8);
 
388
    int strategy = luaL_optint(L, 6, Z_DEFAULT_STRATEGY);
 
389
 
 
390
    int ret;
 
391
    luaL_Buffer b;
 
392
    luaL_buffinit(L, &b);
 
393
 
 
394
    z_stream zs;
 
395
 
 
396
    zs.zalloc = Z_NULL;
 
397
    zs.zfree = Z_NULL;
 
398
 
 
399
    zs.next_out = Z_NULL;
 
400
    zs.avail_out = 0;
 
401
    zs.next_in = Z_NULL;
 
402
    zs.avail_in = 0;
 
403
 
 
404
    ret = deflateInit2(&zs, level, method, windowBits, memLevel, strategy);
 
405
 
 
406
    if (ret != Z_OK)
 
407
    {
 
408
        lua_pushnil(L);
 
409
        lua_pushnumber(L, ret);
 
410
        return 2;
 
411
    }
 
412
 
 
413
    zs.next_in = (char*)next_in;
 
414
    zs.avail_in = avail_in;
 
415
 
 
416
    for(;;)
 
417
    {
 
418
        zs.next_out = luaL_prepbuffer(&b);
 
419
        zs.avail_out = LUAL_BUFFERSIZE;
 
420
 
 
421
        /* munch some more */
 
422
        ret = deflate(&zs, Z_FINISH);
 
423
 
 
424
        /* push gathered data */
 
425
        luaL_addsize(&b, LUAL_BUFFERSIZE - zs.avail_out);
 
426
 
 
427
        /* done processing? */
 
428
        if (ret == Z_STREAM_END)
 
429
            break;
 
430
 
 
431
        /* error condition? */
 
432
        if (ret != Z_OK)
 
433
            break;
 
434
    }
 
435
 
 
436
    /* cleanup */
 
437
    deflateEnd(&zs);
 
438
 
 
439
    luaL_pushresult(&b);
 
440
    lua_pushnumber(L, ret);
 
441
    return 2;
 
442
}
 
443
 
 
444
/* ====================================================================== */
 
445
 
 
446
static int lzlib_decompress(lua_State *L)
 
447
{
 
448
    const char *next_in = luaL_checkstring(L, 1);
 
449
    int avail_in = lua_strlen(L, 1);
 
450
    int windowBits = luaL_optint(L, 2, 15);
 
451
 
 
452
    int ret;
 
453
    luaL_Buffer b;
 
454
    luaL_buffinit(L, &b);
 
455
 
 
456
    z_stream zs;
 
457
 
 
458
    zs.zalloc = Z_NULL;
 
459
    zs.zfree = Z_NULL;
 
460
 
 
461
    zs.next_out = Z_NULL;
 
462
    zs.avail_out = 0;
 
463
    zs.next_in = Z_NULL;
 
464
    zs.avail_in = 0;
 
465
 
 
466
    ret = inflateInit2(&zs, windowBits);
 
467
 
 
468
    if (ret != Z_OK)
 
469
    {
 
470
        lua_pushnil(L);
 
471
        lua_pushnumber(L, ret);
 
472
        return 2;
 
473
    }
 
474
 
 
475
    zs.next_in = (char*)next_in;
 
476
    zs.avail_in = avail_in;
 
477
 
 
478
    for(;;)
 
479
    {
 
480
        zs.next_out = luaL_prepbuffer(&b);
 
481
        zs.avail_out = LUAL_BUFFERSIZE;
 
482
 
 
483
        /* bake some more */
 
484
        ret = inflate(&zs, Z_FINISH);
 
485
 
 
486
        /* push gathered data */
 
487
        luaL_addsize(&b, LUAL_BUFFERSIZE - zs.avail_out);
 
488
 
 
489
        /* need dictionary? - no dictionary support here, so just quit */
 
490
        if (ret == Z_NEED_DICT)
 
491
            break;
 
492
 
 
493
        /* done processing? */
 
494
        if (ret == Z_STREAM_END)
 
495
            break;
 
496
 
 
497
        /* error condition? */
 
498
        if (ret != Z_BUF_ERROR)
 
499
            break;
 
500
    }
 
501
 
 
502
    /* cleanup */
 
503
    inflateEnd(&zs);
 
504
 
 
505
    luaL_pushresult(&b);
 
506
    lua_pushnumber(L, ret);
 
507
    return 2;
 
508
}
 
509
 
 
510
 
 
511
/*
 
512
** =========================================================================
 
513
** Register functions
 
514
** =========================================================================
 
515
*/
 
516
 
 
517
 
 
518
LUALIB_API int luaopen_zlib(lua_State *L)
 
519
{
 
520
    const luaL_reg zstreamm[] =
 
521
    {
 
522
        {"reset",           lzstream_reset      },
 
523
 
 
524
        {"compress",        lzstream_compress   },
 
525
        {"decompress",      lzstream_decompress },
 
526
        {"flush",           lzstream_flush      },
 
527
        {"close",           lzstream_close      },
 
528
 
 
529
        {"adler",           lzstream_adler      },
 
530
 
 
531
        {"__tostring",      lzstream_tostring   },
 
532
        {"__gc",            lzstream_gc         },
 
533
        {NULL, NULL}
 
534
    };
 
535
 
 
536
    const luaL_reg zlib[] =
 
537
    {
 
538
        {"version",         lzlib_version       },
 
539
        {"adler32",         lzlib_adler32       },
 
540
        {"crc32",           lzlib_crc32         },
 
541
 
 
542
        {"compressobj",     lzlib_deflate       },
 
543
        {"decompressobj",   lzlib_inflate       },
 
544
 
 
545
        {"compress",        lzlib_compress      },
 
546
        {"decompress",      lzlib_decompress    },
 
547
 
 
548
        {NULL, NULL}
 
549
    };
 
550
 
 
551
    /* ====================================================================== */
 
552
 
 
553
    /* make sure header and library version are consistent */
 
554
    const char* version = zlibVersion();
 
555
    if (strncmp(version, ZLIB_VERSION, 5))
 
556
    {
 
557
        lua_pushfstring(L, "zlib library version does not match - header: %s, library: %s", ZLIB_VERSION, version);
 
558
        lua_error(L);
 
559
    }
 
560
 
 
561
    /* create new metatable for zlib compression structures */
 
562
    luaL_newmetatable(L, ZSTREAMMETA);
 
563
    lua_pushliteral(L, "__index");
 
564
    lua_pushvalue(L, -2);               /* push metatable */
 
565
    lua_rawset(L, -3);                  /* metatable.__index = metatable */
 
566
 
 
567
    /*
 
568
    ** Stack: metatable
 
569
    */
 
570
    luaL_openlib(L, NULL, zstreamm, 0);
 
571
 
 
572
    lua_pop(L, 1);                      /* remove metatable from stack */
 
573
 
 
574
    /*
 
575
    ** Stack:
 
576
    */
 
577
    lua_newtable(L);
 
578
    luaL_openlib(L, NULL, zlib, 0);
 
579
 
 
580
    /*
 
581
    ** Stack: zlib table
 
582
    */
 
583
    return 1;
 
584
}