inflate_sync.c 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. /* inflate.c -- zlib interface to inflate modules
  2. * Copyright (C) 1995-1998 Mark Adler
  3. * For conditions of distribution and use, see copyright notice in zlib.h
  4. */
  5. #include <linux/zutil.h>
  6. #include "infblock.h"
  7. #include "infutil.h"
  8. int zlib_inflateSync(
  9. z_streamp z
  10. )
  11. {
  12. uInt n; /* number of bytes to look at */
  13. Byte *p; /* pointer to bytes */
  14. uInt m; /* number of marker bytes found in a row */
  15. uLong r, w; /* temporaries to save total_in and total_out */
  16. /* set up */
  17. if (z == NULL || z->state == NULL)
  18. return Z_STREAM_ERROR;
  19. if (z->state->mode != I_BAD)
  20. {
  21. z->state->mode = I_BAD;
  22. z->state->sub.marker = 0;
  23. }
  24. if ((n = z->avail_in) == 0)
  25. return Z_BUF_ERROR;
  26. p = z->next_in;
  27. m = z->state->sub.marker;
  28. /* search */
  29. while (n && m < 4)
  30. {
  31. static const Byte mark[4] = {0, 0, 0xff, 0xff};
  32. if (*p == mark[m])
  33. m++;
  34. else if (*p)
  35. m = 0;
  36. else
  37. m = 4 - m;
  38. p++, n--;
  39. }
  40. /* restore */
  41. z->total_in += p - z->next_in;
  42. z->next_in = p;
  43. z->avail_in = n;
  44. z->state->sub.marker = m;
  45. /* return no joy or set up to restart on a new block */
  46. if (m != 4)
  47. return Z_DATA_ERROR;
  48. r = z->total_in; w = z->total_out;
  49. zlib_inflateReset(z);
  50. z->total_in = r; z->total_out = w;
  51. z->state->mode = BLOCKS;
  52. return Z_OK;
  53. }
  54. /* Returns true if inflate is currently at the end of a block generated
  55. * by Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP
  56. * implementation to provide an additional safety check. PPP uses Z_SYNC_FLUSH
  57. * but removes the length bytes of the resulting empty stored block. When
  58. * decompressing, PPP checks that at the end of input packet, inflate is
  59. * waiting for these length bytes.
  60. */
  61. int zlib_inflateSyncPoint(
  62. z_streamp z
  63. )
  64. {
  65. if (z == NULL || z->state == NULL || z->state->blocks == NULL)
  66. return Z_STREAM_ERROR;
  67. return zlib_inflate_blocks_sync_point(z->state->blocks);
  68. }
  69. /*
  70. * This subroutine adds the data at next_in/avail_in to the output history
  71. * without performing any output. The output buffer must be "caught up";
  72. * i.e. no pending output (hence s->read equals s->write), and the state must
  73. * be BLOCKS (i.e. we should be willing to see the start of a series of
  74. * BLOCKS). On exit, the output will also be caught up, and the checksum
  75. * will have been updated if need be.
  76. */
  77. static int zlib_inflate_addhistory(inflate_blocks_statef *s,
  78. z_stream *z)
  79. {
  80. uLong b; /* bit buffer */ /* NOT USED HERE */
  81. uInt k; /* bits in bit buffer */ /* NOT USED HERE */
  82. uInt t; /* temporary storage */
  83. Byte *p; /* input data pointer */
  84. uInt n; /* bytes available there */
  85. Byte *q; /* output window write pointer */
  86. uInt m; /* bytes to end of window or read pointer */
  87. if (s->read != s->write)
  88. return Z_STREAM_ERROR;
  89. if (s->mode != TYPE)
  90. return Z_DATA_ERROR;
  91. /* we're ready to rock */
  92. LOAD
  93. /* while there is input ready, copy to output buffer, moving
  94. * pointers as needed.
  95. */
  96. while (n) {
  97. t = n; /* how many to do */
  98. /* is there room until end of buffer? */
  99. if (t > m) t = m;
  100. /* update check information */
  101. if (s->checkfn != NULL)
  102. s->check = (*s->checkfn)(s->check, q, t);
  103. memcpy(q, p, t);
  104. q += t;
  105. p += t;
  106. n -= t;
  107. z->total_out += t;
  108. s->read = q; /* drag read pointer forward */
  109. /* WWRAP */ /* expand WWRAP macro by hand to handle s->read */
  110. if (q == s->end) {
  111. s->read = q = s->window;
  112. m = WAVAIL;
  113. }
  114. }
  115. UPDATE
  116. return Z_OK;
  117. }
  118. /*
  119. * This subroutine adds the data at next_in/avail_in to the output history
  120. * without performing any output. The output buffer must be "caught up";
  121. * i.e. no pending output (hence s->read equals s->write), and the state must
  122. * be BLOCKS (i.e. we should be willing to see the start of a series of
  123. * BLOCKS). On exit, the output will also be caught up, and the checksum
  124. * will have been updated if need be.
  125. */
  126. int zlib_inflateIncomp(
  127. z_stream *z
  128. )
  129. {
  130. if (z->state->mode != BLOCKS)
  131. return Z_DATA_ERROR;
  132. return zlib_inflate_addhistory(z->state->blocks, z);
  133. }