]> granicus.if.org Git - zziplib/commitdiff
memdisk
authorGuido Draheim <guidod@gmx.de>
Mon, 16 May 2005 02:11:01 +0000 (02:11 +0000)
committerGuido Draheim <guidod@gmx.de>
Mon, 16 May 2005 02:11:01 +0000 (02:11 +0000)
 (.)

zzip/fetch.h
zzip/format.h
zzip/fseeko.c
zzip/fseeko.h
zzip/memdisk.c
zzip/memdisk.h
zzip/mmapped.c
zzip/mmapped.h
zzip/types.h
zziplib.spec

index 7e2777c22b48dadf5592e6ee89da08275a342586..bb719ba911a38b668ecc3f1203205b6c60712fe6 100644 (file)
@@ -3,6 +3,7 @@
 
 #include <zzip/types.h>
 #include <zzip/format.h> 
+#include <zzip/stdint.h>
 
 /* linux knows "byteswap.h" giving us an optimized variant */
 #ifdef ZZIP_HAVE_BYTESWAP_H
index 83dbf2e4de34ee3a5be53f8a505b316e170d2593..21857c3cd66ed6d82f45f29caae0179c7259a89f 100644 (file)
@@ -17,7 +17,7 @@
 #ifndef _ZZIP_FORMAT_H /* zzipformat.h */
 #define _ZZIP_FORMAT_H
  
-#include <zzip/lib.h>
+#include <zzip/types.h>
 /* we have ICO C 9X types defined */
 
 /* 
index 61a2852bd68b2aab4be636a150a5e6a1953bb71e..7daab3379f6aae674f81a3947940e46c0cefa075 100644 (file)
  * following code more readable, we use a shorthand notation for the
  * upcast needed in C (not needed in C++) as "disk_(entry)".
  */
-#ifdef __cplusplus
+#ifdef __zzip_entry_extends_zzip_disk_entry
 #define disk_(_entry_) _entry_
 #else
 #define disk_(_entry_) (& (_entry_)->head)
 #endif
 
-#ifdef __cplusplus
-struct zzip_entry : public struct zzip_disk_entry
-{
-    char*             _zzip_restrict tail;
-    zzip_off_t                  tailalloc;   /* the allocated size of tail */
-    FILE*                        diskfile;   /* a file reference */
-    zzip_off_t                   disksize;   /* the size of the file */
-    zzip_off_t                   headseek;   /* the offset within the file */
-    zzip_off_t                   zz_usize;
-    zzip_off_t                   zz_csize;   /* items scanned from header */
-    zzip_off_t                   zz_offset;  /* or zip64 extension block */
-    int                          zz_diskstart;
-};
-#else
-struct zzip_entry /* : struct zzip_disk_entry */
-{
-    struct zzip_disk_entry           head;
-    char*             _zzip_restrict tail;
-    zzip_off_t                  tailalloc;   /* the allocated size of tail */
-    FILE*                        diskfile;   /* a file reference */
-    zzip_off_t                   disksize;   /* the size of the file */
-    zzip_off_t                   headseek;   /* the offset within the file */
-    zzip_off_t                   zz_usize;
-    zzip_off_t                   zz_csize;   /* items scanned from header */
-    zzip_off_t                   zz_offset;  /* or zip64 extension block */
-    int                          zz_diskstart;
-};
-#endif
-
 /* we try to round all seeks to the pagesize - since we do not use
  * the sys/mmap interface we have to guess a good value here: */
 #define PAGESIZE 8192
index 83c9e2037cbb2c7f4f7234ed029f05aecb98b176..34ce3c5dac81e3d8ef7e0599eb303a6c380e80b8 100644 (file)
@@ -72,5 +72,37 @@ zzip_entry_fclose (ZZIP_ENTRY_FILE* file);
 int
 zzip_entry_feof (ZZIP_ENTRY_FILE* file);
 
+# ifdef _ZZIP_MEM_ENTRY_PRIVATE
+#  ifdef __cplusplus
+#  define __zzip_entry_extends_zzip_disk_entry
+struct zzip_entry : public struct zzip_disk_entry
+{
+    char*             _zzip_restrict tail;
+    zzip_off_t                  tailalloc;   /* the allocated size of tail */
+    FILE*                        diskfile;   /* a file reference */
+    zzip_off_t                   disksize;   /* the size of the file */
+    zzip_off_t                   headseek;   /* the offset within the file */
+    zzip_off_t                   zz_usize;
+    zzip_off_t                   zz_csize;   /* items scanned from header */
+    zzip_off_t                   zz_offset;  /* or zip64 extension block */
+    int                          zz_diskstart;
+};
+#  else
+struct zzip_entry /* : struct zzip_disk_entry */
+{
+    struct zzip_disk_entry           head;
+    char*             _zzip_restrict tail;
+    zzip_off_t                  tailalloc;   /* the allocated size of tail */
+    FILE*                        diskfile;   /* a file reference */
+    zzip_off_t                   disksize;   /* the size of the file */
+    zzip_off_t                   headseek;   /* the offset within the file */
+    zzip_off_t                   zz_usize;
+    zzip_off_t                   zz_csize;   /* items scanned from header */
+    zzip_off_t                   zz_offset;  /* or zip64 extension block */
+    int                          zz_diskstart;
+};
+#  endif /* __cplusplus */
+# endif /* _ZZIP_MEM_ENTRY_PRIVATE */
+
 #endif
 
index 04d7ba2c043c2e939e1133df7a00a98de13118e7..fab5087873f8ddcaf310dd0ddf0bc53d427994b9 100644 (file)
@@ -20,6 +20,7 @@
  *          of the Mozilla Public License 1.1
  */
 #define _ZZIP_MEM_DISK_PRIVATE 1
+#define _ZZIP_MMAPPED_PRIVATE 1
 
 #include <zzip/lib.h>                                  /* archive handling */
 #include <zzip/file.h>
@@ -28,6 +29,7 @@
 
 #include <stdlib.h>
 #include <stdio.h>
+#include <string.h>
 
 #include <zzip/mmapped.h>
 #include <zzip/memdisk.h>
