summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/java/ChangeLog8
-rw-r--r--gcc/java/jcf-io.c49
-rw-r--r--gcc/java/zextract.c6
-rw-r--r--gcc/java/zipfile.h2
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[...]; */