aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGlenn L McGrath <bug1@ihug.co.nz>2002-11-17 21:33:30 +0000
committerGlenn L McGrath <bug1@ihug.co.nz>2002-11-17 21:33:30 +0000
commitfd73b8c2ce6ae9517e37127cba2a48a6ee803287 (patch)
treeaf2e3ad9ace98903d663957e6ed29f4840188830
parent36233bdd71cd6fd733fc2010d70db28cd5eb57e0 (diff)
downloadbusybox-w32-fd73b8c2ce6ae9517e37127cba2a48a6ee803287.tar.gz
busybox-w32-fd73b8c2ce6ae9517e37127cba2a48a6ee803287.tar.bz2
busybox-w32-fd73b8c2ce6ae9517e37127cba2a48a6ee803287.zip
Patch from Laurence Anderson to provide a read_gz function, doesnt require fork(), pipe(), consistent with read_bz2 and more flexible.
-rw-r--r--archival/libunarchive/decompress_unzip.c109
-rw-r--r--archival/libunarchive/unzip.c109
2 files changed, 162 insertions, 56 deletions
diff --git a/archival/libunarchive/decompress_unzip.c b/archival/libunarchive/decompress_unzip.c
index 20bf88f55..046f4dd72 100644
--- a/archival/libunarchive/decompress_unzip.c
+++ b/archival/libunarchive/decompress_unzip.c
@@ -81,7 +81,6 @@ typedef struct huft_s {
81} huft_t; 81} huft_t;
82 82
83static int gunzip_src_fd; 83static int gunzip_src_fd;
84static int gunzip_dst_fd;
85unsigned int gunzip_bytes_out; /* number of output bytes */ 84unsigned int gunzip_bytes_out; /* number of output bytes */
86static unsigned int gunzip_outbuf_count; /* bytes in output buffer */ 85static unsigned int gunzip_outbuf_count; /* bytes in output buffer */
87 86
@@ -93,11 +92,15 @@ unsigned char *gunzip_in_buffer;
93/* gunzip_window size--must be a power of two, and 92/* gunzip_window size--must be a power of two, and
94 * at least 32K for zip's deflate method */ 93 * at least 32K for zip's deflate method */
95static const int gunzip_wsize = 0x8000; 94static const int gunzip_wsize = 0x8000;
95static int output_buffer_size = 0x8000; // gunzip_wsize initially
96 96
97static unsigned char *gunzip_window; 97static unsigned char *gunzip_window;
98static unsigned int *gunzip_crc_table; 98static unsigned int *gunzip_crc_table;
99unsigned int gunzip_crc; 99unsigned int gunzip_crc;
100 100
101static unsigned char *output_buffer;
102static unsigned int output_buffer_len;
103
101/* If BMAX needs to be larger than 16, then h and x[] should be ulg. */ 104/* If BMAX needs to be larger than 16, then h and x[] should be ulg. */
102#define BMAX 16 /* maximum bit length of any code (16 for explode) */ 105#define BMAX 16 /* maximum bit length of any code (16 for explode) */
103#define N_MAX 288 /* maximum number of codes in any set */ 106#define N_MAX 288 /* maximum number of codes in any set */
@@ -410,9 +413,20 @@ static void flush_gunzip_window(void)
410 gunzip_crc = gunzip_crc_table[((int) gunzip_crc ^ (gunzip_window[n])) & 0xff] ^ (gunzip_crc >> 8); 413 gunzip_crc = gunzip_crc_table[((int) gunzip_crc ^ (gunzip_window[n])) & 0xff] ^ (gunzip_crc >> 8);
411 } 414 }
412 415
413 if (write(gunzip_dst_fd, gunzip_window, gunzip_outbuf_count) != gunzip_outbuf_count) { 416 if (output_buffer_len == 0) { // Our buffer is empty -> straight memcpy
414 error_msg_and_die("Couldnt write"); 417 memcpy(output_buffer, gunzip_window, gunzip_outbuf_count);
418 output_buffer_len = gunzip_outbuf_count;
419 } else { // Bit more complicated, append to end of output_buffer, realloc as necessary
420 int newlen = output_buffer_len + gunzip_outbuf_count;
421 if (newlen > output_buffer_size) {
422 output_buffer = xrealloc(output_buffer, newlen); // Could free later, but as we now have the memory...
423 //printf("Using %d byte output buffer\n", newlen);
424 output_buffer_size = newlen;
425 }
426 memcpy(output_buffer + output_buffer_len, gunzip_window, gunzip_outbuf_count);
427 output_buffer_len += gunzip_outbuf_count;
415 } 428 }
429
416 gunzip_bytes_out += gunzip_outbuf_count; 430 gunzip_bytes_out += gunzip_outbuf_count;
417 gunzip_outbuf_count = 0; 431 gunzip_outbuf_count = 0;
418} 432}
@@ -835,20 +849,49 @@ static int inflate_block(int *e)
835 * 849 *
836 * GLOBAL VARIABLES: gunzip_outbuf_count, bk, gunzip_bb, hufts, inptr 850 * GLOBAL VARIABLES: gunzip_outbuf_count, bk, gunzip_bb, hufts, inptr
837 */ 851 */
838extern int inflate(int in, int out) 852
853extern ssize_t read_gz(int fd, void *buf, size_t count)
839{ 854{
840 typedef void (*sig_type) (int); 855 static int e = 0; /* last block flag */
841 int e; /* last block flag */
842 int r; /* result code */ 856 int r; /* result code */
843 unsigned h = 0; /* maximum struct huft's malloc'ed */ 857 unsigned h = 0; /* maximum struct huft's malloc'ed */
858 ssize_t written = count;
859 static char *output_buffer_ptr = 0;
860
861 while (output_buffer_len == 0) { // We need more data
862 if (e) return 0; // No more data here!
863 gunzip_hufts = 0;
864 r = inflate_block(&e);
865 if (r != 0) {
866 error_msg_and_die("inflate error %d", r);
867 return -1;
868 }
869 if (gunzip_hufts > h) {
870 h = gunzip_hufts;
871 }
872 if (e) { // Ok finished uncompressing, get any buffered uncompressed data
873 flush_gunzip_window();
874 }
875 output_buffer_ptr = output_buffer;
876 }
877 if (count > output_buffer_len) written = output_buffer_len; // We're only giving them as much as we have!
878 memcpy(buf, output_buffer_ptr, written);
879 output_buffer_ptr += written;
880 output_buffer_len -= written;
881
882 return written;
883}
884
885extern void GZ_gzReadOpen(int fd, void *unused, int nUnused)
886{
887 typedef void (*sig_type) (int);
844 888
845 /* Allocate all global buffers (for DYN_ALLOC option) */ 889 /* Allocate all global buffers (for DYN_ALLOC option) */
846 gunzip_window = xmalloc(0x8000); 890 gunzip_window = xmalloc(gunzip_wsize);
891 output_buffer = xmalloc(gunzip_wsize);
847 gunzip_outbuf_count = 0; 892 gunzip_outbuf_count = 0;
848 gunzip_bytes_out = 0; 893 gunzip_bytes_out = 0;
849 894 gunzip_src_fd = fd;
850 gunzip_src_fd = in;
851 gunzip_dst_fd = out;
852 895
853 gunzip_in_buffer = malloc(8); 896 gunzip_in_buffer = malloc(8);
854 897
@@ -867,25 +910,13 @@ extern int inflate(int in, int out)
867 910
868 /* Create the crc table */ 911 /* Create the crc table */
869 make_gunzip_crc_table(); 912 make_gunzip_crc_table();
913}
870 914
871 /* decompress until the last block */ 915extern void GZ_gzReadClose(void)
872 do { 916{
873 gunzip_hufts = 0;
874 r = inflate_block(&e);
875 if (r != 0) {
876 error_msg_and_die("inflate error %d", r);
877 return r;
878 }
879 if (gunzip_hufts > h) {
880 h = gunzip_hufts;
881 }
882 } while (!e);
883
884 /* write any buffered uncompressed data */
885 flush_gunzip_window();
886 free(gunzip_window);
887
888 /* Cleanup */ 917 /* Cleanup */
918 free(gunzip_window);
919 free(output_buffer);
889 free(gunzip_crc_table); 920 free(gunzip_crc_table);
890 921
891 /* Store unused bytes in a global buffer so calling applets can access it */ 922 /* Store unused bytes in a global buffer so calling applets can access it */
@@ -898,7 +929,29 @@ extern int inflate(int in, int out)
898 gunzip_bb >>= 8; 929 gunzip_bb >>= 8;
899 gunzip_bk -= 8; 930 gunzip_bk -= 8;
900 } 931 }
932}
901 933
902 /* return success */ 934extern int inflate(int in, int out)
935{
936 char buf[8192];
937 ssize_t nread, nwrote;
938 ssize_t total = 0;
939
940 GZ_gzReadOpen(in, 0, 0);
941 while(1) { // Robbed from copyfd.c
942 nread = read_gz(in, buf, sizeof(buf));
943 if (nread == 0) break; // no data to write
944 else if (nread == -1) {
945 perror_msg("read");
946 return -1;
947 }
948 nwrote = full_write(out, buf, nread);
949 if (nwrote == -1) {
950 perror_msg("write");
951 return -1;
952 }
953 total += nwrote;
954 }
955 GZ_gzReadClose();
903 return 0; 956 return 0;
904} 957}
diff --git a/archival/libunarchive/unzip.c b/archival/libunarchive/unzip.c
index 20bf88f55..046f4dd72 100644
--- a/archival/libunarchive/unzip.c
+++ b/archival/libunarchive/unzip.c
@@ -81,7 +81,6 @@ typedef struct huft_s {
81} huft_t; 81} huft_t;
82 82
83static int gunzip_src_fd; 83static int gunzip_src_fd;
84static int gunzip_dst_fd;
85unsigned int gunzip_bytes_out; /* number of output bytes */ 84unsigned int gunzip_bytes_out; /* number of output bytes */
86static unsigned int gunzip_outbuf_count; /* bytes in output buffer */ 85static unsigned int gunzip_outbuf_count; /* bytes in output buffer */
87 86
@@ -93,11 +92,15 @@ unsigned char *gunzip_in_buffer;
93/* gunzip_window size--must be a power of two, and 92/* gunzip_window size--must be a power of two, and
94 * at least 32K for zip's deflate method */ 93 * at least 32K for zip's deflate method */
95static const int gunzip_wsize = 0x8000; 94static const int gunzip_wsize = 0x8000;
95static int output_buffer_size = 0x8000; // gunzip_wsize initially
96 96
97static unsigned char *gunzip_window; 97static unsigned char *gunzip_window;
98static unsigned int *gunzip_crc_table; 98static unsigned int *gunzip_crc_table;
99unsigned int gunzip_crc; 99unsigned int gunzip_crc;
100 100
101static unsigned char *output_buffer;
102static unsigned int output_buffer_len;
103
101/* If BMAX needs to be larger than 16, then h and x[] should be ulg. */ 104/* If BMAX needs to be larger than 16, then h and x[] should be ulg. */
102#define BMAX 16 /* maximum bit length of any code (16 for explode) */ 105#define BMAX 16 /* maximum bit length of any code (16 for explode) */
103#define N_MAX 288 /* maximum number of codes in any set */ 106#define N_MAX 288 /* maximum number of codes in any set */
@@ -410,9 +413,20 @@ static void flush_gunzip_window(void)
410 gunzip_crc = gunzip_crc_table[((int) gunzip_crc ^ (gunzip_window[n])) & 0xff] ^ (gunzip_crc >> 8); 413 gunzip_crc = gunzip_crc_table[((int) gunzip_crc ^ (gunzip_window[n])) & 0xff] ^ (gunzip_crc >> 8);
411 } 414 }
412 415
413 if (write(gunzip_dst_fd, gunzip_window, gunzip_outbuf_count) != gunzip_outbuf_count) { 416 if (output_buffer_len == 0) { // Our buffer is empty -> straight memcpy
414 error_msg_and_die("Couldnt write"); 417 memcpy(output_buffer, gunzip_window, gunzip_outbuf_count);
418 output_buffer_len = gunzip_outbuf_count;
419 } else { // Bit more complicated, append to end of output_buffer, realloc as necessary
420 int newlen = output_buffer_len + gunzip_outbuf_count;
421 if (newlen > output_buffer_size) {
422 output_buffer = xrealloc(output_buffer, newlen); // Could free later, but as we now have the memory...
423 //printf("Using %d byte output buffer\n", newlen);
424 output_buffer_size = newlen;
425 }
426 memcpy(output_buffer + output_buffer_len, gunzip_window, gunzip_outbuf_count);
427 output_buffer_len += gunzip_outbuf_count;
415 } 428 }
429
416 gunzip_bytes_out += gunzip_outbuf_count; 430 gunzip_bytes_out += gunzip_outbuf_count;
417 gunzip_outbuf_count = 0; 431 gunzip_outbuf_count = 0;
418} 432}
@@ -835,20 +849,49 @@ static int inflate_block(int *e)
835 * 849 *
836 * GLOBAL VARIABLES: gunzip_outbuf_count, bk, gunzip_bb, hufts, inptr 850 * GLOBAL VARIABLES: gunzip_outbuf_count, bk, gunzip_bb, hufts, inptr
837 */ 851 */
838extern int inflate(int in, int out) 852
853extern ssize_t read_gz(int fd, void *buf, size_t count)
839{ 854{
840 typedef void (*sig_type) (int); 855 static int e = 0; /* last block flag */
841 int e; /* last block flag */
842 int r; /* result code */ 856 int r; /* result code */
843 unsigned h = 0; /* maximum struct huft's malloc'ed */ 857 unsigned h = 0; /* maximum struct huft's malloc'ed */
858 ssize_t written = count;
859 static char *output_buffer_ptr = 0;
860
861 while (output_buffer_len == 0) { // We need more data
862 if (e) return 0; // No more data here!
863 gunzip_hufts = 0;
864 r = inflate_block(&e);
865 if (r != 0) {
866 error_msg_and_die("inflate error %d", r);
867 return -1;
868 }
869 if (gunzip_hufts > h) {
870 h = gunzip_hufts;
871 }
872 if (e) { // Ok finished uncompressing, get any buffered uncompressed data
873 flush_gunzip_window();
874 }
875 output_buffer_ptr = output_buffer;
876 }
877 if (count > output_buffer_len) written = output_buffer_len; // We're only giving them as much as we have!
878 memcpy(buf, output_buffer_ptr, written);
879 output_buffer_ptr += written;
880 output_buffer_len -= written;
881
882 return written;
883}
884
885extern void GZ_gzReadOpen(int fd, void *unused, int nUnused)
886{
887 typedef void (*sig_type) (int);
844 888
845 /* Allocate all global buffers (for DYN_ALLOC option) */ 889 /* Allocate all global buffers (for DYN_ALLOC option) */
846 gunzip_window = xmalloc(0x8000); 890 gunzip_window = xmalloc(gunzip_wsize);
891 output_buffer = xmalloc(gunzip_wsize);
847 gunzip_outbuf_count = 0; 892 gunzip_outbuf_count = 0;
848 gunzip_bytes_out = 0; 893 gunzip_bytes_out = 0;
849 894 gunzip_src_fd = fd;
850 gunzip_src_fd = in;
851 gunzip_dst_fd = out;
852 895
853 gunzip_in_buffer = malloc(8); 896 gunzip_in_buffer = malloc(8);
854 897
@@ -867,25 +910,13 @@ extern int inflate(int in, int out)
867 910
868 /* Create the crc table */ 911 /* Create the crc table */
869 make_gunzip_crc_table(); 912 make_gunzip_crc_table();
913}
870 914
871 /* decompress until the last block */ 915extern void GZ_gzReadClose(void)
872 do { 916{
873 gunzip_hufts = 0;
874 r = inflate_block(&e);
875 if (r != 0) {
876 error_msg_and_die("inflate error %d", r);
877 return r;
878 }
879 if (gunzip_hufts > h) {
880 h = gunzip_hufts;
881 }
882 } while (!e);
883
884 /* write any buffered uncompressed data */
885 flush_gunzip_window();
886 free(gunzip_window);
887
888 /* Cleanup */ 917 /* Cleanup */
918 free(gunzip_window);
919 free(output_buffer);
889 free(gunzip_crc_table); 920 free(gunzip_crc_table);
890 921
891 /* Store unused bytes in a global buffer so calling applets can access it */ 922 /* Store unused bytes in a global buffer so calling applets can access it */
@@ -898,7 +929,29 @@ extern int inflate(int in, int out)
898 gunzip_bb >>= 8; 929 gunzip_bb >>= 8;
899 gunzip_bk -= 8; 930 gunzip_bk -= 8;
900 } 931 }
932}
901 933
902 /* return success */ 934extern int inflate(int in, int out)
935{
936 char buf[8192];
937 ssize_t nread, nwrote;
938 ssize_t total = 0;
939
940 GZ_gzReadOpen(in, 0, 0);
941 while(1) { // Robbed from copyfd.c
942 nread = read_gz(in, buf, sizeof(buf));
943 if (nread == 0) break; // no data to write
944 else if (nread == -1) {
945 perror_msg("read");
946 return -1;
947 }
948 nwrote = full_write(out, buf, nread);
949 if (nwrote == -1) {
950 perror_msg("write");
951 return -1;
952 }
953 total += nwrote;
954 }
955 GZ_gzReadClose();
903 return 0; 956 return 0;
904} 957}