@@ -43,35 +45,29 @@ static const char* error[] = {
     "zzip_mem_disk_fdopen: zzip_disk_mmap did fail"
 };
 
-struct _zzip_mem_disk_entry {
-    struct _zzip_mem_disk_entry* zz_next;
-    char*      zz_name;
-    char*      zz_data;
-    int        zz_flags;
-    int        zz_compr;
-    long       zz_crc32;
-    zzip_off_t zz_csize;
-    zzip_off_t zz_usize;
-    zzip_off_t zz_offset;
-    int        zz_diskstart;
-    int        zz_filetype;
-    char*      zz_comment;
-    size_t     zz_extcount;
-    struct _zzip_mem_disk_extra* zz_extras; /* extras[extcount] : array */
-};
+#define R _zzip_restrict /* a.k.a. allocated */
 
-struct _zzip_mem_disk_extra {
-    int   zz_datatype;
-    int   zz_datasize;
-    char* zz_data;
-};
 
-static ZZIP_MEM_DISK_ENTRY* _zzip_new
-zzip_mem_disk_entry_new(ZZIP_DISK* disk, ZZIP_DISK_ENTRY* entry);
-static void
-zzip_mem_disk_entry_free(ZZIP_MEM_DISK_ENTRY* _zzip_restrict item);
+#define ZZIP_EXTRA_zip64 0x0001
+typedef struct _zzip_extra_zip64 { /* ZIP64 extended information extra field */
+    char z_datatype[2]; /* Tag for this "extra" block type */
+    char z_datasize[2]; /* Size of this "extra" block */
+    char z_usize[8]; /* Original uncompressed file size */
+    char z_csize[8]; /* Size of compressed data */
+    char z_offset[8]; /* Offset of local header record */
+    char z_diskstart[4]; /* Number of the disk for file start*/
+} zzip_extra_zip64;
 
+static ZZIP_MEM_ENTRY* _zzip_new
+zzip_mem_entry_new(ZZIP_DISK* disk, ZZIP_DISK_ENTRY* entry);
+static void
+zzip_mem_entry_free(ZZIP_MEM_ENTRY* _zzip_restrict item);
 
+ZZIP_MEM_DISK* _zzip_new
+zzip_mem_disk_new(void)
+{
+    return calloc(1, sizeof(ZZIP_MEM_DISK)); 
+}
 
 /** create new diskdir handle. 
  *  wraps underlying zzip_disk_open. */
@@ -80,7 +76,7 @@ zzip_mem_disk_open(char* filename)
 {
     ZZIP_DISK* disk = zzip_disk_open(filename);
     if (! disk) { perror(error[_zzip_mem_disk_open_fail]); return 0; }
-    ___ ZZIP_MEM_DISK* dir = calloc(1, sizeof(*dir)); 
+    ___ ZZIP_MEM_DISK* dir = zzip_mem_disk_new();
     zzip_mem_disk_load(dir, disk);
     return dir; ____;
 }
@@ -92,26 +88,34 @@ zzip_mem_disk_fdopen(int fd)
 {
     ZZIP_DISK* disk = zzip_disk_mmap(fd);
     if (! disk) { perror(error[_zzip_mem_disk_fdopen_fail]); return 0; }
-    ___ ZZIP_MEM_DISK* dir = calloc(1, sizeof(*dir)); 
+    ___ ZZIP_MEM_DISK* dir = zzip_mem_disk_new();
     zzip_mem_disk_load(dir, disk);
     return dir; ____;
 }
 
 /** parse central dir.
  *  creates an internal copy of each entry converted to the local platform.
+ *  returns: number of entries, or -1 on error (setting errno)
  */
-int
+long
 zzip_mem_disk_load(ZZIP_MEM_DISK* dir, ZZIP_DISK* disk)
 {
+    if (! dir || ! disk) { errno=EINVAL; return -1; }
     if (dir->list) zzip_mem_disk_unload(dir);
+    ___ long count = 0;
     ___ struct zzip_disk_entry* entry = zzip_disk_findfirst(disk);
     for (; entry ; entry = zzip_disk_findnext(disk, entry)) {
-       ZZIP_MEM_DISK_ENTRY* item = zzip_mem_disk_entry_new(disk, entry);
-       if (dir->last) { dir->last->zz_next = item; }
-       else { dir->list = item; }; dir->last = item;
+       ZZIP_MEM_ENTRY* item = zzip_mem_entry_new(disk, entry);
+       if (! item) goto error;
+       if (dir->last) { dir->last->zz_next = item; }    /* chain last */
+       else { dir->list = item; }; dir->last = item;    /* to earlier */
+       count++;
     } ____;
     dir->disk = disk;
-    return 0;
+    return count; ____;
+ error:
+    zzip_mem_disk_unload (dir); 
+    return -1;
 }
 
 /** convert a zip disk entry to internal format.
@@ -119,21 +123,19 @@ zzip_mem_disk_load(ZZIP_MEM_DISK* dir, ZZIP_DISK* disk)
  * in the zip archive. This is a good place to extend functionality if
  * you have a project with extra requirements as you can push more bits
  * right into the diskdir_entry for later usage in higher layers.
+ * returns: new item, or null on error (setting errno)
  */
