Add valid member to struct zip_stat to specify which members are valid.

--HG--
branch : HEAD
diff --git a/lib/zip.h b/lib/zip.h
index 4a764de..58b1c3e 100644
--- a/lib/zip.h
+++ b/lib/zip.h
@@ -171,13 +171,23 @@
     ZIP_SOURCE_FREE	/* cleanup and free resources */
 };
 
+#define ZIP_STAT_NAME			0x0001
+#define ZIP_STAT_INDEX			0x0002
+#define ZIP_STAT_SIZE			0x0004
+#define ZIP_STAT_COMP_SIZE		0x0008
+#define ZIP_STAT_MTIME			0x0010
+#define ZIP_STAT_CRC			0x0020
+#define ZIP_STAT_COMP_METHOD		0x0040
+#define ZIP_STAT_ENCRYPTION_METHOD	0x0080
+
 struct zip_stat {
+    zip_uint64_t valid;			/* which fields have valid values */
     const char *name;			/* name of the file */
     zip_uint64_t index;			/* index within archive */
-    zip_uint32_t crc;			/* crc of file data */
-    time_t mtime;			/* modification time */
     zip_uint64_t size;			/* size of file (uncompressed) */
     zip_uint64_t comp_size;		/* size of file (compressed) */
+    time_t mtime;			/* modification time */
+    zip_uint32_t crc;			/* crc of file data */
     zip_uint16_t comp_method;		/* compression method used */
     zip_uint16_t encryption_method;	/* encryption method used */
 };
diff --git a/lib/zip_source_buffer.c b/lib/zip_source_buffer.c
index bd81894..eee9138 100644
--- a/lib/zip_source_buffer.c
+++ b/lib/zip_source_buffer.c
@@ -126,6 +126,10 @@
 	    zip_stat_init(st);
 	    st->mtime = z->mtime;
 	    st->size = z->end - z->data;
+	    st->comp_method = ZIP_CM_STORE;
+	    st->encryption_method = ZIP_EM_NONE;
+	    st->valid = ZIP_STAT_MTIME|ZIP_STAT_SIZE
+		|ZIP_STAT_COMP_METHOD|ZIP_STAT_ENCRYPTION_METHOD;
 	    
 	    return sizeof(*st);
 	}
diff --git a/lib/zip_source_deflate.c b/lib/zip_source_deflate.c
index b289500..22db543 100644
--- a/lib/zip_source_deflate.c
+++ b/lib/zip_source_deflate.c
@@ -45,7 +45,6 @@
     int eof;
     int mem_level;
     zip_uint64_t size;
-    zip_uint32_t crc;
     char buffer[BUFSIZE];
     z_stream zstr;
 };
@@ -142,7 +141,6 @@
 		    /* XXX: check against stat of src? */
 		}
 		else {
-		    ctx->crc = crc32(ctx->crc, (Bytef *)ctx->buffer, n);
 		    ctx->zstr.next_in = (Bytef *)ctx->buffer;
 		    ctx->zstr.avail_in = n;
 		}
@@ -291,12 +289,13 @@
 	    st = (struct zip_stat *)data;
 
 	    st->comp_method = ZIP_CM_DEFLATE;
+	    st->valid |= ZIP_STAT_COMP_METHOD;
 	    if (ctx->eof) {
 		st->comp_size = ctx->size;
-		st->crc = ctx->crc;
+		st->valid |= ZIP_STAT_COMP_SIZE;
 	    }
 	    else
-		st->comp_size = -1;
+		st->valid &= ~ZIP_STAT_COMP_SIZE;
 	}
 	return 0;
 
diff --git a/lib/zip_source_filep.c b/lib/zip_source_filep.c
index a3ac7e3..5b7e0c0 100644
--- a/lib/zip_source_filep.c
+++ b/lib/zip_source_filep.c
@@ -190,7 +190,7 @@
 	    if (len < sizeof(z->st))
 		return -1;
 
-	    if (z->st.size != -1)
+	    if (z->st.valid != 0)
 		memcpy(data, &z->st, sizeof(z->st));
 	    else {
 		struct zip_stat *st;
@@ -212,10 +212,15 @@
 		
 		zip_stat_init(st);
 		st->mtime = fst.st_mtime;
-		if (z->len != -1)
+		st->valid |= ZIP_STAT_MTIME;
+		if (z->len != -1) {
 		    st->size = z->len;
-		else if ((fst.st_mode&S_IFMT) == S_IFREG)
+		    st->valid |= ZIP_STAT_SIZE;
+		}
+		else if ((fst.st_mode&S_IFMT) == S_IFREG) {
 		    st->size = fst.st_size;
+		    st->valid |= ZIP_STAT_SIZE;
+		}
 	    }
 	    return sizeof(z->st);
 	}
