Fossil SCM

Update the ZIP archiver to include date information. Provide a function that constructs a ZIP archive from manifest.

drh 2007-07-31 20:20 trunk
Commit dead090c0bd601124619cbde91215e9a873972bc
2 files changed +97 -6 +3 -6
+97 -6
--- src/zip.c
+++ src/zip.c
@@ -46,27 +46,57 @@
4646
** Variables in which to accumulate a growing ZIP archive.
4747
*/
4848
static Blob body; /* The body of the ZIP archive */
4949
static Blob toc; /* The table of contents */
5050
static int nEntry; /* Number of files */
51
+static int dosTime; /* DOS-format time */
52
+static int dosDate; /* DOS-format date */
5153
5254
/*
5355
** Initialize a new ZIP archive.
5456
*/
5557
void zip_open(void){
5658
blob_zero(&body);
5759
blob_zero(&toc);
5860
nEntry = 0;
61
+ dosTime = 0;
62
+ dosDate = 0;
63
+}
64
+
65
+/*
66
+** Set the date and time values from an ISO8601 date string.
67
+*/
68
+void zip_set_timedate_from_str(const char *zDate){
69
+ int y, m, d;
70
+ int H, M, S;
71
+
72
+ y = atoi(zDate);
73
+ m = atoi(&zDate[5]);
74
+ d = atoi(&zDate[8]);
75
+ H = atoi(&zDate[11]);
76
+ M = atoi(&zDate[14]);
77
+ S = atoi(&zDate[17]);
78
+ dosTime = (H<<11) + (M<<5) + S;
79
+ dosDate = ((y-1980)<<9) + (m<<5) + d;
80
+}
81
+
82
+/*
83
+** Set the date and time from a julian day number.
84
+*/
85
+void zip_set_timedate(double rDate){
86
+ char *zDate = db_text(0, "SELECT datetime(%.17g)", rDate);
87
+ zip_set_timedate_from_str(zDate);
88
+ free(zDate);
5989
}
6090
6191
/*
6292
** Append a single file to a growing ZIP archive.
6393
**
6494
** pFile is the file to be appended. zName is the name
6595
** that the file should be saved as.
6696
*/
67
-int zip_add_file(const char *zName, const Blob *pFile){
97
+void zip_add_file(const char *zName, const Blob *pFile){
6898
z_stream stream;
6999
int nameLen;
70100
int skip;
71101
int toOut;
72102
int iStart;
@@ -83,12 +113,12 @@
83113
nameLen = strlen(zName);
84114
put32(&zHdr[0], 0x04034b50);
85115
put16(&zHdr[4], 0x0014);
86116
put16(&zHdr[6], 0);
87117
put16(&zHdr[8], 8);
88
- put16(&zHdr[10], 0);
89
- put16(&zHdr[12], 0);
118
+ put16(&zHdr[10], dosTime);
119
+ put16(&zHdr[12], dosDate);
90120
put16(&zHdr[26], nameLen);
91121
put16(&zHdr[28], 0);
92122
93123
/* Write the header and filename.
94124
*/
@@ -154,12 +184,12 @@
154184
put32(&zBuf[0], 0x02014b50);
155185
put16(&zBuf[4], 0x0317);
156186
put16(&zBuf[6], 0x0014);
157187
put16(&zBuf[8], 0);
158188
put16(&zBuf[10], 0x0008);
159
- put16(&zBuf[12], 0);
160
- put16(&zBuf[14], 0);
189
+ put16(&zBuf[12], dosTime);
190
+ put16(&zBuf[14], dosDate);
161191
put32(&zBuf[16], iCRC);
162192
put32(&zBuf[20], nByteCompr);
163193
put32(&zBuf[24], nByte);
164194
put16(&zBuf[28], nameLen);
165195
put16(&zBuf[30], 0);
@@ -175,11 +205,11 @@
175205
176206
177207
/*
178208
** Write the ZIP archive into the given BLOB.
179209
*/
180
-int zip_close(Blob *pZip){
210
+void zip_close(Blob *pZip){
181211
int iTocStart;
182212
int iTocEnd;
183213
char zBuf[30];
184214
185215
iTocStart = blob_size(&body);
@@ -223,5 +253,66 @@
223253
blob_reset(&file);
224254
}
225255
zip_close(&zip);
226256
blob_write_to_file(&zip, g.argv[2]);
227257
}
258
+
259
+/*
260
+** Given the RID for a manifest, construct a ZIP archive containing
261
+** all files in the corresponding baseline.
262
+**
263
+** If RID is for an object that is not a real manifest, then the
264
+** resulting ZIP archive contains a single file which is the RID
265
+** object.
266
+**
267
+** If the RID object does not exist in the repository, then
268
+** pZip is zeroed.
269
+*/
270
+void zip_of_baseline(int rid, Blob *pZip){
271
+ int i;
272
+ Blob mfile, file;
273
+ Manifest m;
274
+
275
+ content_get(rid, &mfile);
276
+ if( blob_size(&mfile)==0 ){
277
+ blob_zero(pZip);
278
+ return;
279
+ }
280
+ blob_zero(&file);
281
+ blob_copy(&file, &mfile);
282
+ zip_open();
283
+ if( manifest_parse(&m, &mfile) ){
284
+ zip_set_timedate(m.rDate);
285
+ zip_add_file("manifest", &file);
286
+ blob_reset(&file);
287
+ for(i=0; i<m.nFile; i++){
288
+ int fid = uuid_to_rid(m.aFile[i].zUuid, 0);
289
+ if( fid ){
290
+ content_get(fid, &file);
291
+ zip_add_file(m.aFile[i].zName, &file);
292
+ blob_reset(&file);
293
+ }
294
+ }
295
+ manifest_clear(&m);
296
+ }else{
297
+ blob_reset(&mfile);
298
+ blob_reset(&file);
299
+ }
300
+ zip_close(pZip);
301
+}
302
+
303
+/*
304
+** COMMAND: test-baseline-zip
305
+**
306
+** Generate a ZIP archive for a specified baseline.
307
+*/
308
+void baseline_zip_cmd(void){
309
+ int rid;
310
+ Blob zip;
311
+ if( g.argc!=4 ){
312
+ usage("UUID ZIPFILE");
313
+ }
314
+ db_must_be_within_tree();
315
+ rid = name_to_rid(g.argv[2]);
316
+ zip_of_baseline(rid, &zip);
317
+ blob_write_to_file(&zip, g.argv[3]);
318
+}
228319
--- src/zip.c
+++ src/zip.c
@@ -46,27 +46,57 @@
46 ** Variables in which to accumulate a growing ZIP archive.
47 */
48 static Blob body; /* The body of the ZIP archive */
49 static Blob toc; /* The table of contents */
50 static int nEntry; /* Number of files */
 
 
51
52 /*
53 ** Initialize a new ZIP archive.
54 */
55 void zip_open(void){
56 blob_zero(&body);
57 blob_zero(&toc);
58 nEntry = 0;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
59 }
60
61 /*
62 ** Append a single file to a growing ZIP archive.
63 **
64 ** pFile is the file to be appended. zName is the name
65 ** that the file should be saved as.
66 */
67 int zip_add_file(const char *zName, const Blob *pFile){
68 z_stream stream;
69 int nameLen;
70 int skip;
71 int toOut;
72 int iStart;
@@ -83,12 +113,12 @@
83 nameLen = strlen(zName);
84 put32(&zHdr[0], 0x04034b50);
85 put16(&zHdr[4], 0x0014);
86 put16(&zHdr[6], 0);
87 put16(&zHdr[8], 8);
88 put16(&zHdr[10], 0);
89 put16(&zHdr[12], 0);
90 put16(&zHdr[26], nameLen);
91 put16(&zHdr[28], 0);
92
93 /* Write the header and filename.
94 */
@@ -154,12 +184,12 @@
154 put32(&zBuf[0], 0x02014b50);
155 put16(&zBuf[4], 0x0317);
156 put16(&zBuf[6], 0x0014);
157 put16(&zBuf[8], 0);
158 put16(&zBuf[10], 0x0008);
159 put16(&zBuf[12], 0);
160 put16(&zBuf[14], 0);
161 put32(&zBuf[16], iCRC);
162 put32(&zBuf[20], nByteCompr);
163 put32(&zBuf[24], nByte);
164 put16(&zBuf[28], nameLen);
165 put16(&zBuf[30], 0);
@@ -175,11 +205,11 @@
175
176
177 /*
178 ** Write the ZIP archive into the given BLOB.
179 */
180 int zip_close(Blob *pZip){
181 int iTocStart;
182 int iTocEnd;
183 char zBuf[30];
184
185 iTocStart = blob_size(&body);
@@ -223,5 +253,66 @@
223 blob_reset(&file);
224 }
225 zip_close(&zip);
226 blob_write_to_file(&zip, g.argv[2]);
227 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
228
--- src/zip.c
+++ src/zip.c
@@ -46,27 +46,57 @@
46 ** Variables in which to accumulate a growing ZIP archive.
47 */
48 static Blob body; /* The body of the ZIP archive */
49 static Blob toc; /* The table of contents */
50 static int nEntry; /* Number of files */
51 static int dosTime; /* DOS-format time */
52 static int dosDate; /* DOS-format date */
53
54 /*
55 ** Initialize a new ZIP archive.
56 */
57 void zip_open(void){
58 blob_zero(&body);
59 blob_zero(&toc);
60 nEntry = 0;
61 dosTime = 0;
62 dosDate = 0;
63 }
64
65 /*
66 ** Set the date and time values from an ISO8601 date string.
67 */
68 void zip_set_timedate_from_str(const char *zDate){
69 int y, m, d;
70 int H, M, S;
71
72 y = atoi(zDate);
73 m = atoi(&zDate[5]);
74 d = atoi(&zDate[8]);
75 H = atoi(&zDate[11]);
76 M = atoi(&zDate[14]);
77 S = atoi(&zDate[17]);
78 dosTime = (H<<11) + (M<<5) + S;
79 dosDate = ((y-1980)<<9) + (m<<5) + d;
80 }
81
82 /*
83 ** Set the date and time from a julian day number.
84 */
85 void zip_set_timedate(double rDate){
86 char *zDate = db_text(0, "SELECT datetime(%.17g)", rDate);
87 zip_set_timedate_from_str(zDate);
88 free(zDate);
89 }
90
91 /*
92 ** Append a single file to a growing ZIP archive.
93 **
94 ** pFile is the file to be appended. zName is the name
95 ** that the file should be saved as.
96 */
97 void zip_add_file(const char *zName, const Blob *pFile){
98 z_stream stream;
99 int nameLen;
100 int skip;
101 int toOut;
102 int iStart;
@@ -83,12 +113,12 @@
113 nameLen = strlen(zName);
114 put32(&zHdr[0], 0x04034b50);
115 put16(&zHdr[4], 0x0014);
116 put16(&zHdr[6], 0);
117 put16(&zHdr[8], 8);
118 put16(&zHdr[10], dosTime);
119 put16(&zHdr[12], dosDate);
120 put16(&zHdr[26], nameLen);
121 put16(&zHdr[28], 0);
122
123 /* Write the header and filename.
124 */
@@ -154,12 +184,12 @@
184 put32(&zBuf[0], 0x02014b50);
185 put16(&zBuf[4], 0x0317);
186 put16(&zBuf[6], 0x0014);
187 put16(&zBuf[8], 0);
188 put16(&zBuf[10], 0x0008);
189 put16(&zBuf[12], dosTime);
190 put16(&zBuf[14], dosDate);
191 put32(&zBuf[16], iCRC);
192 put32(&zBuf[20], nByteCompr);
193 put32(&zBuf[24], nByte);
194 put16(&zBuf[28], nameLen);
195 put16(&zBuf[30], 0);
@@ -175,11 +205,11 @@
205
206
207 /*
208 ** Write the ZIP archive into the given BLOB.
209 */
210 void zip_close(Blob *pZip){
211 int iTocStart;
212 int iTocEnd;
213 char zBuf[30];
214
215 iTocStart = blob_size(&body);
@@ -223,5 +253,66 @@
253 blob_reset(&file);
254 }
255 zip_close(&zip);
256 blob_write_to_file(&zip, g.argv[2]);
257 }
258
259 /*
260 ** Given the RID for a manifest, construct a ZIP archive containing
261 ** all files in the corresponding baseline.
262 **
263 ** If RID is for an object that is not a real manifest, then the
264 ** resulting ZIP archive contains a single file which is the RID
265 ** object.
266 **
267 ** If the RID object does not exist in the repository, then
268 ** pZip is zeroed.
269 */
270 void zip_of_baseline(int rid, Blob *pZip){
271 int i;
272 Blob mfile, file;
273 Manifest m;
274
275 content_get(rid, &mfile);
276 if( blob_size(&mfile)==0 ){
277 blob_zero(pZip);
278 return;
279 }
280 blob_zero(&file);
281 blob_copy(&file, &mfile);
282 zip_open();
283 if( manifest_parse(&m, &mfile) ){
284 zip_set_timedate(m.rDate);
285 zip_add_file("manifest", &file);
286 blob_reset(&file);
287 for(i=0; i<m.nFile; i++){
288 int fid = uuid_to_rid(m.aFile[i].zUuid, 0);
289 if( fid ){
290 content_get(fid, &file);
291 zip_add_file(m.aFile[i].zName, &file);
292 blob_reset(&file);
293 }
294 }
295 manifest_clear(&m);
296 }else{
297 blob_reset(&mfile);
298 blob_reset(&file);
299 }
300 zip_close(pZip);
301 }
302
303 /*
304 ** COMMAND: test-baseline-zip
305 **
306 ** Generate a ZIP archive for a specified baseline.
307 */
308 void baseline_zip_cmd(void){
309 int rid;
310 Blob zip;
311 if( g.argc!=4 ){
312 usage("UUID ZIPFILE");
313 }
314 db_must_be_within_tree();
315 rid = name_to_rid(g.argv[2]);
316 zip_of_baseline(rid, &zip);
317 blob_write_to_file(&zip, g.argv[3]);
318 }
319
+3 -6
--- todo.txt
+++ todo.txt
@@ -60,25 +60,22 @@
6060
Information available in the mlink table. Hyperlinks to
6161
the finfo page for each file.
6262
+ Hyperlinks to diff all files in this version against any
6363
of the named decendents or ancestors. The unified_diff()
6464
function will compute a unified diff given to file blobs.
65
+ + Add a link that will download a ZIP archive containing the
66
+ complete baseline. Use zip_of_baseline() function in
67
+ zip.c to construct the ZIP archive.
6568
6669
* A new webpage: "finfo" Information about a particular file
6770
given its name.
6871
6972
+ All historical changes to this file with version number,
7073
user, and comment, and hyperlink to the vinfo page for
7174
the version. Information available from the minfo table.
7275
+ Hyperlinks for diffing consecutive versions of the file.
7376
74
- * Given any version uuid, construct a ZIP archive that contains
75
- the complete content for that version. Feature should be
76
- callable from the command-line or from the www interface.
77
- Perhaps a hyperlink on the vinfo page to download the ZIP archive
78
- for any version.
79
-
8077
* Timeline enhanced so that you can specify a range of dates.
8178
8279
* The /xfer handler (for push, pull, and clone) does not do
8380
delta compression. This results in excess bandwidth usage.
8481
There are some code in xfer.c that are sketches of ideas on
8582
--- todo.txt
+++ todo.txt
@@ -60,25 +60,22 @@
60 Information available in the mlink table. Hyperlinks to
61 the finfo page for each file.
62 + Hyperlinks to diff all files in this version against any
63 of the named decendents or ancestors. The unified_diff()
64 function will compute a unified diff given to file blobs.
 
 
 
65
66 * A new webpage: "finfo" Information about a particular file
67 given its name.
68
69 + All historical changes to this file with version number,
70 user, and comment, and hyperlink to the vinfo page for
71 the version. Information available from the minfo table.
72 + Hyperlinks for diffing consecutive versions of the file.
73
74 * Given any version uuid, construct a ZIP archive that contains
75 the complete content for that version. Feature should be
76 callable from the command-line or from the www interface.
77 Perhaps a hyperlink on the vinfo page to download the ZIP archive
78 for any version.
79
80 * Timeline enhanced so that you can specify a range of dates.
81
82 * The /xfer handler (for push, pull, and clone) does not do
83 delta compression. This results in excess bandwidth usage.
84 There are some code in xfer.c that are sketches of ideas on
85
--- todo.txt
+++ todo.txt
@@ -60,25 +60,22 @@
60 Information available in the mlink table. Hyperlinks to
61 the finfo page for each file.
62 + Hyperlinks to diff all files in this version against any
63 of the named decendents or ancestors. The unified_diff()
64 function will compute a unified diff given to file blobs.
65 + Add a link that will download a ZIP archive containing the
66 complete baseline. Use zip_of_baseline() function in
67 zip.c to construct the ZIP archive.
68
69 * A new webpage: "finfo" Information about a particular file
70 given its name.
71
72 + All historical changes to this file with version number,
73 user, and comment, and hyperlink to the vinfo page for
74 the version. Information available from the minfo table.
75 + Hyperlinks for diffing consecutive versions of the file.
76
 
 
 
 
 
 
77 * Timeline enhanced so that you can specify a range of dates.
78
79 * The /xfer handler (for push, pull, and clone) does not do
80 delta compression. This results in excess bandwidth usage.
81 There are some code in xfer.c that are sketches of ideas on
82

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button