📄 compress.c
字号:
} /* If there's any data left in the buffer, write it out */ if(zs.avail_out != RDSZ){ wramt = RDSZ - zs.avail_out; if (write_data (out_fd, out_buff, wramt, existing) != (int)wramt) { perror("write"); exit(1); } } /* update fastjar's entry information */ ze->usize = (ub4)zs.total_in; ze->csize = (ub4)zs.total_out; /* Reset the deflation for the next time around */ if(deflateReset(&zs) != Z_OK){ fprintf(stderr, "Error resetting deflation\n"); exit(1); } return 0;}void end_compression(){ int rtval; /* Oddly enough, zlib always returns Z_DATA_ERROR if you specify no zlib header. Go fig. */ if((rtval = deflateEnd(&zs)) != Z_OK && rtval != Z_DATA_ERROR){ fprintf(stderr, "Error calling deflateEnd\n"); fprintf(stderr, "error: (%d) %s\n", rtval, zs.msg); exit(1); }}void init_inflation(){ memset(&zs, 0, sizeof(z_stream)); zs.zalloc = Z_NULL; zs.zfree = Z_NULL; zs.opaque = Z_NULL; if(inflateInit2(&zs, -15) != Z_OK){ fprintf(stderr, "Error initializing deflation!\n"); exit(1); }}int inflate_file(pb_file *pbf, int out_fd, struct zipentry *ze){ Bytef in_buff[RDSZ]; Bytef out_buff[RDSZ]; unsigned int rdamt; int rtval; ub4 crc = 0; zs.avail_in = 0; crc = crc32(crc, NULL, 0); /* initialize crc */ /* loop until we've consumed all the compressed data */ for(;;){ if(zs.avail_in == 0){ if((rdamt = pb_read(pbf, in_buff, RDSZ)) == 0) break; else if((int)rdamt < 0){ perror("read"); exit(1); }#ifdef DEBUG printf("%d bytes read\n", rdamt);#endif zs.next_in = in_buff; zs.avail_in = rdamt; } zs.next_out = out_buff; zs.avail_out = RDSZ; if((rtval = inflate(&zs, 0)) != Z_OK){ if(rtval == Z_STREAM_END){#ifdef DEBUG printf("end of stream\n");#endif if(zs.avail_out != RDSZ){ crc = crc32(crc, out_buff, (RDSZ - zs.avail_out)); if(out_fd >= 0) if(write(out_fd, out_buff, (RDSZ - zs.avail_out)) != (int)(RDSZ - zs.avail_out)){ perror("write"); exit(1); } } break; } else { fprintf(stderr, "Error inflating file! (%d)\n", rtval); exit(1); } } else { if(zs.avail_out != RDSZ){ crc = crc32(crc, out_buff, (RDSZ - zs.avail_out)); if(out_fd >= 0) if(write(out_fd, out_buff, (RDSZ - zs.avail_out)) != (int)(RDSZ - zs.avail_out)){ perror("write"); exit(1); } zs.next_out = out_buff; zs.avail_out = RDSZ; } } }#ifdef DEBUG printf("done inflating\n");#endif#ifdef DEBUG printf("%d bytes left over\n", zs.avail_in);#endif#ifdef DEBUG printf("CRC is %x\n", crc);#endif ze->crc = crc; pb_push(pbf, zs.next_in, zs.avail_in); ze->usize = zs.total_out; inflateReset(&zs); return 0;}/*Function name: report_str_errorargs: val Error code returned from zlib.purpose: Put out an error message corresponding to error code returned from zlib.Be suitably cryptic seeing I don't really know exactly what these errors mean.*/static void report_str_error(int val) { switch(val) { case Z_STREAM_END: break; case Z_NEED_DICT: fprintf(stderr, "Need a dictionary?\n"); exit(1); case Z_DATA_ERROR: fprintf(stderr, "Z_DATA_ERROR\n"); exit(1); case Z_STREAM_ERROR: fprintf(stderr, "Z_STREAM_ERROR\n"); exit(1); case Z_MEM_ERROR: fprintf(stderr, "Z_MEM_ERROR\n"); exit(1); case Z_BUF_ERROR: fprintf(stderr, "Z_BUF_ERROR\n"); exit(1); case Z_OK: break; default: fprintf(stderr, "Unknown behavior from inflate\n"); exit(1); }}/*Function name: ez_inflate_strargs: pbf Pointer to pushback handle for file. csize Compressed size of embedded file. usize Uncompressed size of embedded file.purpose: Read in and decompress the contents of an embedded file and store it in abyte array.returns: Byte array of uncompressed embedded file.*/static Bytef *ez_inflate_str(pb_file *pbf, ub4 csize, ub4 usize) { Bytef *out_buff; Bytef *in_buff; unsigned int rdamt; if((zs.next_in = in_buff = (Bytef *) malloc(csize))) { if((zs.next_out = out_buff = (Bytef *) malloc(usize + 1))) { if((rdamt = pb_read(pbf, zs.next_in, csize)) == csize) { zs.avail_in = csize; zs.avail_out = usize; report_str_error(inflate(&zs, 0)); free(in_buff); inflateReset(&zs); out_buff[usize] = '\0'; } else { fprintf(stderr, "Read failed on input file.\n"); fprintf(stderr, "Tried to read %u but read %u instead.\n", csize, rdamt); free(in_buff); free(out_buff); exit(1); } } else { fprintf(stderr, "Malloc of out_buff failed.\n"); fprintf(stderr, "Error: %s\n", strerror(errno)); free(in_buff); exit(1); } } else { fprintf(stderr, "Malloc of in_buff failed.\n"); fprintf(stderr, "Error: %s\n", strerror(errno)); exit(1); } return out_buff;}/*Function name: hrd_inflate_strargs: pbf Pointer to pushback handle for file. csize Pointer to compressed size of embedded file. usize Pointer to uncompressed size of embedded file.purpose: Read and decompress an embedded file into a string. Set csize and usizeaccordingly. This function does the reading for us in the case there is not sizeinformation in the header for the embedded file.returns: Byte array of the contents of the embedded file.*/static Bytef *hrd_inflate_str(pb_file *pbf, ub4 *csize, ub4 *usize) { Bytef *out_buff; Bytef *tmp; Bytef in_buff[RDSZ]; unsigned int rdamt; int i; int zret; i = 1; out_buff = NULL; zret = Z_OK; while(zret != Z_STREAM_END && (rdamt = pb_read(pbf, in_buff, RDSZ))) { zs.avail_in = rdamt; zs.avail_out = 0; zs.next_in = in_buff; do { if((tmp = (Bytef *) realloc(out_buff, (RDSZ * i) + 1))) { out_buff = tmp; zs.next_out = &(out_buff[(RDSZ * (i - 1)) - zs.avail_out]); zs.avail_out += RDSZ; i++; } else { fprintf(stderr, "Realloc of out_buff failed.\n"); fprintf(stderr, "Error: %s\n", strerror(errno)); exit(1); } } while((zret = inflate(&zs, 0)) == Z_OK); report_str_error(zret); } pb_push(pbf, zs.next_in, zs.avail_in); out_buff[(RDSZ * (i - 1)) - zs.avail_out] = '\0'; *usize = zs.total_out; *csize = zs.total_in; inflateReset(&zs); return out_buff;}/*Function name: inflate_stringargs: pbf Pointer to pushback handle for file. csize Pointer to compressed size of embedded file. May be 0 if not set. usize Pointer to uncompressed size of embedded file. May be 0 if not set.purpose: Decide the easiest (in computer terms) methos of decompressing this embeddedfile to a string.returns: Pointer to a string containing the decompressed contents of the embedded file.If csize and usize are not set set them to correct numbers.*/Bytef *inflate_string(pb_file *pbf, ub4 *csize, ub4 *usize) {Bytef *ret_buf; if(*csize && *usize) ret_buf = ez_inflate_str(pbf, *csize, *usize); else ret_buf = hrd_inflate_str(pbf, csize, usize); return ret_buf;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -