528 static jlong read_input_via_gzip(unpacker* u, 529 void* buf, jlong minlen, jlong maxlen) { 530 assert(minlen <= maxlen); // don't talk nonsense 531 jlong numread = 0; 532 char* bufptr = (char*) buf; 533 char* inbuf = u->gzin->inbuf; 534 size_t inbuflen = sizeof(u->gzin->inbuf); 535 unpacker::read_input_fn_t read_gzin_fn = 536 (unpacker::read_input_fn_t) u->gzin->read_input_fn; 537 z_stream& zs = *(z_stream*) u->gzin->zstream; 538 while (numread < minlen) { 539 int readlen = (1 << 16); // pretty arbitrary 540 if (readlen > (maxlen - numread)) 541 readlen = (int)(maxlen - numread); 542 zs.next_out = (uchar*) bufptr; 543 zs.avail_out = readlen; 544 if (zs.avail_in == 0) { 545 zs.avail_in = (int) read_gzin_fn(u, inbuf, 1, inbuflen); 546 zs.next_in = (uchar*) inbuf; 547 } 548 int error = inflate(&zs, Z_NO_FLUSH); 549 if (error != Z_OK && error != Z_STREAM_END) { 550 u->abort("error inflating input"); 551 break; 552 } 553 int nr = readlen - zs.avail_out; 554 u->gzcrc = crc32(u->gzcrc, (const unsigned char *)bufptr, nr); 555 numread += nr; 556 bufptr += nr; 557 assert(numread <= maxlen); 558 if (error == Z_STREAM_END) { 559 enum { TRAILER_LEN = 8 }; 560 // skip 8-byte trailer 561 if (zs.avail_in >= TRAILER_LEN) { 562 zs.avail_in -= TRAILER_LEN; 563 } else { 564 // Bug: 5023768,we read past the TRAILER_LEN to see if there is 565 // any extraneous data, as we don't support concatenated .gz 566 // files just yet. 567 int extra = (int) read_gzin_fn(u, inbuf, 1, inbuflen); 568 zs.avail_in += extra - TRAILER_LEN; 569 } | 528 static jlong read_input_via_gzip(unpacker* u, 529 void* buf, jlong minlen, jlong maxlen) { 530 assert(minlen <= maxlen); // don't talk nonsense 531 jlong numread = 0; 532 char* bufptr = (char*) buf; 533 char* inbuf = u->gzin->inbuf; 534 size_t inbuflen = sizeof(u->gzin->inbuf); 535 unpacker::read_input_fn_t read_gzin_fn = 536 (unpacker::read_input_fn_t) u->gzin->read_input_fn; 537 z_stream& zs = *(z_stream*) u->gzin->zstream; 538 while (numread < minlen) { 539 int readlen = (1 << 16); // pretty arbitrary 540 if (readlen > (maxlen - numread)) 541 readlen = (int)(maxlen - numread); 542 zs.next_out = (uchar*) bufptr; 543 zs.avail_out = readlen; 544 if (zs.avail_in == 0) { 545 zs.avail_in = (int) read_gzin_fn(u, inbuf, 1, inbuflen); 546 zs.next_in = (uchar*) inbuf; 547 } 548 // When flush is set to Z_FINISH, inflate() cannot return Z_OK. Instead it 549 // will return Z_BUF_ERROR if it has not reached the end of the stream. 550 // So, the only normal return codes are Z_BUF_ERROR and Z_STREAM_END. 551 int error = inflate(&zs, Z_FINISH); 552 if (error != Z_BUF_ERROR && error != Z_STREAM_END) { 553 u->abort("error inflating input"); 554 break; 555 } 556 int nr = readlen - zs.avail_out; 557 u->gzcrc = crc32(u->gzcrc, (const unsigned char *)bufptr, nr); 558 numread += nr; 559 bufptr += nr; 560 assert(numread <= maxlen); 561 if (error == Z_STREAM_END) { 562 enum { TRAILER_LEN = 8 }; 563 // skip 8-byte trailer 564 if (zs.avail_in >= TRAILER_LEN) { 565 zs.avail_in -= TRAILER_LEN; 566 } else { 567 // Bug: 5023768,we read past the TRAILER_LEN to see if there is 568 // any extraneous data, as we don't support concatenated .gz 569 // files just yet. 570 int extra = (int) read_gzin_fn(u, inbuf, 1, inbuflen); 571 zs.avail_in += extra - TRAILER_LEN; 572 } |