This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Patch: read compressed bytecode archives



This patch depends on zlib being moved over and my top-level and gcc
configure changes being approved.

See: http://gcc.gnu.org/ml/gcc-patches/2000-09/msg00062.html

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.

Index: gcc/java/zextract.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/java/zextract.c,v
retrieving revision 1.9
diff -u -p -u -r1.9 zextract.c
--- zextract.c	2000/04/27 00:18:41	1.9
+++ zextract.c	2000/08/16 06:57:21
@@ -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
Index: gcc/java/zipfile.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/java/zipfile.h,v
retrieving revision 1.8
diff -u -p -u -r1.8 zipfile.h
--- zipfile.h	2000/02/26 19:56:23	1.8
+++ zipfile.h	2000/08/16 06:57:21
@@ -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[...]; */
Index: gcc/java/jcf-io.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/java/jcf-io.c,v
retrieving revision 1.23
diff -u -p -u -r1.23 jcf-io.c
--- jcf-io.c	2000/05/09 19:55:52	1.23
+++ jcf-io.c	2000/08/16 06:57:21
@@ -30,6 +30,8 @@ The Free Software Foundation is independ
 #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, zipmem
   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, zipmem
   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, zipmem
 	  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;
 	}
     }

-- 
Anthony Green                                                        Red Hat
                                                       Sunnyvale, California

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]