Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 8 Sep 2008 12:09:04 GMT
From:      Anselm Strauss <strauss@FreeBSD.org>
To:        Perforce Change Reviews <perforce@FreeBSD.org>
Subject:   PERFORCE change 149416 for review
Message-ID:  <200809081209.m88C94Bm075553@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=149416

Change 149416 by strauss@strauss_marvelman on 2008/09/08 12:08:40

	Work towards compression, things are currently broken ...

Affected files ...

.. //depot/projects/soc2008/strauss_libarchive/TODO#16 edit
.. //depot/projects/soc2008/strauss_libarchive/libarchive/archive_write_set_format_zip.c#41 edit
.. //depot/projects/soc2008/strauss_libarchive/misc/deflate/Makefile#1 add
.. //depot/projects/soc2008/strauss_libarchive/misc/deflate/deflate.c#1 add

Differences ...

==== //depot/projects/soc2008/strauss_libarchive/TODO#16 (text+ko) ====

@@ -1,6 +1,7 @@
 To Be Done
 ==========
 
+- add HAVE_ZLIB_H checks
 - Fix compiler warnings (also in checks)
 - Consider switching to 0x000d extension
 - Consider portability of code to other operating systems

==== //depot/projects/soc2008/strauss_libarchive/libarchive/archive_write_set_format_zip.c#41 (text+ko) ====

@@ -85,6 +85,7 @@
 static unsigned int dos_time(const time_t);
 static size_t path_length(struct archive_entry *);
 static int write_path(struct archive_entry *, struct archive_write *);
+static int set_compression(struct archive_write *, enum compression);
 
 struct zip_local_file_header {
 	char signature[4];
@@ -152,6 +153,7 @@
 	struct archive_entry *entry;
 	off_t offset;
 	uLong crc32;
+	enum compression compression;
 };
 
 struct zip {
@@ -161,6 +163,7 @@
 	off_t offset;
 	size_t written_bytes;
 	size_t remaining_data_bytes;
+	enum compression compression;
 };
 
 struct zip_central_directory_end {
@@ -174,6 +177,11 @@
 	char comment_length[2];
 };
 
+static enum compression {
+	COMPRESSION_STORE = 0,
+	COMPRESSION_DEFLATE = 6
+}; 
+
 int
 archive_write_set_format_zip(struct archive *_a)
 {
@@ -194,6 +202,7 @@
 	zip->offset = 0;
 	zip->written_bytes = 0;
 	zip->remaining_data_bytes = 0;
+	zip->compression = COMPRESSION_DEFLATE;
 	a->format_data = zip;
 
 	a->pad_uncompressed = 0; /* Actually not needed for now, since no compression support yet. */
@@ -214,6 +223,20 @@
 	return (ARCHIVE_OK);
 }
 
+/* TODO: Register compression setting functions in public header. */
+
+void
+archive_write_zip_set_store(struct archive_write *a)
+{
+	set_compression(a, COMPRESSION_STORE);
+}
+
+void
+archive_write_zip_set_deflate(struct archive_write *a)
+{
+	set_compression(a, COMPRESSION_DEFLATE);
+}
+
 static int
 archive_write_zip_header(struct archive_write *a, struct archive_entry *entry)
 {
@@ -250,6 +273,7 @@
 	}
 	l->entry = archive_entry_clone(entry);
 	l->crc32 = crc32(0, NULL, 0);
