diff options
-rw-r--r-- | gcc/java/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/java/jcf-io.c | 49 | ||||
-rw-r--r-- | gcc/java/zextract.c | 6 | ||||
-rw-r--r-- | gcc/java/zipfile.h | 2 |
4 files changed, 57 insertions, 8 deletions
diff --git a/gcc/java/ChangeLog b/gcc/java/ChangeLog index 58d8a747676..f21e2a03286 100644 --- a/gcc/java/ChangeLog +++ b/gcc/java/ChangeLog @@ -1,3 +1,11 @@ +2000-09-02 Anthony Green <green@redhat.com> + + * jcf-io.c: Include zlib.h. + (open_in_zip): Read compressed class file archives. + * zipfile.h (ZipDirectory): Add uncompressed_size and + compression_method fields. + * zextract.c (read_zip_archive): Collect file compression info. + 2000-08-07 Hans Boehm <boehm@acm.org> * boehm.c (mark_reference_fields): Set marking bits for all words in diff --git a/gcc/java/jcf-io.c b/gcc/java/jcf-io.c index b4f4e2eecd4..7bd4fe81afa 100644 --- a/gcc/java/jcf-io.c +++ b/gcc/java/jcf-io.c @@ -30,6 +30,8 @@ The Free Software Foundation is independent of Sun Microsystems, Inc. */ #include "toplev.h" #include "java-tree.h" +#include "zlib.h" + /* DOS brain-damage */ #ifndef O_BINARY #define O_BINARY 0 /* MS-DOS brain-damage */ @@ -149,6 +151,7 @@ DEFUN(open_in_zip, (jcf, zipfile, zipmember, is_system), ZipDirectory *zipd; int i, len; ZipFile *zipf = opendir_in_zip (zipfile, is_system); + z_stream d_stream; /* decompression stream */ if (zipf == NULL) return -2; @@ -156,6 +159,10 @@ DEFUN(open_in_zip, (jcf, zipfile, zipmember, is_system), if (!zipmember) return 0; + d_stream.zalloc = (alloc_func) 0; + d_stream.zfree = (free_func) 0; + d_stream.opaque = (voidpf) 0; + len = strlen (zipmember); zipd = (struct ZipDirectory*) zipf->central_directory; @@ -165,17 +172,45 @@ DEFUN(open_in_zip, (jcf, zipfile, zipmember, is_system), strncmp (ZIPDIR_FILENAME (zipd), zipmember, len) == 0) { JCF_ZERO (jcf); - jcf->buffer = ALLOC (zipd->size); - jcf->buffer_end = jcf->buffer + zipd->size; - jcf->read_ptr = jcf->buffer; - jcf->read_end = jcf->buffer_end; + jcf->filbuf = jcf_unexpected_eof; jcf->filename = xstrdup (zipfile); jcf->classname = xstrdup (zipmember); jcf->zipd = (void *)zipd; - if (lseek (zipf->fd, zipd->filestart, 0) < 0 - || read (zipf->fd, jcf->buffer, zipd->size) != zipd->size) - return -2; + + if (zipd->compression_method == Z_NO_COMPRESSION) + { + jcf->buffer = ALLOC (zipd->size); + jcf->buffer_end = jcf->buffer + zipd->size; + jcf->read_ptr = jcf->buffer; + jcf->read_end = jcf->buffer_end; + if (lseek (zipf->fd, zipd->filestart, 0) < 0 + || read (zipf->fd, jcf->buffer, zipd->size) != zipd->size) + return -2; + } + else + { + char *buffer; + jcf->buffer = ALLOC (zipd->uncompressed_size); + d_stream.next_out = jcf->buffer; + d_stream.avail_out = zipd->uncompressed_size; + jcf->buffer_end = jcf->buffer + zipd->uncompressed_size; + jcf->read_ptr = jcf->buffer; + jcf->read_end = jcf->buffer_end; + buffer = ALLOC (zipd->size); + d_stream.next_in = buffer; + d_stream.avail_in = zipd->size; + if (lseek (zipf->fd, zipd->filestart, 0) < 0 + || read (zipf->fd, buffer, zipd->size) != zipd->size) + return -2; + /* Handle NO_HEADER using undocumented zlib feature. + This is a very common hack. */ + inflateInit2 (&d_stream, -MAX_WBITS); + inflate (&d_stream, Z_NO_FLUSH); + inflateEnd (&d_stream); + FREE (buffer); + } + return 0; } } diff --git a/gcc/java/zextract.c b/gcc/java/zextract.c index b7ced1562a1..f381f92c57f 100644 --- a/gcc/java/zextract.c +++ b/gcc/java/zextract.c @@ -318,6 +318,8 @@ read_zip_archive (zipf) for (i = 0; i < zipf->count; i++) { ZipDirectory *zipd = (ZipDirectory*)(dir_ptr + dir_last_pad); + int compression_method = (int) dir_ptr[4+C_COMPRESSION_METHOD]; + long size = makelong (&dir_ptr[4+C_COMPRESSED_SIZE]); long uncompressed_size = makelong (&dir_ptr[4+C_UNCOMPRESSED_SIZE]); long filename_length = makeword (&dir_ptr[4+C_FILENAME_LENGTH]); long extra_field_length = makeword (&dir_ptr[4+C_EXTRA_FIELD_LENGTH]); @@ -326,7 +328,9 @@ read_zip_archive (zipf) return -1; zipd->filename_length = filename_length; - zipd->size = uncompressed_size; + zipd->compression_method = compression_method; + zipd->size = size; + zipd->uncompressed_size = uncompressed_size; #ifdef __GNUC__ #define DIR_ALIGN __alignof__(ZipDirectory) #else diff --git a/gcc/java/zipfile.h b/gcc/java/zipfile.h index a19ec169f72..172829cbd1c 100644 --- a/gcc/java/zipfile.h +++ b/gcc/java/zipfile.h @@ -34,7 +34,9 @@ typedef struct ZipFile ZipFile; struct ZipDirectory { int direntry_size; int filename_offset; + int compression_method; long size; /* length of file */ + long uncompressed_size; /* length of uncompressed data */ long filestart; /* start of file in archive */ long filename_length; /* char mid_padding[...]; */ |