-ZZIP_MEM_DISK_ENTRY* _zzip_new
-zzip_mem_disk_entry_new(ZZIP_DISK* disk, ZZIP_DISK_ENTRY* entry) 
+ZZIP_MEM_ENTRY* _zzip_new
+zzip_mem_entry_new(ZZIP_DISK* disk, ZZIP_DISK_ENTRY* entry) 
 {
-    ZZIP_MEM_DISK_ENTRY* item = calloc(1, sizeof(*item));
-    struct zzip_file_header* header = 
+    if (! disk || ! entry) { errno=EINVAL; return 0; }
+    ___ ZZIP_MEM_ENTRY* item = calloc(1, sizeof(*item));
+    if (! item) return 0; /* errno=ENOMEM; */
+    ___ struct zzip_file_header* header = 
        zzip_disk_entry_to_file_header(disk, entry);
     /*  there is a number of duplicated information in the file header
      *  or the disk entry block. Theoretically some part may be missing
-     *  that exists in the other, so each and every item would need to
-     *  be checked. However, we assume that the "always-exists" fields
-     *  do either (a) exist both and have the same value or (b) the bits
-     *  in the disk entry are correct. Only the variable fields are 
-     *  checked in both places: file name, file comment, extra blocks.
-     *  From mmapped.c we do already have two helper functions for that:
+     *  that exists in the other, ... but we will prefer the disk entry.
      */
     item->zz_comment =   zzip_disk_entry_strdup_comment(disk, entry);
     item->zz_name =      zzip_disk_entry_strdup_name(disk, entry);
@@ -146,118 +148,78 @@ zzip_mem_disk_entry_new(ZZIP_DISK* disk, ZZIP_DISK_ENTRY* entry)
     item->zz_diskstart = zzip_disk_entry_get_diskstart(entry);
     item->zz_filetype =  zzip_disk_entry_get_filetype(entry);
 
-    { /* 1. scanning the extra blocks and building a fast-access table. */
-       size_t extcount = 0;
-       int    extlen = zzip_file_header_get_extras(header);
-       char*  extras = zzip_file_header_to_extras(header);
-       while (extlen > 0) {
-           struct zzip_extra_block* ext = (struct zzip_extra_block*) extras;
-           int size = zzip_extra_block_sizeto_end(ext);
-           extlen -= size; extras += size; extcount ++;
+    {   /* copy the extra blocks to memory as well */
+       int     ext1 = zzip_disk_entry_get_extras(entry);
+       char* R ptr1 = zzip_disk_entry_to_extras(entry);
+       int     ext2 = zzip_file_header_get_extras(header);
+       char* R ptr2 = zzip_file_header_to_extras(header);
+       
+       if (ext1) {
+           void* mem = malloc (ext1+2);
+           item->zz_ext[1] = mem;
+           memcpy (mem, ptr1, ext1);
+           ((char*)(mem))[ext1+0] = 0; 
+           ((char*)(mem))[ext1+1] = 0;
+       }           
+       if (ext2) {
+           void* mem = malloc (ext2+2);
+           item->zz_ext[2] = mem;
+           memcpy (mem, ptr2, ext2);
+           ((char*)(mem))[ext2+0] = 0; 
+           ((char*)(mem))[ext2+1] = 0;
+       }           
+    }    
+    {   /* override sizes/offsets with zip64 values for largefile support */
+       zzip_extra_zip64* block = (zzip_extra_zip64*)
+           zzip_mem_entry_extra_block (item, ZZIP_EXTRA_zip64);
+       if (block) {
+           item->zz_usize  =    __zzip_get64(block->z_usize);
+           item->zz_csize  =    __zzip_get64(block->z_csize);
+           item->zz_offset =    __zzip_get64(block->z_offset);
+           item->zz_diskstart = __zzip_get32(block->z_diskstart);
        }
-       extlen = zzip_disk_entry_get_extras(entry);
-       extras = zzip_disk_entry_to_extras(entry);
-       while (extlen > 0) {
-           struct zzip_extra_block* ext = (struct zzip_extra_block*) extras;
-           int size = zzip_extra_block_sizeto_end(ext);
-           extlen -= size; extras += size; extcount ++;
-       }
-       if (item->zz_extras) free(item->zz_extras);
-       item->zz_extras = calloc(extcount,sizeof(struct _zzip_mem_disk_extra));
-       item->zz_extcount = extcount;
     }
-    { /* 2. reading the extra blocks and building a fast-access table. */
-       size_t ext = 0;
-       int    extlen = zzip_file_header_get_extras(header);
-       char*  extras = zzip_file_header_to_extras(header);
-       struct _zzip_mem_disk_extra* mem = item->zz_extras;
-       while (extlen > 0) {
-           struct zzip_extra_block* ext = (struct zzip_extra_block*) extras;
-           mem[ext].zz_data = extras;
-           mem[ext].zz_datatype = zzip_extra_block_get_datatype(ext);
-           mem[ext].zz_datasize = zzip_extra_block_get_datasize(ext);
-           ___ register int size = zzip_extra_block_sizeto_end(ext);
-           extlen -= size; extras += size; ext ++; ____;
-       }
-       extlen = zzip_disk_entry_get_extras(entry);
-       extras = zzip_disk_entry_to_extras(entry);
-       while (extlen > 0) {
-           struct zzip_extra_block* ext = (struct zzip_extra_block*) extras;
-           mem[ext].zz_data = extras;
-           mem[ext].zz_datatype = zzip_extra_block_get_datatype(ext);
-           mem[ext].zz_datasize = zzip_extra_block_get_datasize(ext);
-           ___ register int size = zzip_extra_block_sizeto_end(ext);
-           extlen -= size; extras += size; ext ++; ____;
-       }
-    }
-    { /* 3. scanning the extra blocks for platform specific extensions. */
-       register size_t ext;
-       for (ext = 0; ext < item->zz_extcount; ext++) {
-           /* "http://www.pkware.com/company/standards/appnote/" */
-           switch (item->zz_extras[ext].zz_datatype) {
-           case 0x0001: { /* ZIP64 extended information extra field */
-               struct {
-                   char z_datatype[2]; /* Tag for this "extra" block type */
-                   char z_datasize[2]; /* Size of this "extra" block */
-                   char z_usize[8]; /* Original uncompressed file size */
-                   char z_csize[8]; /* Size of compressed data */
-                   char z_offset[8]; /* Offset of local header record */
-                   char z_diskstart[4]; /* Number of the disk for file start*/
-               } *block = (void*) item->zz_extras[ext].zz_data;
-               item->zz_usize  =    __zzip_get64(block->z_usize);
-               item->zz_csize  =    __zzip_get64(block->z_csize);
-               item->zz_offset =    __zzip_get64(block->z_offset);
-               item->zz_diskstart = __zzip_get32(block->z_diskstart);
-           } break;
-           case 0x0007: /* AV Info */
-           case 0x0008: /* Reserved for future Unicode file name data (PFS) */
-           case 0x0009: /* OS/2 */
-           case 0x000a: /* NTFS */
-           case 0x000c: /* OpenVMS */
-           case 0x000d: /* Unix */
-           case 0x000e: /* Reserved for file stream and fork descriptors */
-           case 0x000f: /* Patch Descriptor */
-           case 0x0014: /* PKCS#7 Store for X.509 Certificates */
-           case 0x0015: /* X.509 Certificate ID and Signature for file */
-           case 0x0016: /* X.509 Certificate ID for Central Directory */
-           case 0x0017: /* Strong Encryption Header */
-           case 0x0018: /* Record Management Controls */
-           case 0x0019: /* PKCS#7 Encryption Recipient Certificate List */
-           case 0x0065: /* IBM S/390, AS/400 attributes - uncompressed */
-           case 0x0066: /* Reserved for IBM S/390, AS/400 attr - compressed */
-           case 0x07c8: /* Macintosh */
-           case 0x2605: /* ZipIt Macintosh */
-           case 0x2705: /* ZipIt Macintosh 1.3.5+ */
-           case 0x2805: /* ZipIt Macintosh 1.3.5+ */
-           case 0x334d: /* Info-ZIP Macintosh */
-           case 0x4341: /* Acorn/SparkFS  */
-           case 0x4453: /* Windows NT security descriptor (binary ACL) */
-           case 0x4704: /* VM/CMS */
-           case 0x470f: /* MVS */
-           case 0x4b46: /* FWKCS MD5 (see below) */
-           case 0x4c41: /* OS/2 access control list (text ACL) */
-           case 0x4d49: /* Info-ZIP OpenVMS */
-           case 0x4f4c: /* Xceed original location extra field */
-           case 0x5356: /* AOS/VS (ACL) */
-           case 0x5455: /* extended timestamp */
-           case 0x554e: /* Xceed unicode extra field */
-           case 0x5855: /* Info-ZIP Unix (original, also OS/2, NT, etc) */
-           case 0x6542: /* BeOS/BeBox */
-           case 0x756e: /* ASi Unix */
-           case 0x7855: /* Info-ZIP Unix (new) */
-           case 0xfd4a: /* SMS/QDOS */
-               break;
+    /* NOTE: 
+     * All information from the central directory entry is now in memory.
+     * Effectivly that allows us to modify it and write it back to disk.
+     */
+    return item; ____;____;
+}
+
+/* find an extra block for the given datatype code. 
+ * We assume that the central directory has been preparsed to memory.
+ */
+ZZIP_EXTRA_BLOCK*
+zzip_mem_entry_extra_block (ZZIP_MEM_ENTRY* entry, short datatype)
+{
+    int i = 2;
+    while (1) {
+       ZZIP_EXTRA_BLOCK* ext = entry->zz_ext[i];
+       if (ext) {
+           while (ext->z_datatype) {
+               if (datatype == zzip_extra_block_get_datatype (ext)) {
+                   return ext;
+               }
+               ___ char* e = (char*) ext;
+               e += zzip_extra_block_headerlength;
+               e += zzip_extra_block_get_datasize (ext);
+               ext = (void*) e; ____;
            }
        }
+       if (! i) return 0;
+       i--;
     }
-    return item;
 }
-    
+
 void
-zzip_mem_disk_entry_free(ZZIP_MEM_DISK_ENTRY* _zzip_restrict item) 
+zzip_mem_entry_free(ZZIP_MEM_ENTRY* _zzip_restrict item) 
 {
     if (item) {
-       if (item->zz_extras) free(item->zz_extras);
+       if (item->zz_ext[0]) free (item->zz_ext[0]);
+       if (item->zz_ext[1]) free (item->zz_ext[1]);
+       if (item->zz_ext[2]) free (item->zz_ext[2]);
+       if (item->zz_comment) free (item->zz_comment);
+       if (item->zz_name) free (item->zz_name);
        free (item);
     }
 }
@@ -265,10 +227,10 @@ zzip_mem_disk_entry_free(ZZIP_MEM_DISK_ENTRY* _zzip_restrict item)
 void
 zzip_mem_disk_unload(ZZIP_MEM_DISK* dir)
 {
-    ZZIP_MEM_DISK_ENTRY* item = dir->list;
+    ZZIP_MEM_ENTRY* item = dir->list;
     while (item) {
-       ZZIP_MEM_DISK_ENTRY* next = item->zz_next;
-       zzip_mem_disk_entry_free(item); item = next;
+       ZZIP_MEM_ENTRY* next = item->zz_next;
+       zzip_mem_entry_free(item); item = next;
     }
     dir->list = dir->last = 0; dir->disk = 0;
 }
@@ -282,3 +244,130 @@ zzip_mem_disk_close(ZZIP_MEM_DISK* _zzip_restrict dir)
        free (dir);
     }
 }
+
+#if 0
+static void foo (short zz_datatype) {
+    switch (zz_datatype) {
+    case 0x0001: /* ZIP64 extended information extra field */
+    case 0x0007: /* AV Info */
+    case 0x0008: /* Reserved for future Unicode file name data (PFS) */
+    case 0x0009: /* OS/2 */
+    case 0x000a: /* NTFS */
+    case 0x000c: /* OpenVMS */
+    case 0x000d: /* Unix */
+    case 0x000e: /* Reserved for file stream and fork descriptors */
+    case 0x000f: /* Patch Descriptor */
+    case 0x0014: /* PKCS#7 Store for X.509 Certificates */
+    case 0x0015: /* X.509 Certificate ID and Signature for file */
+    case 0x0016: /* X.509 Certificate ID for Central Directory */
+    case 0x0017: /* Strong Encryption Header */
+    case 0x0018: /* Record Management Controls */
+    case 0x0019: /* PKCS#7 Encryption Recipient Certificate List */
+    case 0x0065: /* IBM S/390, AS/400 attributes - uncompressed */
+    case 0x0066: /* Reserved for IBM S/390, AS/400 attr - compressed */
+    case 0x07c8: /* Macintosh */
+    case 0x2605: /* ZipIt Macintosh */
+    case 0x2705: /* ZipIt Macintosh 1.3.5+ */
+    case 0x2805: /* ZipIt Macintosh 1.3.5+ */
+    case 0x334d: /* Info-ZIP Macintosh */
+    case 0x4341: /* Acorn/SparkFS  */
+    case 0x4453: /* Windows NT security descriptor (binary ACL) */
+    case 0x4704: /* VM/CMS */
+    case 0x470f: /* MVS */
+    case 0x4b46: /* FWKCS MD5 (see below) */
+    case 0x4c41: /* OS/2 access control list (text ACL) */
+    case 0x4d49: /* Info-ZIP OpenVMS */
+    case 0x4f4c: /* Xceed original location extra field */
+    case 0x5356: /* AOS/VS (ACL) */
+    case 0x5455: /* extended timestamp */
+    case 0x554e: /* Xceed unicode extra field */
+    case 0x5855: /* Info-ZIP Unix (original, also OS/2, NT, etc) */
+    case 0x6542: /* BeOS/BeBox */
+    case 0x756e: /* ASi Unix */
+    case 0x7855: /* Info-ZIP Unix (new) */
+    case 0xfd4a: /* SMS/QDOS */
+    }
+}
+#endif
+
+ZZIP_MEM_ENTRY*
+zzip_mem_disk_findfile(ZZIP_MEM_DISK* dir, 
+                       char* filename, ZZIP_MEM_ENTRY* after,
+                      zzip_strcmp_fn_t compare) 
+{
+    ZZIP_MEM_ENTRY* entry = (! after ? dir->list : after->zz_next);
+    if (! compare) compare = (zzip_strcmp_fn_t) (strcmp);
+    for (; entry ; entry = entry->zz_next) {
+       if (! compare (filename, entry->zz_name)) {
+           return entry;
+       }
+    }
+    return 0;
+}
+
+ZZIP_MEM_ENTRY*
+zzip_mem_disk_findmatch(ZZIP_MEM_DISK* dir, 
+                        char* filespec, ZZIP_MEM_ENTRY* after,
+                       zzip_fnmatch_fn_t compare, int flags)
+{
+    ZZIP_MEM_ENTRY* entry = (! after ? dir->list : after->zz_next);
+    if (! compare) compare = (zzip_fnmatch_fn_t) _zzip_fnmatch;
+    for (; entry ; entry = entry->zz_next) {
+       if (! compare (filespec, entry->zz_name, flags)) {
+           return entry;
+       }
+    }
+    return 0;
+}
+
+ZZIP_MEM_DISK_FILE* _zzip_new
+zzip_mem_entry_fopen (ZZIP_MEM_DISK* dir, ZZIP_MEM_ENTRY* entry) 
+{
+    /* keep this in sync with zzip_disk_entry_fopen */
+    ZZIP_DISK_FILE* file = malloc(sizeof(ZZIP_MEM_DISK_FILE));
+    if (! file) return file;
+    file->buffer = dir->disk->buffer;
+    file->endbuf = dir->disk->endbuf;
+    file->avail = zzip_mem_entry_usize (entry);
+
+    if (! file->avail || zzip_mem_entry_data_stored (entry))
+    { file->stored = zzip_mem_entry_to_data (entry); return file; }
+
+    file->stored = 0;
+    file->zlib.opaque = 0;
+    file->zlib.zalloc = Z_NULL;
+    file->zlib.zfree = Z_NULL;
+    file->zlib.avail_in = zzip_mem_entry_csize (entry);
+    file->zlib.next_in = zzip_mem_entry_to_data (entry);
+
+    if (! zzip_mem_entry_data_deflated (entry) ||
+       inflateInit2 (& file->zlib, -MAX_WBITS) != Z_OK)
+    { free (file); return 0; }
+
+    return file;
+}
+
+ZZIP_MEM_DISK_FILE* _zzip_new
+zzip_mem_disk_fopen (ZZIP_MEM_DISK* dir, char* filename) 
+{
+    ZZIP_MEM_ENTRY* entry = zzip_mem_disk_findfile (dir, filename, 0, 0);
+    if (! entry) return 0; else return zzip_mem_entry_fopen (dir, entry);
+}
+_zzip_size_t
+zzip_mem_disk_fread (void* ptr, _zzip_size_t size, _zzip_size_t nmemb,
+                     ZZIP_MEM_DISK_FILE* file)
+{
+    return zzip_disk_fread (ptr, size, nmemb, file);
+}
+
+int
+zzip_mem_disk_fclose (ZZIP_MEM_DISK_FILE* file) 
+{
+    return zzip_disk_fclose (file);
+}
+
+int
+zzip_mem_disk_feof (ZZIP_MEM_DISK_FILE* file)
+{
+    return zzip_disk_feof (file);
+}
index 18c3247a6046ab13332d1b6e573a37899f34c6eb..eb3d9c58cbc3a75883b4840b8889249964b17371 100644 (file)
@@ -1,16 +1,17 @@
 #ifndef __ZZIP_MEMDISK_H
 #define __ZZIP_MEMDISK_H
 
+#include <zzip/types.h>
 #include <zzip/mmapped.h>
 
 typedef struct _zzip_mem_disk ZZIP_MEM_DISK;
-typedef struct _zzip_mem_disk_entry ZZIP_MEM_DISK_ENTRY;
+typedef struct _zzip_mem_entry ZZIP_MEM_ENTRY;
 
 struct _zzip_mem_disk {
     ZZIP_DISK* disk;
 #  ifdef _ZZIP_MEM_DISK_PRIVATE
-    ZZIP_MEM_DISK_ENTRY* list;
-    ZZIP_MEM_DISK_ENTRY* last;
+    ZZIP_MEM_ENTRY* list;
+    ZZIP_MEM_ENTRY* last;
 #  endif
 };
 
@@ -18,6 +19,8 @@ struct _zzip_mem_disk {
 #define zzip_mem_disk_extern
 #endif
 
+zzip_mem_disk_extern ZZIP_MEM_DISK* _zzip_new
+zzip_mem_disk_new (void);
 zzip_mem_disk_extern ZZIP_MEM_DISK* _zzip_new
 zzip_mem_disk_open (char* filename);
 zzip_mem_disk_extern ZZIP_MEM_DISK* _zzip_new
@@ -25,97 +28,127 @@ zzip_mem_disk_fdopen (int fd);
 zzip_mem_disk_extern void 
 zzip_mem_disk_close (ZZIP_MEM_DISK* _zzip_restrict dir);
 
-zzip_mem_disk_extern int 
+zzip_mem_disk_extern long
 zzip_mem_disk_load (ZZIP_MEM_DISK* dir, ZZIP_DISK* disk);
 zzip_mem_disk_extern void 
 zzip_mem_disk_unload (ZZIP_MEM_DISK* dir);
+ZZIP_EXTRA_BLOCK*
+zzip_mem_entry_extra_block (ZZIP_MEM_ENTRY* entry, short datatype);
 
 #ifdef USE_INLINE
-_zzip_inline ZZIP_DISK_ENTRY*
-zzip_mem_disk_findfirst(ZZIP_MEM_DISK* dir) {
-    return zzip_disk_findfirst(dir->disk); }
-_zzip_inline ZZIP_DISK_ENTRY*
-zzip_mem_disk_findnext(ZZIP_MEM_DISK* dir, ZZIP_DISK_ENTRY* entry) {
-    return zzip_mem_disk_findnext(dir->disk, entry);
-}
+_zzip_inline ZZIP_DISK* zzip_disk (ZZIP_MEM_DISK* dir) { return dir->disk; }
 #else
-#define zzip_mem_disk_findfirst(__dir) \
-             zzip_disk_findfirst((__dir)->disk)
-#define zzip_mem_disk_findnext(__dir,__entry) \
-            zzip_disk_findnext((__dir)->disk,(__entry))
+#define zzip_disk(_X_) ((_X_)->disk)
 #endif
 
-#ifdef USE_INLINE
+
+/* these functions are much faster than the orgiinal zzip_disk_ functions */
+
+/* zzip_mem_entry <is similar to> zzip_disk_entry */
+struct _zzip_mem_entry {
+    struct _zzip_mem_entry* zz_next;
+    char*            zz_name;      /* zero-terminated (from "filename") */
+    char*            zz_data;      /* compressed content start (mmap addr) */
+    int              zz_flags;     /* (from "z_flags") */
+    int              zz_compr;     /* (from "z_compr") */
+    long             zz_crc32;     /* (from "z_crc32") */
+    zzip_off_t       zz_csize;     /* (from "z_csize")  overridden by zip64 */
+    zzip_off_t       zz_usize;     /* (from "z_usize")  overridden by zip64 */
+    zzip_off_t       zz_offset;    /* (from "z_offset") overridden by zip64 */
+    int              zz_diskstart; /* (from "z_diskstart") rridden by zip64 */
+    int              zz_filetype;  /* (from "z_filetype") */
+    char*            zz_comment;   /* zero-terminated (from "comment") */
+    ZZIP_EXTRA_BLOCK* zz_ext[3];   /* terminated by null in z_datatype */
+};                                 /* the extra blocks are NOT converted */
+     
+#define _zzip_mem_disk_findfirst(_d_) ((_d_)->list)
+#define _zzip_mem_disk_findnext(_d_,_e_) ((_e_)?(_d_)->list:(_e_)->zz_next)
+#define _zzip_mem_entry_findnext(_e_) ((_e_)->zz_next)
+
+#ifndef USE_INLINE
+#define zzip_mem_disk_findfirst _zzip_mem_disk_findfirst
+#define zzip_mem_disk_findnext _zzip_mem_disk_findnext
+#define zzip_mem_entry_findnext _zzip_mem_entry_findnext
+#else
+
+_zzip_inline ZZIP_MEM_ENTRY*
+zzip_mem_disk_findfirst(ZZIP_MEM_DISK* dir) {
+    if (! dir) return 0;
+    return _zzip_mem_disk_findfirst(dir); }
+_zzip_inline ZZIP_MEM_ENTRY*
+zzip_mem_disk_findnext(ZZIP_MEM_DISK* dir, ZZIP_MEM_ENTRY* entry) {
+    if (! dir) return 0;
+    return _zzip_mem_disk_findnext(dir, entry); }
+_zzip_inline ZZIP_MEM_ENTRY*
+zzip_mem_entry_findnext(ZZIP_MEM_ENTRY* entry) {
+    if (! entry) return 0;
+    return _zzip_mem_entry_findnext(entry); }
+#endif
+
+#define _zzip_mem_entry_to_name(_e_) ((_e_)->zz_name)
+#define _zzip_mem_entry_strdup_name(_e_) (strdup((_e_)->zz_name))
+#define _zzip_mem_entry_to_data(_e_) ((_e_)->zz_data)
+
+#ifndef USE_INLINE
+#define zzip_mem_entry_to_name _zzip_mem_entry_to_name
+#define zzip_mem_entry_strdup_name _zzip_mem_entry_strdup_name
+#define zzip_mem_entry_to_data _zzip_mem_entry_to_data
+#else
+_zzip_inline char*
+zzip_mem_entry_to_name(ZZIP_MEM_ENTRY* entry) {
+    if (! entry) return 0;
+    return _zzip_mem_entry_to_name(entry); }
 _zzip_inline char* _zzip_new
-zzip_mem_disk_entry_strdup_name(ZZIP_MEM_DISK* dir, 
-                                ZZIP_DISK_ENTRY* entry) {
-    return zzip_disk_entry_strdup_name(dir->disk, entry); }
-_zzip_inline struct zzip_file_header*
-zzip_mem_disk_entry_to_file_header(ZZIP_MEM_DISK* dir, 
-                                  ZZIP_DISK_ENTRY* entry) {
-    return zzip_disk_entry_to_file_header(dir->disk, entry); }
+zzip_mem_entry_strdup_name(ZZIP_MEM_ENTRY* entry) {
+    if (! entry) return 0;
+    return _zzip_mem_entry_strdup_name(entry); }
 _zzip_inline char*
-zzip_mem_disk_entry_to_data(ZZIP_MEM_DISK* dir, ZZIP_DISK_ENTRY* entry) {
-    return zzip_disk_entry_to_data(dir->disk, entry); }
-#else
-#define zzip_mem_disk_entry_strdup_name(__dir,__entry) \
-            zzip_disk_entry_strdup_name((__dir)->disk,(__entry))
-#define zzip_mem_disk_entry_to_file_header(__dir,__entry) \
-            zzip_disk_entry_to_file_header((__dir)->disk,(__entry))
-#define zzip_mem_disk_entry_to_data(__dir,__entry) \
-            zzip_disk_entry_to_data((__dir)->disk,(__entry))
+zzip_mem_entry_to_data(ZZIP_MEM_ENTRY* entry) {
+    if (! entry) return 0;
+    return _zzip_mem_entry_to_data(entry); }
 #endif
 
-#ifdef USE_INLINE
-_zzip_inline ZZIP_DISK_ENTRY*
+ZZIP_MEM_ENTRY*
 zzip_mem_disk_findfile(ZZIP_MEM_DISK* dir, 
-                       char* filename, ZZIP_DISK_ENTRY* after,
-                      zzip_strcmp_fn_t compare) {
-    return zzip_disk_findfile(dir->disk, filename, after, compare); }
-_zzip_inline ZZIP_DISK_ENTRY*
+                       char* filename, ZZIP_MEM_ENTRY* after,
+                      zzip_strcmp_fn_t compare);
+
+ZZIP_MEM_ENTRY*
 zzip_mem_disk_findmatch(ZZIP_MEM_DISK* dir, 
-                        char* filespec, ZZIP_DISK_ENTRY* after,
-                       zzip_fnmatch_fn_t compare, int flags) {
-    return zzip_disk_findmatch(dir->disk, filespec, after, compare, flags); }
-#else
-#define zzip_mem_disk_findfile(__dir,__name,__after,__compare) \
-            zzip_disk_findfile((__dir)->disk,(__name),(__after), \
-                                                    (__compare))
-#define zzip_mem_disk_findmatch(__dir,__spec,__after,__compare,__flags) \
-            zzip_disk_findmatch((__dir)->disk,(__spec),(__after), \
-                                           (__compare),(__flags))
-#endif
+                        char* filespec, ZZIP_MEM_ENTRY* after,
+                       zzip_fnmatch_fn_t compare, int flags);
 
-#ifdef USE_INLINE
-_zzip_inline ZZIP_DISK_FILE* _zzip_new
-zzip_mem_disk_entry_fopen (ZZIP_MEM_DISK* dir, ZZIP_DISK_ENTRY* entry) {
-    return zzip_disk_entry_fopen(dir->disk, entry); }
-_zzip_inline ZZIP_DISK_FILE* _zzip_new
-zzip_mem_disk_fopen (ZZIP_MEM_DISK* dir, char* filename) {
-    return zzip_disk_fopen(dir->disk, filename); }
-_zzip_inline _zzip_size_t
+/* named access -------------------------------------------------------- */
+#define zzip_mem_entry_usize(_e_) ((_e_)->zz_usize)
+#define zzip_mem_entry_csize(_e_) ((_e_)->zz_csize)
+#define zzip_mem_entry_data_encrypted(_e_) ZZIP_IS_ENCRYPTED((_e_)->zz_flags)
+#define zzip_mem_entry_data_streamed(_e_) ZZIP_IS_STREAMED((_e_)->zz_flags)
+#define zzip_mem_entry_data_comprlevel(_e_) ((_e_)->zz_compr)
+#define zzip_mem_entry_data_stored(_e_) ((_e_)->zz_compr == ZZIP_IS_STORED)
+#define zzip_mem_entry_data_deflated(_e_) ((_e_)->zz_compr == ZZIP_IS_DEFLATED)
+
+/* zzip_mem_disk_file -------------------------------------------------- */
+
+/* since only the header data is being cached, all the real data
+ * operations are actually the same as in mmapped.h - just fopen makes
+ * access to the header data in memory instead of the zip archive.
+ */
+
+typedef ZZIP_DISK_FILE ZZIP_MEM_DISK_FILE;
+
+ZZIP_MEM_DISK_FILE* _zzip_new
+zzip_mem_entry_fopen (ZZIP_MEM_DISK* dir, ZZIP_MEM_ENTRY* entry);
+ZZIP_MEM_DISK_FILE* _zzip_new
+zzip_mem_disk_fopen (ZZIP_MEM_DISK* dir, char* filename);
+_zzip_size_t
 zzip_mem_disk_fread (void* ptr, _zzip_size_t size, _zzip_size_t nmemb,
-                     ZZIP_DISK_FILE* file) {
-    return zzip_disk_fread(ptr, size, nmemb, file); }
-_zzip_inline int
-zzip_mem_disk_fclose (ZZIP_DISK_FILE* file) {
-    return zzip_disk_fclose(file); }
-_zzip_inline int
-zzip_mem_disk_feof (ZZIP_DISK_FILE* file) {
-    return zzip_disk_feof(file); }
-#else
-#define zzip_mem_disk_entry_fopen(__dir,__entry) \
-            zzip_disk_entry_fopen((__dir)->disk,(__entry))
-
-#define zzip_mem_disk_fopen(__dir,__name) \
-            zzip_disk_fopen((__dir)->disk,(__name))
-
-#define zzip_mem_disk_fread(__ptr,__size,__nmemb,__file) \
-            zzip_disk_fread((__ptr),(__size),(__nmemb),(__file))
-#define zzip_mem_disk_fclose(__file) \
-        zzip_disk_fclose((__file))
-#define zzip_mem_disk_feof(__file) \
-            zzip_disk_feof((__file))
-#endif
+                     ZZIP_MEM_DISK_FILE* file);
+int
+zzip_mem_disk_fclose (ZZIP_MEM_DISK_FILE* file);
+int
+zzip_mem_disk_feof (ZZIP_MEM_DISK_FILE* file);
+
+
+
 
 #endif
index 35679ace51bf4a1bc119cabdafbf0a66d37b6bcb..3fd736c916d4e6b4ff544c7732e5c0f033914999 100644 (file)
 #define _GNU_SOURCE _glibc_developers_are_idiots_to_call_this_gnu_specific_
 #endif
 
+#define _ZZIP_MMAPPED_PRIVATE 1
+
+#include <zlib.h>
+#include <zzip/format.h>
+#include <zzip/fetch.h>
+#include <zzip/__mmap.h>
+
 #include <zzip/mmapped.h>
 #include <stdlib.h>
 #include <sys/stat.h>
 #include <strings.h>
 #endif
 
-#include <zlib.h>
-#include <zzip/format.h>
-#include <zzip/fetch.h>
-#include <zzip/__mmap.h>
 
 #if __STDC_VERSION__+0 > 199900L
 #define ___
@@ -461,19 +464,6 @@ zzip_disk_findmatch(ZZIP_DISK* disk, char* filespec,
 
 /* ====================================================================== */
 
-/**
- * typedef struct zzip_disk_file ZZIP_DISK_FILE;
- */
-struct zzip_disk_file
-{
-    char* buffer;                      /* fopen disk->buffer */
-    char* endbuf;                      /* fopen disk->endbuf */
-    struct zzip_file_header* header;   /* fopen detected header */
-    zzip_size_t avail;                 /* memorized for checks on EOF */
-    z_stream zlib;                     /* for inflated blocks */
-    char* stored;                      /* for stored blocks */
-};
-
 /** => zzip_disk_fopen
  *
  * the ZZIP_DISK_FILE* is rather simple in just encapsulating the
@@ -488,29 +478,31 @@ struct zzip_disk_file
 ZZIP_DISK_FILE* _zzip_restrict
 zzip_disk_entry_fopen (ZZIP_DISK* disk, ZZIP_DISK_ENTRY* entry)
 {
-    ZZIP_DISK_FILE* file = malloc(sizeof(ZZIP_DISK_FILE));
+    /* keep this in sync with zzip_mem_entry_fopen */
+    struct zzip_file_header* header = 
+       zzip_disk_entry_to_file_header (disk, entry);
+    if (! header) return 0;
+    ___ ZZIP_DISK_FILE* file = malloc(sizeof(ZZIP_DISK_FILE));
     if (! file) return file;
     file->buffer = disk->buffer;
     file->endbuf = disk->endbuf;
-    file->header = zzip_disk_entry_to_file_header (disk, entry);
-    if (! file->header) { free (file); return 0; }
-    file->avail = zzip_file_header_usize (file->header);
+    file->avail = zzip_file_header_usize (header);
 
-    if (! file->avail || zzip_file_header_data_stored (file->header))
-    { file->stored = zzip_file_header_to_data (file->header); return file; }
+    if (! file->avail || zzip_file_header_data_stored (header))
+    { file->stored = zzip_file_header_to_data (header); return file; }
 
     file->stored = 0;
     file->zlib.opaque = 0;
     file->zlib.zalloc = Z_NULL;
     file->zlib.zfree = Z_NULL;
-    file->zlib.avail_in = zzip_file_header_csize (file->header);
-    file->zlib.next_in = zzip_file_header_to_data (file->header);
+    file->zlib.avail_in = zzip_file_header_csize (header);
+    file->zlib.next_in = zzip_file_header_to_data (header);
 
-    if (! zzip_file_header_data_deflated (file->header) ||
+    if (! zzip_file_header_data_deflated (header) ||
        inflateInit2 (& file->zlib, -MAX_WBITS) != Z_OK)
     { free (file); return 0; }
 
-    return file;
+    return file; ____;
 }
 
 /** openening a file part wrapped within a (mmapped) zip archive
index cd7c7389db3cee5b9d762621b96cfc024db1a28c..f27869f7606783d4b511b25c934748ef325e2608 100644 (file)
@@ -19,7 +19,7 @@
 
 typedef struct zzip_disk_file  ZZIP_DISK_FILE;
 typedef struct zzip_disk       ZZIP_DISK;
-typedef struct zzip_disk_entry ZZIP_DISK_ENTRY;
+/*  def struct zzip_disk_entry ZZIP_DISK_ENTRY; */
 
 /* we expose this structure so third party applications can augment
  * on them. The mmapped zip access usually just needs the two pointers
@@ -100,5 +100,19 @@ zzip_disk_fclose (ZZIP_DISK_FILE* file);
 int
 zzip_disk_feof (ZZIP_DISK_FILE* file);
 
+#ifdef _ZZIP_MMAPPED_PRIVATE
+/**
+ * typedef struct zzip_disk_file ZZIP_DISK_FILE;
+ */
+struct zzip_disk_file
+{
+    char* buffer;                      /* fopen disk->buffer */
+    char* endbuf;                      /* fopen disk->endbuf */
+    zzip_size_t avail;                 /* memorized for checks on EOF */
+    z_stream zlib;                     /* for inflated blocks */
+    char* stored;                      /* for stored blocks */
+};
+#endif
+
 #endif
 
index dc9298472d96ef1c2934052bdf1e27ebce3feb6e..c1c0cd46acadd8efed4e2e40f83ab039b565b408 100644 (file)
@@ -32,5 +32,16 @@ typedef       _zzip_off_t       zzip_off_t;
 typedef       _zzip_size_t      zzip_size_t;
 typedef       _zzip_ssize_t     zzip_ssize_t;
 
+/* in <zzip/format.h> */
+typedef struct zzip_disk64_trailer ZZIP_DISK64_TRAILER;
+typedef struct zzip_disk_trailer ZZIP_DISK_TRAILER;
+typedef struct zzip_file_trailer ZZIP_FILE_TRAILER;
+typedef struct zzip_root_dirent  ZZIP_ROOT_DIRENT;
+typedef struct zzip_file_header ZZIP_FILE_HEADER;
+typedef struct zzip_disk_entry  ZZIP_DISK_ENTRY;
+typedef struct zzip_extra_block ZZIP_EXTRA_BLOCK;
+
+
+
 #endif
 
index 9d9e8417368922e9498739d8b3c0a5fac255346e..083f8288f8ae23f7d4ba3b87662d50da171b4800 100644 (file)
@@ -1,7 +1,7 @@
 %define lib   lib010
 Summary:      ZZipLib - libZ-based ZIP-access Library
 Name:         zziplib
-Version:      0.13.43
+Version:      0.13.44
 Release:      1.suse92
 Serial:       1
 Copyright:    LGPL