compressionlibs/ziplib/src/zlib/infback.cpp
changeset 0 e4d67989cc36
equal deleted inserted replaced
-1:000000000000 0:e4d67989cc36
       
     1 /* Portions Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2  * All rights reserved.
       
     3  */
       
     4 
       
     5 /* infback.cpp -- inflate using a call-back interface
       
     6  * Copyright (C) 1995-2005 Mark Adler
       
     7  * For conditions of distribution and use, see copyright notice in zlib.h
       
     8  */
       
     9 
       
    10 /*
       
    11    This code is largely copied from inflate.c.  Normally either infback.o or
       
    12    inflate.o would be linked into an application--not both.  The interface
       
    13    with inffast.c is retained so that optimized assembler-coded versions of
       
    14    inflate_fast() can be used with either inflate.c or infback.c.
       
    15  */
       
    16 
       
    17 #include "zutil.h"
       
    18 #include "inftrees.h"
       
    19 #include "inflate.h"
       
    20 #include "inffast.h"
       
    21 
       
    22 /* function prototypes */
       
    23 local void fixedtables OF((struct inflate_state FAR *state));
       
    24 
       
    25 /*
       
    26    strm provides memory allocation functions in zalloc and zfree, or
       
    27    Z_NULL to use the library memory allocation functions.
       
    28 
       
    29    windowBits is in the range 8..15, and window is a user-supplied
       
    30    window and output buffer that is 2**windowBits bytes.
       
    31  */
       
    32 
       
    33 #ifdef __SYMBIAN32__
       
    34 EXPORT_C int inflateBackInit__r(z_streamp strm, int windowBits,unsigned char FAR *  window,const char *  version,int stream_size)
       
    35 #else
       
    36 int ZEXPORT inflateBackInit_(strm, windowBits, window, version, stream_size)
       
    37 z_streamp strm;
       
    38 int windowBits;
       
    39 unsigned char FAR *window;
       
    40 const char *version;
       
    41 int stream_size;
       
    42 #endif //__SYMBIAN32__
       
    43 {
       
    44     struct inflate_state FAR *state;
       
    45 
       
    46     if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||
       
    47         stream_size != (int)(sizeof(z_stream)))
       
    48         return Z_VERSION_ERROR;
       
    49     if (strm == Z_NULL || window == Z_NULL ||
       
    50         windowBits < 8 || windowBits > 15)
       
    51         return Z_STREAM_ERROR;
       
    52     strm->msg = Z_NULL;                 /* in case we return an error */
       
    53     if (strm->zalloc == (alloc_func)0) {
       
    54         strm->zalloc = zcalloc;
       
    55         strm->opaque = (voidpf)0;
       
    56     }
       
    57     if (strm->zfree == (free_func)0) strm->zfree = zcfree;
       
    58     state = (struct inflate_state FAR *)ZALLOC(strm, 1,
       
    59                                                sizeof(struct inflate_state));
       
    60     if (state == Z_NULL) return Z_MEM_ERROR;
       
    61     Tracev((stderr, "inflate: allocated\n"));
       
    62     strm->state = (struct internal_state FAR *)state;
       
    63     state->dmax = 32768U;
       
    64     state->wbits = windowBits;
       
    65     state->wsize = 1U << windowBits;
       
    66     state->window = window;
       
    67     state->write = 0;
       
    68     state->whave = 0;
       
    69     return Z_OK;
       
    70 }
       
    71 
       
    72 
       
    73 /*
       
    74    Return state with length and distance decoding tables and index sizes set to
       
    75    fixed code decoding.  Normally this returns fixed tables from inffixed.h.
       
    76    If BUILDFIXED is defined, then instead this routine builds the tables the
       
    77    first time it's called, and returns those tables the first time and
       
    78    thereafter.  This reduces the size of the code by about 2K bytes, in
       
    79    exchange for a little execution time.  However, BUILDFIXED should not be
       
    80    used for threaded applications, since the rewriting of the tables and virgin
       
    81    may not be thread-safe.
       
    82  */
       
    83 
       
    84 #ifdef __SYMBIAN32__
       
    85 local void fixedtables(struct inflate_state FAR * state)
       
    86 #else
       
    87 local void fixedtables(state)
       
    88 struct inflate_state FAR *state;
       
    89 #endif //__SYMBIAN32__
       
    90 {
       
    91 #ifdef BUILDFIXED
       
    92     static int virgin = 1;
       
    93     static code *lenfix, *distfix;
       
    94     static code fixed[544];
       
    95 
       
    96     /* build fixed huffman tables if first call (may not be thread safe) */
       
    97     if (virgin) {
       
    98         unsigned sym, bits;
       
    99         static code *next;
       
   100 
       
   101         /* literal/length table */
       
   102         sym = 0;
       
   103         while (sym < 144) state->lens[sym++] = 8;
       
   104         while (sym < 256) state->lens[sym++] = 9;
       
   105         while (sym < 280) state->lens[sym++] = 7;
       
   106         while (sym < 288) state->lens[sym++] = 8;
       
   107         next = fixed;
       
   108         lenfix = next;
       
   109         bits = 9;
       
   110         inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work);
       
   111 
       
   112         /* distance table */
       
   113         sym = 0;
       
   114         while (sym < 32) state->lens[sym++] = 5;
       
   115         distfix = next;
       
   116         bits = 5;
       
   117         inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work);
       
   118 
       
   119         /* do this just once */
       
   120         virgin = 0;
       
   121     }
       
   122 #else /* !BUILDFIXED */
       
   123 #   include "inffixed.h"
       
   124 #endif /* BUILDFIXED */
       
   125     state->lencode = lenfix;
       
   126     state->lenbits = 9;
       
   127     state->distcode = distfix;
       
   128     state->distbits = 5;
       
   129 }
       
   130 
       
   131 
       
   132 /* Macros for inflateBack(): */
       
   133 
       
   134 /* Load returned state from inflate_fast() */
       
   135 #define LOAD() \
       
   136     do { \
       
   137         put = strm->next_out; \
       
   138         left = strm->avail_out; \
       
   139         next = strm->next_in; \
       
   140         have = strm->avail_in; \
       
   141         hold = state->hold; \
       
   142         bits = state->bits; \
       
   143     } while (0)
       
   144 
       
   145 /* Set state from registers for inflate_fast() */
       
   146 #define RESTORE() \
       
   147     do { \
       
   148         strm->next_out = put; \
       
   149         strm->avail_out = left; \
       
   150         strm->next_in = next; \
       
   151         strm->avail_in = have; \
       
   152         state->hold = hold; \
       
   153         state->bits = bits; \
       
   154     } while (0)
       
   155 
       
   156 /* Clear the input bit accumulator */
       
   157 #define INITBITS() \
       
   158     do { \
       
   159         hold = 0; \
       
   160         bits = 0; \
       
   161     } while (0)
       
   162 
       
   163 /* Assure that some input is available.  If input is requested, but denied,
       
   164    then return a Z_BUF_ERROR from inflateBack(). */
       
   165 #define PULL() \
       
   166     do { \
       
   167         if (have == 0) { \
       
   168             have = in(in_desc, &next); \
       
   169             if (have == 0) { \
       
   170                 next = Z_NULL; \
       
   171                 ret = Z_BUF_ERROR; \
       
   172                 goto inf_leave; \
       
   173             } \
       
   174         } \
       
   175     } while (0)
       
   176 
       
   177 /* Get a byte of input into the bit accumulator, or return from inflateBack()
       
   178    with an error if there is no input available. */
       
   179 #define PULLBYTE() \
       
   180     do { \
       
   181         PULL(); \
       
   182         have--; \
       
   183         hold += (unsigned long)(*next++) << bits; \
       
   184         bits += 8; \
       
   185     } while (0)
       
   186 
       
   187 /* Assure that there are at least n bits in the bit accumulator.  If there is
       
   188    not enough available input to do that, then return from inflateBack() with
       
   189    an error. */
       
   190 #define NEEDBITS(n) \
       
   191     do { \
       
   192         while (bits < (unsigned)(n)) \
       
   193             PULLBYTE(); \
       
   194     } while (0)
       
   195 
       
   196 /* Return the low n bits of the bit accumulator (n < 16) */
       
   197 #define BITS(n) \
       
   198     ((unsigned)hold & ((1U << (n)) - 1))
       
   199 
       
   200 /* Remove n bits from the bit accumulator */
       
   201 #define DROPBITS(n) \
       
   202     do { \
       
   203         hold >>= (n); \
       
   204         bits -= (unsigned)(n); \
       
   205     } while (0)
       
   206 
       
   207 /* Remove zero to seven bits as needed to go to a byte boundary */
       
   208 #define BYTEBITS() \
       
   209     do { \
       
   210         hold >>= bits & 7; \
       
   211         bits -= bits & 7; \
       
   212     } while (0)
       
   213 
       
   214 /* Assure that some output space is available, by writing out the window
       
   215    if it's full.  If the write fails, return from inflateBack() with a
       
   216    Z_BUF_ERROR. */
       
   217 #define ROOM() \
       
   218     do { \
       
   219         if (left == 0) { \
       
   220             put = state->window; \
       
   221             left = state->wsize; \
       
   222             state->whave = left; \
       
   223             if (out(out_desc, put, left)) { \
       
   224                 ret = Z_BUF_ERROR; \
       
   225                 goto inf_leave; \
       
   226             } \
       
   227         } \
       
   228     } while (0)
       
   229 
       
   230 /*
       
   231    strm provides the memory allocation functions and window buffer on input,
       
   232    and provides information on the unused input on return.  For Z_DATA_ERROR
       
   233    returns, strm will also provide an error message.
       
   234 
       
   235    in() and out() are the call-back input and output functions.  When
       
   236    inflateBack() needs more input, it calls in().  When inflateBack() has
       
   237    filled the window with output, or when it completes with data in the
       
   238    window, it calls out() to write out the data.  The application must not
       
   239    change the provided input until in() is called again or inflateBack()
       
   240    returns.  The application must not change the window/output buffer until
       
   241    inflateBack() returns.
       
   242 
       
   243    in() and out() are called with a descriptor parameter provided in the
       
   244    inflateBack() call.  This parameter can be a structure that provides the
       
   245    information required to do the read or write, as well as accumulated
       
   246    information on the input and output such as totals and check values.
       
   247 
       
   248    in() should return zero on failure.  out() should return non-zero on
       
   249    failure.  If either in() or out() fails, than inflateBack() returns a
       
   250    Z_BUF_ERROR.  strm->next_in can be checked for Z_NULL to see whether it
       
   251    was in() or out() that caused in the error.  Otherwise,  inflateBack()
       
   252    returns Z_STREAM_END on success, Z_DATA_ERROR for an deflate format
       
   253    error, or Z_MEM_ERROR if it could not allocate memory for the state.
       
   254    inflateBack() can also return Z_STREAM_ERROR if the input parameters
       
   255    are not correct, i.e. strm is Z_NULL or the state was not initialized.
       
   256  */
       
   257 
       
   258 #ifdef __SYMBIAN32__
       
   259 EXPORT_C int inflateBack_r(z_streamp strm,in_func  in, void FAR * in_desc,out_func  out,void FAR * out_desc)
       
   260 #else
       
   261 int ZEXPORT inflateBack(strm, in, in_desc, out, out_desc)
       
   262 z_streamp strm;
       
   263 in_func in;
       
   264 void FAR *in_desc;
       
   265 out_func out;
       
   266 void FAR *out_desc;
       
   267 #endif //__SYMBIAN32__
       
   268 {
       
   269     struct inflate_state FAR *state;
       
   270     unsigned char FAR *next;    /* next input */
       
   271     unsigned char FAR *put;     /* next output */
       
   272     unsigned have, left;        /* available input and output */
       
   273     unsigned long hold;         /* bit buffer */
       
   274     unsigned bits;              /* bits in bit buffer */
       
   275     unsigned copy;              /* number of stored or match bytes to copy */
       
   276     unsigned char FAR *from;    /* where to copy match bytes from */
       
   277     
       
   278 /*  Need to replace "this" variable with "current" as "this" is a reserved 
       
   279  *  keyword in C++ which is prefectly fine for a c code. As this file
       
   280  *  has been changed to C++ "this" needs to be changed.
       
   281  */ 
       
   282 #   define this current      
       
   283     code this;                  /* current decoding table entry */
       
   284     code last;                  /* parent table entry */
       
   285     unsigned len;               /* length to copy for repeats, bits to drop */
       
   286     int ret;                    /* return code */
       
   287     static const unsigned short order[19] = /* permutation of code lengths */
       
   288         {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
       
   289 
       
   290     /* Check that the strm exists and that the state was initialized */
       
   291     if (strm == Z_NULL || strm->state == Z_NULL)
       
   292         return Z_STREAM_ERROR;
       
   293     state = (struct inflate_state FAR *)strm->state;
       
   294 
       
   295     /* Reset the state */
       
   296     strm->msg = Z_NULL;
       
   297     state->mode = TYPE;
       
   298     state->last = 0;
       
   299     state->whave = 0;
       
   300     next = strm->next_in;
       
   301     have = next != Z_NULL ? strm->avail_in : 0;
       
   302     hold = 0;
       
   303     bits = 0;
       
   304     put = state->window;
       
   305     left = state->wsize;
       
   306 
       
   307     /* Inflate until end of block marked as last */
       
   308     for (;;)
       
   309         switch (state->mode) {
       
   310         case TYPE:
       
   311             /* determine and dispatch block type */
       
   312             if (state->last) {
       
   313                 BYTEBITS();
       
   314                 state->mode = DONE;
       
   315                 break;
       
   316             }
       
   317             NEEDBITS(3);
       
   318             state->last = BITS(1);
       
   319             DROPBITS(1);
       
   320             switch (BITS(2)) {
       
   321             case 0:                             /* stored block */
       
   322                 Tracev((stderr, "inflate:     stored block%s\n",
       
   323                         state->last ? " (last)" : ""));
       
   324                 state->mode = STORED;
       
   325                 break;
       
   326             case 1:                             /* fixed block */
       
   327                 fixedtables(state);
       
   328                 Tracev((stderr, "inflate:     fixed codes block%s\n",
       
   329                         state->last ? " (last)" : ""));
       
   330                 state->mode = LEN;              /* decode codes */
       
   331                 break;
       
   332             case 2:                             /* dynamic block */
       
   333                 Tracev((stderr, "inflate:     dynamic codes block%s\n",
       
   334                         state->last ? " (last)" : ""));
       
   335                 state->mode = TABLE;
       
   336                 break;
       
   337             case 3:
       
   338                 strm->msg = (char *)"invalid block type";
       
   339                 state->mode = BAD;
       
   340             }
       
   341             DROPBITS(2);
       
   342             break;
       
   343 
       
   344         case STORED:
       
   345             /* get and verify stored block length */
       
   346             BYTEBITS();                         /* go to byte boundary */
       
   347             NEEDBITS(32);
       
   348             if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) {
       
   349                 strm->msg = (char *)"invalid stored block lengths";
       
   350                 state->mode = BAD;
       
   351                 break;
       
   352             }
       
   353             state->length = (unsigned)hold & 0xffff;
       
   354             Tracev((stderr, "inflate:       stored length %u\n",
       
   355                     state->length));
       
   356             INITBITS();
       
   357 
       
   358             /* copy stored block from input to output */
       
   359             while (state->length != 0) {
       
   360                 copy = state->length;
       
   361                 PULL();
       
   362                 ROOM();
       
   363                 if (copy > have) copy = have;
       
   364                 if (copy > left) copy = left;
       
   365                 zmemcpy(put, next, copy);
       
   366                 have -= copy;
       
   367                 next += copy;
       
   368                 left -= copy;
       
   369                 put += copy;
       
   370                 state->length -= copy;
       
   371             }
       
   372             Tracev((stderr, "inflate:       stored end\n"));
       
   373             state->mode = TYPE;
       
   374             break;
       
   375 
       
   376         case TABLE:
       
   377             /* get dynamic table entries descriptor */
       
   378             NEEDBITS(14);
       
   379             state->nlen = BITS(5) + 257;
       
   380             DROPBITS(5);
       
   381             state->ndist = BITS(5) + 1;
       
   382             DROPBITS(5);
       
   383             state->ncode = BITS(4) + 4;
       
   384             DROPBITS(4);
       
   385 #ifndef PKZIP_BUG_WORKAROUND
       
   386             if (state->nlen > 286 || state->ndist > 30) {
       
   387                 strm->msg = (char *)"too many length or distance symbols";
       
   388                 state->mode = BAD;
       
   389                 break;
       
   390             }
       
   391 #endif
       
   392             Tracev((stderr, "inflate:       table sizes ok\n"));
       
   393 
       
   394             /* get code length code lengths (not a typo) */
       
   395             state->have = 0;
       
   396             while (state->have < state->ncode) {
       
   397                 NEEDBITS(3);
       
   398                 state->lens[order[state->have++]] = (unsigned short)BITS(3);
       
   399                 DROPBITS(3);
       
   400             }
       
   401             while (state->have < 19)
       
   402                 state->lens[order[state->have++]] = 0;
       
   403             state->next = state->codes;
       
   404             state->lencode = (code const FAR *)(state->next);
       
   405             state->lenbits = 7;
       
   406             ret = inflate_table(CODES, state->lens, 19, &(state->next),
       
   407                                 &(state->lenbits), state->work);
       
   408             if (ret) {
       
   409                 strm->msg = (char *)"invalid code lengths set";
       
   410                 state->mode = BAD;
       
   411                 break;
       
   412             }
       
   413             Tracev((stderr, "inflate:       code lengths ok\n"));
       
   414 
       
   415             /* get length and distance code code lengths */
       
   416             state->have = 0;
       
   417             while (state->have < state->nlen + state->ndist) {
       
   418                 for (;;) {
       
   419                     this = state->lencode[BITS(state->lenbits)];
       
   420                     if ((unsigned)(this.bits) <= bits) break;
       
   421                     PULLBYTE();
       
   422                 }
       
   423                 if (this.val < 16) {
       
   424                     NEEDBITS(this.bits);
       
   425                     DROPBITS(this.bits);
       
   426                     state->lens[state->have++] = this.val;
       
   427                 }
       
   428                 else {
       
   429                     if (this.val == 16) {
       
   430                         NEEDBITS(this.bits + 2);
       
   431                         DROPBITS(this.bits);
       
   432                         if (state->have == 0) {
       
   433                             strm->msg = (char *)"invalid bit length repeat";
       
   434                             state->mode = BAD;
       
   435                             break;
       
   436                         }
       
   437                         len = (unsigned)(state->lens[state->have - 1]);
       
   438                         copy = 3 + BITS(2);
       
   439                         DROPBITS(2);
       
   440                     }
       
   441                     else if (this.val == 17) {
       
   442                         NEEDBITS(this.bits + 3);
       
   443                         DROPBITS(this.bits);
       
   444                         len = 0;
       
   445                         copy = 3 + BITS(3);
       
   446                         DROPBITS(3);
       
   447                     }
       
   448                     else {
       
   449                         NEEDBITS(this.bits + 7);
       
   450                         DROPBITS(this.bits);
       
   451                         len = 0;
       
   452                         copy = 11 + BITS(7);
       
   453                         DROPBITS(7);
       
   454                     }
       
   455                     if (state->have + copy > state->nlen + state->ndist) {
       
   456                         strm->msg = (char *)"invalid bit length repeat";
       
   457                         state->mode = BAD;
       
   458                         break;
       
   459                     }
       
   460                     while (copy--)
       
   461                         state->lens[state->have++] = (unsigned short)len;
       
   462                 }
       
   463             }
       
   464 
       
   465             /* handle error breaks in while */
       
   466             if (state->mode == BAD) break;
       
   467 
       
   468             /* build code tables */
       
   469             state->next = state->codes;
       
   470             state->lencode = (code const FAR *)(state->next);
       
   471             state->lenbits = 9;
       
   472             ret = inflate_table(LENS, state->lens, state->nlen, &(state->next),
       
   473                                 &(state->lenbits), state->work);
       
   474             if (ret) {
       
   475                 strm->msg = (char *)"invalid literal/lengths set";
       
   476                 state->mode = BAD;
       
   477                 break;
       
   478             }
       
   479             state->distcode = (code const FAR *)(state->next);
       
   480             state->distbits = 6;
       
   481             ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist,
       
   482                             &(state->next), &(state->distbits), state->work);
       
   483             if (ret) {
       
   484                 strm->msg = (char *)"invalid distances set";
       
   485                 state->mode = BAD;
       
   486                 break;
       
   487             }
       
   488             Tracev((stderr, "inflate:       codes ok\n"));
       
   489             state->mode = LEN;
       
   490 
       
   491         case LEN:
       
   492             /* use inflate_fast() if we have enough input and output */
       
   493             if (have >= 6 && left >= 258) {
       
   494                 RESTORE();
       
   495                 if (state->whave < state->wsize)
       
   496                     state->whave = state->wsize - left;
       
   497                 inflate_fast(strm, state->wsize);
       
   498                 LOAD();
       
   499                 break;
       
   500             }
       
   501 
       
   502             /* get a literal, length, or end-of-block code */
       
   503             for (;;) {
       
   504                 this = state->lencode[BITS(state->lenbits)];
       
   505                 if ((unsigned)(this.bits) <= bits) break;
       
   506                 PULLBYTE();
       
   507             }
       
   508             if (this.op && (this.op & 0xf0) == 0) {
       
   509                 last = this;
       
   510                 for (;;) {
       
   511                     this = state->lencode[last.val +
       
   512                             (BITS(last.bits + last.op) >> last.bits)];
       
   513                     if ((unsigned)(last.bits + this.bits) <= bits) break;
       
   514                     PULLBYTE();
       
   515                 }
       
   516                 DROPBITS(last.bits);
       
   517             }
       
   518             DROPBITS(this.bits);
       
   519             state->length = (unsigned)this.val;
       
   520 
       
   521             /* process literal */
       
   522             if (this.op == 0) {
       
   523                 Tracevv((stderr, this.val >= 0x20 && this.val < 0x7f ?
       
   524                         "inflate:         literal '%c'\n" :
       
   525                         "inflate:         literal 0x%02x\n", this.val));
       
   526                 ROOM();
       
   527                 *put++ = (unsigned char)(state->length);
       
   528                 left--;
       
   529                 state->mode = LEN;
       
   530                 break;
       
   531             }
       
   532 
       
   533             /* process end of block */
       
   534             if (this.op & 32) {
       
   535                 Tracevv((stderr, "inflate:         end of block\n"));
       
   536                 state->mode = TYPE;
       
   537                 break;
       
   538             }
       
   539 
       
   540             /* invalid code */
       
   541             if (this.op & 64) {
       
   542                 strm->msg = (char *)"invalid literal/length code";
       
   543                 state->mode = BAD;
       
   544                 break;
       
   545             }
       
   546 
       
   547             /* length code -- get extra bits, if any */
       
   548             state->extra = (unsigned)(this.op) & 15;
       
   549             if (state->extra != 0) {
       
   550                 NEEDBITS(state->extra);
       
   551                 state->length += BITS(state->extra);
       
   552                 DROPBITS(state->extra);
       
   553             }
       
   554             Tracevv((stderr, "inflate:         length %u\n", state->length));
       
   555 
       
   556             /* get distance code */
       
   557             for (;;) {
       
   558                 this = state->distcode[BITS(state->distbits)];
       
   559                 if ((unsigned)(this.bits) <= bits) break;
       
   560                 PULLBYTE();
       
   561             }
       
   562             if ((this.op & 0xf0) == 0) {
       
   563                 last = this;
       
   564                 for (;;) {
       
   565                     this = state->distcode[last.val +
       
   566                             (BITS(last.bits + last.op) >> last.bits)];
       
   567                     if ((unsigned)(last.bits + this.bits) <= bits) break;
       
   568                     PULLBYTE();
       
   569                 }
       
   570                 DROPBITS(last.bits);
       
   571             }
       
   572             DROPBITS(this.bits);
       
   573             if (this.op & 64) {
       
   574                 strm->msg = (char *)"invalid distance code";
       
   575                 state->mode = BAD;
       
   576                 break;
       
   577             }
       
   578             state->offset = (unsigned)this.val;
       
   579 
       
   580             /* get distance extra bits, if any */
       
   581             state->extra = (unsigned)(this.op) & 15;
       
   582             if (state->extra != 0) {
       
   583                 NEEDBITS(state->extra);
       
   584                 state->offset += BITS(state->extra);
       
   585                 DROPBITS(state->extra);
       
   586             }
       
   587             if (state->offset > state->wsize - (state->whave < state->wsize ?
       
   588                                                 left : 0)) {
       
   589                 strm->msg = (char *)"invalid distance too far back";
       
   590                 state->mode = BAD;
       
   591                 break;
       
   592             }
       
   593             Tracevv((stderr, "inflate:         distance %u\n", state->offset));
       
   594 
       
   595             /* copy match from window to output */
       
   596             do {
       
   597                 ROOM();
       
   598                 copy = state->wsize - state->offset;
       
   599                 if (copy < left) {
       
   600                     from = put + copy;
       
   601                     copy = left - copy;
       
   602                 }
       
   603                 else {
       
   604                     from = put - state->offset;
       
   605                     copy = left;
       
   606                 }
       
   607                 if (copy > state->length) copy = state->length;
       
   608                 state->length -= copy;
       
   609                 left -= copy;
       
   610                 do {
       
   611                     *put++ = *from++;
       
   612                 } while (--copy);
       
   613             } while (state->length != 0);
       
   614             break;
       
   615 
       
   616         case DONE:
       
   617             /* inflate stream terminated properly -- write leftover output */
       
   618             ret = Z_STREAM_END;
       
   619             if (left < state->wsize) {
       
   620                 if (out(out_desc, state->window, state->wsize - left))
       
   621                     ret = Z_BUF_ERROR;
       
   622             }
       
   623             goto inf_leave;
       
   624 
       
   625         case BAD:
       
   626             ret = Z_DATA_ERROR;
       
   627             goto inf_leave;
       
   628 
       
   629         default:                /* can't happen, but makes compilers happy */
       
   630             ret = Z_STREAM_ERROR;
       
   631             goto inf_leave;
       
   632         }
       
   633 
       
   634     /* Return unused input */
       
   635   inf_leave:
       
   636     strm->next_in = next;
       
   637     strm->avail_in = have;
       
   638     return ret;
       
   639 }
       
   640 
       
   641 
       
   642 #ifdef __SYMBIAN32__
       
   643 EXPORT_C int  inflateBackEnd_r(z_streamp strm)
       
   644 #else
       
   645 int ZEXPORT inflateBackEnd(strm)
       
   646 z_streamp strm;
       
   647  #endif //__SYMBIAN32__
       
   648 {
       
   649     if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0)
       
   650         return Z_STREAM_ERROR;
       
   651     ZFREE(strm, strm->state);
       
   652     strm->state = Z_NULL;
       
   653     Tracev((stderr, "inflate: end\n"));
       
   654     return Z_OK;
       
   655 }