1 unit ZipUtils;
2
3 { ziputils.pas - IO on .zip files using zlib
4 - definitions, declarations and routines used by both
5 zip.pas and unzip.pas
6 The file IO is implemented here.
7
8 based on work by Gilles Vollant
9
10 March 23th, 2000,
11 Copyright (C) 2000 Jacques Nomssi Nzali }
12
13 interface
14
15 {$undef UseStream}
16
17 {$ifdef WIN32}
18 {$define Delphi}
19 {$ifdef UseStream}
20 {$define Streams}
21 {$endif}
22 {$endif}
23
24 //uses Classes, SysUtils;
25
26 { -------------------------------------------------------------- }
27 {$ifdef Streams}
28 type
29 FILEptr = TFileStream;
30 {$else}
31 type
32 FILEptr = ^file;
33 {$endif}
34
35 type
36 seek_mode = (SEEK_SET, SEEK_CUR, SEEK_END);
37 open_mode = (fopenread, fopenwrite, fappendwrite);
38
fopennull39 function fopen(filename: PChar; mode: open_mode): FILEptr;
40
41 procedure fclose(fp: FILEptr);
42
fseeknull43 function fseek(fp: FILEptr; recPos: longint; mode: seek_mode): longint;
44
freadnull45 function fread(buf: pointer; recSize: longint; recCount: longint; fp: FILEptr): longint;
46
fwritenull47 function fwrite(buf: pointer; recSize: longint; recCount: longint; fp: FILEptr): longint;
48
ftellnull49 function ftell(fp: FILEptr): longint; { ZIP }
50
feofnull51 function feof(fp: FILEptr): longint; { MiniZIP }
52
53 { ------------------------------------------------------------------- }
54
55 type
56 zipFile = pointer;
57 unzFile = pointer;
58
59 type
60 z_off_t = longint;
61
62 { tm_zip contain date/time info }
63 type
64 tm_zip = record
65 tm_sec: longint; { seconds after the minute - [0,59] }
66 tm_min: longint; { minutes after the hour - [0,59] }
67 tm_hour: longint; { hours since midnight - [0,23] }
68 tm_mday: longint; { day of the month - [1,31] }
69 tm_mon: longint; { months since January - [0,11] }
70 tm_year: longint; { years - [1980..2044] }
71 end;
72
73 tm_unz = tm_zip;
74
75 const
76 Z_BUFSIZE = (16384);
77 Z_MAXFILENAMEINZIP = (256);
78
79 const
80 CENTRALHEADERMAGIC = $02014b50;
81
82 const
83 SIZECENTRALDIRITEM = $2e;
84 SIZEZIPLOCALHEADER = $1e;
85
86 const
87 Paszip_copyright: PChar = ' Paszip Copyright 2000 Jacques Nomssi Nzali ';
88
89 implementation
90
91 {$ifdef Streams}
92 { ---------------------------------------------------------------- }
93
fopennull94 function fopen(filename: PChar; mode: open_mode): FILEptr;
95 var
96 fp: FILEptr;
97 begin
98 fp := nil;
99 try
100 case mode of
101 fopenread: fp := TFileStream.Create(strpas(filename), fmOpenRead or fmShareDenyWrite);
102 fopenwrite: fp := TFileStream.Create(strpas(filename), fmCreate);
103 fappendwrite:
104 begin
105 fp := TFileStream.Create(strpas(filename), fmOpenReadWrite);
106 fp.Seek(soFromEnd, 0);
107 end;
108 end;
109 except
110 on EFOpenError do
111 fp := nil;
112 end;
113 fopen := fp;
114 end;
115
116 procedure fclose(fp: FILEptr);
117 begin
118 fp.Free;
119 end;
120
freadnull121 function fread(buf: pointer; recSize: longint; recCount: longint; fp: FILEptr): longint;
122 var
123 totalSize, readcount: longint;
124 begin
125 if Assigned(buf) then
126 begin
127 totalSize := recCount * longint(recSize);
128 readCount := fp.Read(buf^, totalSize);
129 if (readcount <> totalSize) then
130 fread := readcount div recSize
131 else
132 fread := recCount;
133 end
134 else
135 fread := 0;
136 end;
137
fwritenull138 function fwrite(buf: pointer; recSize: longint; recCount: longint; fp: FILEptr): longint;
139 var
140 totalSize, written: longint;
141 begin
142 if Assigned(buf) then
143 begin
144 totalSize := recCount * longint(recSize);
145 written := fp.Write(buf^, totalSize);
146 if (written <> totalSize) then
147 fwrite := written div recSize
148 else
149 fwrite := recCount;
150 end
151 else
152 fwrite := 0;
153 end;
154
fseeknull155 function fseek(fp: FILEptr; recPos: longint; mode: seek_mode): int;
156 const
157 fsmode: array[seek_mode] of word = (soFromBeginning, soFromCurrent, soFromEnd);
158 begin
159 fp.Seek(recPos, fsmode[mode]);
160 fseek := 0; { = 0 for success }
161 end;
162
ftellnull163 function ftell(fp: FILEptr): longint;
164 begin
165 ftell := fp.Position;
166 end;
167
feofnull168 function feof(fp: FILEptr): longint;
169 begin
170 feof := 0;
171 if Assigned(fp) then
172 if fp.Position = fp.Size then
173 feof := 1
174 else
175 feof := 0;
176 end;
177
178 {$else}
179 { ---------------------------------------------------------------- }
180
fopennull181 function fopen(filename : PChar; mode : open_mode) : FILEptr;
182 var
183 fp : FILEptr;
184 OldFileMode : byte;
185 begin
186 fp := NIL;
187 OldFileMode := FileMode;
188
189 GetMem(fp, SizeOf(file));
190 Assign(fp^, strpas(filename));
191 {$push}{$i-}
192 Case mode of
193 fopenread:
194 begin
195 FileMode := 0;
196 Reset(fp^, 1);
197 end;
198 fopenwrite:
199 begin
200 FileMode := 1;
201 ReWrite(fp^, 1);
202 end;
203 fappendwrite :
204 begin
205 FileMode := 2;
206 Reset(fp^, 1);
207 Seek(fp^, FileSize(fp^));
208 end;
209 end;
210 FileMode := OldFileMode;
211 {$pop}
212 if IOresult<>0 then
213 begin
214 FreeMem(fp, SizeOf(file));
215 fp := NIL;
216 end;
217
218 fopen := fp;
219 end;
220
221 procedure fclose(fp : FILEptr);
222 begin
223 if Assigned(fp) then
224 begin
225 {$push}{$i-}
226 system.close(fp^);
227 {$pop}
228 if IOresult=0 then;
229 FreeMem(fp, SizeOf(file));
230 end;
231 end;
232
freadnull233 function fread(buf : pointer;
234 recSize : LongInt;
235 recCount : LongInt;
236 fp : FILEptr) : LongInt;
237 var
238 totalSize, readcount : LongInt;
239 begin
240 if Assigned(buf) then
241 begin
242 totalSize := recCount * LongInt(recSize);
243 {$push}{$i-}
244 system.BlockRead(fp^, buf^, totalSize, readcount);
245 if (readcount <> totalSize) then
246 fread := readcount div recSize
247 else
248 fread := recCount;
249 {$pop}
250 end
251 else
252 fread := 0;
253 end;
254
fwritenull255 function fwrite(buf : pointer;
256 recSize : LongInt;
257 recCount : LongInt;
258 fp : FILEptr) : LongInt;
259 var
260 totalSize, written : LongInt;
261 begin
262 if Assigned(buf) then
263 begin
264 totalSize := recCount * LongInt(recSize);
265 {$push}{$i-}
266 system.BlockWrite(fp^, buf^, totalSize, written);
267 if (written <> totalSize) then
268 fwrite := written div recSize
269 else
270 fwrite := recCount;
271 {$pop}
272 end
273 else
274 fwrite := 0;
275 end;
276
fseeknull277 function fseek(fp : FILEptr;
278 recPos : LongInt;
279 mode : seek_mode) : longint;
280 begin
281 {$push}{$i-}
282 case mode of
283 SEEK_SET : system.Seek(fp^, recPos);
284 SEEK_CUR : system.Seek(fp^, FilePos(fp^)+recPos);
285 SEEK_END : system.Seek(fp^, FileSize(fp^)-1-recPos); { ?? check }
286 end;
287 {$pop}
288 fseek := IOresult; { = 0 for success }
289 end;
290
ftellnull291 function ftell(fp : FILEptr) : LongInt;
292 begin
293 ftell := FilePos(fp^);
294 end;
295
feofnull296 function feof(fp : FILEptr) : LongInt;
297 begin
298 feof := 0;
299 if Assigned(fp) then
300 if eof(fp^) then
301 feof := 1
302 else
303 feof := 0;
304 end;
305
306 {$endif}
307 { ---------------------------------------------------------------- }
308
309 end.
310