diff --git a/lib/zip_source_pkware.c b/lib/zip_source_pkware.c
index 351ea3a..36424cd 100644
--- a/lib/zip_source_pkware.c
+++ b/lib/zip_source_pkware.c
@@ -218,7 +218,8 @@
 	    st = (struct zip_stat *)data;
 
 	    st->encryption_method = ZIP_EM_NONE;
-	    if (st->comp_size > 0)
+	    st->valid |= ZIP_STAT_ENCRYPTION_METHOD;
+	    if (st->valid & ZIP_STAT_COMP_SIZE)
 		st->comp_size -= HEADERLEN;
 	}
 	return 0;
diff --git a/lib/zip_stat_index.c b/lib/zip_stat_index.c
index 17bc0a0..e4d84a2 100644
--- a/lib/zip_stat_index.c
+++ b/lib/zip_stat_index.c
@@ -1,6 +1,6 @@
 /*
   zip_stat_index.c -- get information about file by index
-  Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner
+  Copyright (C) 1999-2009 Dieter Baron and Thomas Klausner
 
   This file is part of libzip, a library to manipulate ZIP archives.
   The authors can be contacted at <libzip@nih.at>
@@ -54,8 +54,8 @@
 
     if ((flags & ZIP_FL_UNCHANGED) == 0
 	&& ZIP_ENTRY_DATA_CHANGED(za->entry+index)) {
-	if (za->entry[index].source->f(za->entry[index].source->ud,
-				     st, sizeof(*st), ZIP_SOURCE_STAT) < 0) {
+	if (zip_source_call(za->entry[index].source,
+			    st, sizeof(*st), ZIP_SOURCE_STAT) < 0) {
 	    _zip_error_set(&za->error, ZIP_ER_CHANGED, 0);
 	    return -1;
 	}
@@ -65,7 +65,9 @@
 	    _zip_error_set(&za->error, ZIP_ER_INVAL, 0);
 	    return -1;
 	}
-	
+
+	zip_stat_init(st);
+
 	st->crc = za->cdir->entry[index].crc;
 	st->size = za->cdir->entry[index].uncomp_size;
 	st->mtime = za->cdir->entry[index].last_mod;
@@ -81,11 +83,13 @@
 	}
 	else
 	    st->encryption_method = ZIP_EM_NONE;
-	/* st->bitflags = za->cdir->entry[index].bitflags; */
+	st->valid = ZIP_STAT_CRC|ZIP_STAT_SIZE|ZIP_STAT_MTIME
+	    |ZIP_STAT_COMP_SIZE|ZIP_STAT_COMP_METHOD|ZIP_STAT_ENCRYPTION_METHOD;
     }
 
     st->index = index;
     st->name = name;
+    st->valid |= ZIP_STAT_INDEX|ZIP_STAT_NAME;
     
     return 0;
 }
diff --git a/lib/zip_stat_init.c b/lib/zip_stat_init.c
index 50cc113..d17613b 100644
--- a/lib/zip_stat_init.c
+++ b/lib/zip_stat_init.c
@@ -1,6 +1,6 @@
 /*
   zip_stat_init.c -- initialize struct zip_stat.
-  Copyright (C) 2006-2007 Dieter Baron and Thomas Klausner
+  Copyright (C) 2006-2009 Dieter Baron and Thomas Klausner
 
   This file is part of libzip, a library to manipulate ZIP archives.
   The authors can be contacted at <libzip@nih.at>
@@ -40,12 +40,13 @@
 ZIP_EXTERN void
 zip_stat_init(struct zip_stat *st)
 {
+    st->valid = 0;
     st->name = NULL;
     st->index = ZIP_UINT64_MAX;
     st->crc = 0;
     st->mtime = (time_t)-1;
-    st->size = -1;
-    st->comp_size = -1;
+    st->size = 0;
+    st->comp_size = 0;
     st->comp_method = ZIP_CM_STORE;
     st->encryption_method = ZIP_EM_NONE;
 }