inflate.c 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  1. /*
  2. * This file is part of the UCB release of Plan 9. It is subject to the license
  3. * terms in the LICENSE file found in the top-level directory of this
  4. * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
  5. * part of the UCB release of Plan 9, including this file, may be copied,
  6. * modified, propagated, or distributed except according to the terms contained
  7. * in the LICENSE file.
  8. */
  9. #include "u.h"
  10. #include "lib.h"
  11. #include "mem.h"
  12. #include "dat.h"
  13. #include "fns.h"
  14. #include "io.h"
  15. #include <flate.h>
  16. typedef struct Biobuf Biobuf;
  17. struct Biobuf
  18. {
  19. uint8_t *bp;
  20. uint8_t *p;
  21. uint8_t *ep;
  22. };
  23. static int header(Biobuf*);
  24. static int trailer(Biobuf*, Biobuf*);
  25. static int getc(void*);
  26. static uint32_t offset(Biobuf*);
  27. static int crcwrite(void *out, void *buf, int n);
  28. static uint32_t get4(Biobuf *b);
  29. static uint32_t Boffset(Biobuf *bp);
  30. /* GZIP flags */
  31. enum {
  32. Ftext= (1<<0),
  33. Fhcrc= (1<<1),
  34. Fextra= (1<<2),
  35. Fname= (1<<3),
  36. Fcomment= (1<<4),
  37. GZCRCPOLY = 0xedb88320UL,
  38. };
  39. static uint32_t *crctab;
  40. static uint32_t crc;
  41. extern void diff(char*); //XXX
  42. int
  43. gunzip(uint8_t *out, int outn, uint8_t *in, int inn)
  44. {
  45. Biobuf bin, bout;
  46. int err;
  47. crc = 0;
  48. crctab = mkcrctab(GZCRCPOLY);
  49. err = inflateinit();
  50. if(err != FlateOk)
  51. print("inflateinit failed: %s\n", flateerr(err));
  52. bin.bp = bin.p = in;
  53. bin.ep = in+inn;
  54. bout.bp = bout.p = out;
  55. bout.ep = out+outn;
  56. err = header(&bin);
  57. if(err != FlateOk)
  58. return err;
  59. err = inflate(&bout, crcwrite, &bin, getc);
  60. if(err != FlateOk)
  61. print("inflate failed: %s\n", flateerr(err));
  62. err = trailer(&bout, &bin);
  63. if(err != FlateOk)
  64. return err;
  65. return Boffset(&bout);
  66. }
  67. static int
  68. header(Biobuf *bin)
  69. {
  70. int i, flag;
  71. if(getc(bin) != 0x1f || getc(bin) != 0x8b){
  72. print("bad magic\n");
  73. return FlateCorrupted;
  74. }
  75. if(getc(bin) != 8){
  76. print("unknown compression type\n");
  77. return FlateCorrupted;
  78. }
  79. flag = getc(bin);
  80. /* mod time */
  81. get4(bin);
  82. /* extra flags */
  83. getc(bin);
  84. /* OS type */
  85. getc(bin);
  86. if(flag & Fextra)
  87. for(i=getc(bin); i>0; i--)
  88. getc(bin);
  89. /* name */
  90. if(flag&Fname)
  91. while(getc(bin) != 0)
  92. ;
  93. /* comment */
  94. if(flag&Fcomment)
  95. while(getc(bin) != 0)
  96. ;
  97. /* crc16 */
  98. if(flag&Fhcrc) {
  99. getc(bin);
  100. getc(bin);
  101. }
  102. return FlateOk;
  103. }
  104. static int
  105. trailer(Biobuf *bout, Biobuf *bin)
  106. {
  107. /* crc32 */
  108. if(crc != get4(bin)){
  109. print("crc mismatch\n");
  110. return FlateCorrupted;
  111. }
  112. /* length */
  113. if(get4(bin) != Boffset(bout)){
  114. print("bad output len\n");
  115. return FlateCorrupted;
  116. }
  117. return FlateOk;
  118. }
  119. static uint32_t
  120. get4(Biobuf *b)
  121. {
  122. uint32_t v;
  123. int i, c;
  124. v = 0;
  125. for(i = 0; i < 4; i++){
  126. c = getc(b);
  127. v |= c << (i * 8);
  128. }
  129. return v;
  130. }
  131. static int
  132. getc(void *in)
  133. {
  134. Biobuf *bp = in;
  135. // if((bp->p - bp->bp) % 10000 == 0)
  136. // print(".");
  137. if(bp->p >= bp->ep)
  138. return -1;
  139. return *bp->p++;
  140. }
  141. static uint32_t
  142. Boffset(Biobuf *bp)
  143. {
  144. return bp->p - bp->bp;
  145. }
  146. static int
  147. crcwrite(void *out, void *buf, int n)
  148. {
  149. Biobuf *bp;
  150. int nn;
  151. crc = blockcrc(crctab, crc, buf, n);
  152. bp = out;
  153. nn = n;
  154. if(nn > bp->ep-bp->p)
  155. nn = bp->ep-bp->p;
  156. if(nn > 0)
  157. memmove(bp->p, buf, nn);
  158. bp->p += n;
  159. return n;
  160. }
  161. #undef malloc
  162. #undef free
  163. void *
  164. malloc(uint32_t n)
  165. {
  166. return ialloc(n, 8);
  167. }
  168. void
  169. free(void *)
  170. {
  171. }