1*10465441SEvalZero /* inflate_util.c -- data and routines common to blocks and codes
2*10465441SEvalZero * Copyright (C) 1995-2002 Mark Adler
3*10465441SEvalZero * For conditions of distribution and use, see copyright notice in zlib.h
4*10465441SEvalZero */
5*10465441SEvalZero
6*10465441SEvalZero #include "zutil.h"
7*10465441SEvalZero #include "infblock.h"
8*10465441SEvalZero #include "inftrees.h"
9*10465441SEvalZero #include "infcodes.h"
10*10465441SEvalZero #include "infutil.h"
11*10465441SEvalZero
12*10465441SEvalZero struct inflate_codes_state {int dummy;}; /* for buggy compilers */
13*10465441SEvalZero
14*10465441SEvalZero /* And'ing with mask[n] masks the lower n bits */
15*10465441SEvalZero uInt inflate_mask[17] = {
16*10465441SEvalZero 0x0000,
17*10465441SEvalZero 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff,
18*10465441SEvalZero 0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff
19*10465441SEvalZero };
20*10465441SEvalZero
21*10465441SEvalZero
22*10465441SEvalZero /* copy as much as possible from the sliding window to the output area */
inflate_flush(s,z,r)23*10465441SEvalZero int inflate_flush(s, z, r)
24*10465441SEvalZero inflate_blocks_statef *s;
25*10465441SEvalZero z_streamp z;
26*10465441SEvalZero int r;
27*10465441SEvalZero {
28*10465441SEvalZero uInt n;
29*10465441SEvalZero Bytef *p;
30*10465441SEvalZero Bytef *q;
31*10465441SEvalZero
32*10465441SEvalZero /* local copies of source and destination pointers */
33*10465441SEvalZero p = z->next_out;
34*10465441SEvalZero q = s->read;
35*10465441SEvalZero
36*10465441SEvalZero /* compute number of bytes to copy as far as end of window */
37*10465441SEvalZero n = (uInt)((q <= s->write ? s->write : s->end) - q);
38*10465441SEvalZero if (n > z->avail_out) n = z->avail_out;
39*10465441SEvalZero if (n && r == Z_BUF_ERROR) r = Z_OK;
40*10465441SEvalZero
41*10465441SEvalZero /* update counters */
42*10465441SEvalZero z->avail_out -= n;
43*10465441SEvalZero z->total_out += n;
44*10465441SEvalZero
45*10465441SEvalZero /* update check information */
46*10465441SEvalZero if (s->checkfn != Z_NULL)
47*10465441SEvalZero z->adler = s->check = (*s->checkfn)(s->check, q, n);
48*10465441SEvalZero
49*10465441SEvalZero /* copy as far as end of window */
50*10465441SEvalZero zmemcpy(p, q, n);
51*10465441SEvalZero p += n;
52*10465441SEvalZero q += n;
53*10465441SEvalZero
54*10465441SEvalZero /* see if more to copy at beginning of window */
55*10465441SEvalZero if (q == s->end)
56*10465441SEvalZero {
57*10465441SEvalZero /* wrap pointers */
58*10465441SEvalZero q = s->window;
59*10465441SEvalZero if (s->write == s->end)
60*10465441SEvalZero s->write = s->window;
61*10465441SEvalZero
62*10465441SEvalZero /* compute bytes to copy */
63*10465441SEvalZero n = (uInt)(s->write - q);
64*10465441SEvalZero if (n > z->avail_out) n = z->avail_out;
65*10465441SEvalZero if (n && r == Z_BUF_ERROR) r = Z_OK;
66*10465441SEvalZero
67*10465441SEvalZero /* update counters */
68*10465441SEvalZero z->avail_out -= n;
69*10465441SEvalZero z->total_out += n;
70*10465441SEvalZero
71*10465441SEvalZero /* update check information */
72*10465441SEvalZero if (s->checkfn != Z_NULL)
73*10465441SEvalZero z->adler = s->check = (*s->checkfn)(s->check, q, n);
74*10465441SEvalZero
75*10465441SEvalZero /* copy */
76*10465441SEvalZero zmemcpy(p, q, n);
77*10465441SEvalZero p += n;
78*10465441SEvalZero q += n;
79*10465441SEvalZero }
80*10465441SEvalZero
81*10465441SEvalZero /* update pointers */
82*10465441SEvalZero z->next_out = p;
83*10465441SEvalZero s->read = q;
84*10465441SEvalZero
85*10465441SEvalZero /* done */
86*10465441SEvalZero return r;
87*10465441SEvalZero }
88