+	l->compression = zip->compression;
 	l->next = NULL;
 	if (zip->central_directory == NULL) {
 		zip->central_directory = l;
@@ -261,27 +285,22 @@
 	/* Store the offset of this header for later use in central directory. */ 
 	l->offset = zip->written_bytes;
 
-	/* 
-	 * Formatting local file header.
-	 * Some fields are not explicitely set after they were set to 0
-	 * by the memset() call, meaning they are unused or contain the default value.
-	 * The fields this is true for and the reason why are:
-	 * 
-	 *   - compression: Not yet supported (TODO)
-	 *   - crc32: written in data descriptor
-	 *   - extra_length: not used (TODO)
-	 */
 	memset(&h, 0, sizeof(h));
 	zip_encode(ZIP_SIGNATURE_LOCAL_FILE_HEADER, &h.signature, sizeof(h.signature));
 	zip_encode(ZIP_VERSION_EXTRACT, &h.version, sizeof(h.version));
 	zip_encode(ZIP_FLAGS, &h.flags, sizeof(h.flags));
+	zip_encode(zip->compression, &h.compression, sizeof(h.compression));
 	zip_encode(dos_time(archive_entry_mtime(entry)), &h.timedate, sizeof(h.timedate));
 	zip_encode(path_length(entry), &h.filename_length, sizeof(h.filename_length));
 	zip_encode(sizeof(e), &h.extra_length, sizeof(h.extra_length));
-	/* Setting compressed and uncompressed sizes even when specification says
-	 * to set to zero when using data descriptors. */
-	zip_encode(size, &h.compressed_size, sizeof(h.compressed_size));
-	zip_encode(size, &h.uncompressed_size, sizeof(h.uncompressed_size));
+	
+	if (zip->compression = COMPRESSION_STORE) {
+		/* Setting compressed and uncompressed sizes even when specification says
+		 * to set to zero when using data descriptors. Otherwise the end of the
+		 * data for an entry is rather difficult to find. */
+		zip_encode(size, &h.compressed_size, sizeof(h.compressed_size));
+		zip_encode(size, &h.uncompressed_size, sizeof(h.uncompressed_size));
+	}
 	
 	/* Formatting extra data. */
 	zip_encode(sizeof(e), &h.extra_length, sizeof(h.extra_length));
@@ -296,8 +315,6 @@
 	zip_encode(archive_entry_uid(entry), &e.unix_uid, sizeof(e.unix_uid));
 	zip_encode(archive_entry_gid(entry), &e.unix_gid, sizeof(e.unix_gid));
 	
-	/* This will surely change when compression is implemented. */
-	zip_encode(size, &d->compressed_size, sizeof(d->compressed_size));
 	zip_encode(size, &d->uncompressed_size, sizeof(d->uncompressed_size));
 	
 	ret = (a->compressor.write)(a, &h, sizeof(h));
@@ -324,11 +341,28 @@
 	int ret;
 	struct zip *zip = a->format_data;
 	struct zip_file_header_link *l = zip->central_directory_end;
+	z_stream stream;
 	
 	if (s > zip->remaining_data_bytes)
 		s = zip->remaining_data_bytes;
 	
-	ret = (a->compressor.write)(a, buff, s);
+	switch (zip->compression) {
+		
+		case COMPRESSION_STORE:
+		
+			ret = (a->compressor.write)(a, buff, s);
+		
+		case COMPRESSION_DEFLATE:
+			
+			deflateInit2(
+					stream,
+					
+			);
+			
+	}
+	
+	/* TODO: set compressed size in data descriptor and local file header link */
+	
 	if (ret >= 0) {
 		zip->written_bytes += s;
 		zip->remaining_data_bytes -= s;
@@ -367,7 +401,6 @@
 	struct zip_file_header h;
 	struct zip_central_directory_end end;
 	struct zip_extra_data_central e;
-	int64_t size;
 	off_t offset_start, offset_end;
 	int entries;
 	int ret;
@@ -397,11 +430,11 @@
 	 * writing each entry. */
 	while (l != NULL) {
 		
-		size = archive_entry_size(l->entry);
+		zip_encode(l->compression, &h.compression, sizeof(h.compression));
 		zip_encode(dos_time(archive_entry_mtime(l->entry)), &h.timedate, sizeof(h.timedate));
 		zip_encode(l->crc32, &h.crc32, sizeof(h.crc32));
-		zip_encode(size, &h.compressed_size, sizeof(h.compressed_size));
-		zip_encode(size, &h.uncompressed_size, sizeof(h.uncompressed_size));
+		/* TODO: write compressed size */
+		zip_encode(archive_entry_size(entry), &h.uncompressed_size, sizeof(h.uncompressed_size));
 		zip_encode(path_length(l->entry), &h.filename_length, sizeof(h.filename_length));
 		zip_encode(sizeof(e), &h.extra_length, sizeof(h.extra_length));
 		mode = archive_entry_mode(l->entry);
@@ -550,3 +583,12 @@
 	
 	return written_bytes;
 }
+
+static int
+set_compression(struct archive_write *a, enum compression compression)
+{
+	/* TODO: check archive state, should not switch between header and data */
+	/* TODO: check if valid compression? */
+	
+	a->format_data->compression = compression;
+}



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200809081209.m88C94Bm075553>