332 lines
6.6 KiB
ObjectPascal
332 lines
6.6 KiB
ObjectPascal
Unit ziputils;
|
|
|
|
{ ziputils.pas - IO on .zip files using zlib
|
|
- definitions, declarations and routines used by both
|
|
zip.pas and unzip.pas
|
|
The file IO is implemented here.
|
|
|
|
based on work by Gilles Vollant
|
|
|
|
March 23th, 2000,
|
|
Copyright (C) 2000 Jacques Nomssi Nzali }
|
|
|
|
interface
|
|
|
|
{$undef UseStream}
|
|
{$ifdef WIN32}
|
|
{$define Delphi}
|
|
{$ifdef UseStream}
|
|
{$define Streams}
|
|
{$endif}
|
|
{$endif}
|
|
|
|
uses
|
|
{$ifdef Delphi}
|
|
classes, SysUtils,
|
|
{$endif}
|
|
zutil;
|
|
|
|
{ -------------------------------------------------------------- }
|
|
{$ifdef Streams}
|
|
type
|
|
FILEptr = TFileStream;
|
|
{$else}
|
|
type
|
|
FILEptr = ^file;
|
|
{$endif}
|
|
type
|
|
seek_mode = (SEEK_SET, SEEK_CUR, SEEK_END);
|
|
open_mode = (fopenread, fopenwrite, fappendwrite);
|
|
|
|
function fopen(filename : PChar; mode : open_mode) : FILEptr;
|
|
|
|
procedure fclose(fp : FILEptr);
|
|
|
|
function fseek(fp : FILEptr; recPos : uLong; mode : seek_mode) : int;
|
|
|
|
function fread(buf : voidp; recSize : uInt;
|
|
recCount : uInt; fp : FILEptr) : uInt;
|
|
|
|
function fwrite(buf : voidp; recSize : uInt;
|
|
recCount : uInt; fp : FILEptr) : uInt;
|
|
|
|
function ftell(fp : FILEptr) : uLong; { ZIP }
|
|
|
|
function feof(fp : FILEptr) : uInt; { MiniZIP }
|
|
|
|
{ ------------------------------------------------------------------- }
|
|
|
|
type
|
|
zipFile = voidp;
|
|
unzFile = voidp;
|
|
type
|
|
z_off_t = long;
|
|
|
|
{ tm_zip contain date/time info }
|
|
type
|
|
tm_zip = record
|
|
tm_sec : uInt; { seconds after the minute - [0,59] }
|
|
tm_min : uInt; { minutes after the hour - [0,59] }
|
|
tm_hour : uInt; { hours since midnight - [0,23] }
|
|
tm_mday : uInt; { day of the month - [1,31] }
|
|
tm_mon : uInt; { months since January - [0,11] }
|
|
tm_year : uInt; { years - [1980..2044] }
|
|
end;
|
|
|
|
tm_unz = tm_zip;
|
|
|
|
const
|
|
Z_BUFSIZE = (16384);
|
|
Z_MAXFILENAMEINZIP = (256);
|
|
|
|
const
|
|
CENTRALHEADERMAGIC = $02014b50;
|
|
|
|
const
|
|
SIZECENTRALDIRITEM = $2e;
|
|
SIZEZIPLOCALHEADER = $1e;
|
|
|
|
function ALLOC(size : int) : voidp;
|
|
|
|
procedure TRYFREE(p : voidp);
|
|
|
|
const
|
|
Paszip_copyright : PChar = ' Paszip Copyright 2000 Jacques Nomssi Nzali ';
|
|
|
|
implementation
|
|
|
|
function ALLOC(size : int) : voidp;
|
|
begin
|
|
ALLOC := zcalloc (NIL, size, 1);
|
|
end;
|
|
|
|
procedure TRYFREE(p : voidp);
|
|
begin
|
|
if Assigned(p) then
|
|
zcfree(NIL, p);
|
|
end;
|
|
|
|
{$ifdef Streams}
|
|
{ ---------------------------------------------------------------- }
|
|
|
|
function fopen(filename : PChar; mode : open_mode) : FILEptr;
|
|
var
|
|
fp : FILEptr;
|
|
begin
|
|
fp := NIL;
|
|
try
|
|
Case mode of
|
|
fopenread: fp := TFileStream.Create(filename, fmOpenRead);
|
|
fopenwrite: fp := TFileStream.Create(filename, fmCreate);
|
|
fappendwrite :
|
|
begin
|
|
fp := TFileStream.Create(filename, fmOpenReadWrite);
|
|
fp.Seek(soFromEnd, 0);
|
|
end;
|
|
end;
|
|
except
|
|
on EFOpenError do
|
|
fp := NIL;
|
|
end;
|
|
fopen := fp;
|
|
end;
|
|
|
|
procedure fclose(fp : FILEptr);
|
|
begin
|
|
fp.Free;
|
|
end;
|
|
|
|
function fread(buf : voidp;
|
|
recSize : uInt;
|
|
recCount : uInt;
|
|
fp : FILEptr) : uInt;
|
|
var
|
|
totalSize, readcount : uInt;
|
|
begin
|
|
if Assigned(buf) then
|
|
begin
|
|
totalSize := recCount * uInt(recSize);
|
|
readCount := fp.Read(buf^, totalSize);
|
|
if (readcount <> totalSize) then
|
|
fread := readcount div recSize
|
|
else
|
|
fread := recCount;
|
|
end
|
|
else
|
|
fread := 0;
|
|
end;
|
|
|
|
function fwrite(buf : voidp;
|
|
recSize : uInt;
|
|
recCount : uInt;
|
|
fp : FILEptr) : uInt;
|
|
var
|
|
totalSize, written : uInt;
|
|
begin
|
|
if Assigned(buf) then
|
|
begin
|
|
totalSize := recCount * uInt(recSize);
|
|
written := fp.Write(buf^, totalSize);
|
|
if (written <> totalSize) then
|
|
fwrite := written div recSize
|
|
else
|
|
fwrite := recCount;
|
|
end
|
|
else
|
|
fwrite := 0;
|
|
end;
|
|
|
|
function fseek(fp : FILEptr;
|
|
recPos : uLong;
|
|
mode : seek_mode) : int;
|
|
const
|
|
fsmode : array[seek_mode] of Word
|
|
= (soFromBeginning, soFromCurrent, soFromEnd);
|
|
begin
|
|
fp.Seek(recPos, fsmode[mode]);
|
|
fseek := 0; { = 0 for success }
|
|
end;
|
|
|
|
function ftell(fp : FILEptr) : uLong;
|
|
begin
|
|
ftell := fp.Position;
|
|
end;
|
|
|
|
function feof(fp : FILEptr) : uInt;
|
|
begin
|
|
feof := 0;
|
|
if Assigned(fp) then
|
|
if fp.Position = fp.Size then
|
|
feof := 1
|
|
else
|
|
feof := 0;
|
|
end;
|
|
|
|
{$else}
|
|
{ ---------------------------------------------------------------- }
|
|
|
|
function fopen(filename : PChar; mode : open_mode) : FILEptr;
|
|
var
|
|
fp : FILEptr;
|
|
OldFileMode : byte;
|
|
begin
|
|
fp := NIL;
|
|
OldFileMode := FileMode;
|
|
|
|
GetMem(fp, SizeOf(file));
|
|
Assign(fp^, filename);
|
|
{$i-}
|
|
Case mode of
|
|
fopenread:
|
|
begin
|
|
FileMode := 0;
|
|
Reset(fp^, 1);
|
|
end;
|
|
fopenwrite:
|
|
begin
|
|
FileMode := 1;
|
|
ReWrite(fp^, 1);
|
|
end;
|
|
fappendwrite :
|
|
begin
|
|
FileMode := 2;
|
|
Reset(fp^, 1);
|
|
Seek(fp^, FileSize(fp^));
|
|
end;
|
|
end;
|
|
FileMode := OldFileMode;
|
|
if IOresult<>0 then
|
|
begin
|
|
FreeMem(fp, SizeOf(file));
|
|
fp := NIL;
|
|
end;
|
|
|
|
fopen := fp;
|
|
end;
|
|
|
|
procedure fclose(fp : FILEptr);
|
|
begin
|
|
if Assigned(fp) then
|
|
begin
|
|
{$i-}
|
|
system.close(fp^);
|
|
if IOresult=0 then;
|
|
FreeMem(fp, SizeOf(file));
|
|
end;
|
|
end;
|
|
|
|
function fread(buf : voidp;
|
|
recSize : uInt;
|
|
recCount : uInt;
|
|
fp : FILEptr) : uInt;
|
|
var
|
|
totalSize, readcount : uInt;
|
|
begin
|
|
if Assigned(buf) then
|
|
begin
|
|
totalSize := recCount * uInt(recSize);
|
|
{$i-}
|
|
system.BlockRead(fp^, buf^, totalSize, readcount);
|
|
if (readcount <> totalSize) then
|
|
fread := readcount div recSize
|
|
else
|
|
fread := recCount;
|
|
end
|
|
else
|
|
fread := 0;
|
|
end;
|
|
|
|
function fwrite(buf : voidp;
|
|
recSize : uInt;
|
|
recCount : uInt;
|
|
fp : FILEptr) : uInt;
|
|
var
|
|
totalSize, written : uInt;
|
|
begin
|
|
if Assigned(buf) then
|
|
begin
|
|
totalSize := recCount * uInt(recSize);
|
|
{$i-}
|
|
system.BlockWrite(fp^, buf^, totalSize, written);
|
|
if (written <> totalSize) then
|
|
fwrite := written div recSize
|
|
else
|
|
fwrite := recCount;
|
|
end
|
|
else
|
|
fwrite := 0;
|
|
end;
|
|
|
|
function fseek(fp : FILEptr;
|
|
recPos : uLong;
|
|
mode : seek_mode) : int;
|
|
begin
|
|
{$i-}
|
|
case mode of
|
|
SEEK_SET : system.Seek(fp^, recPos);
|
|
SEEK_CUR : system.Seek(fp^, FilePos(fp^)+recPos);
|
|
SEEK_END : system.Seek(fp^, FileSize(fp^)-1-recPos); { ?? check }
|
|
end;
|
|
fseek := IOresult; { = 0 for success }
|
|
end;
|
|
|
|
function ftell(fp : FILEptr) : uLong;
|
|
begin
|
|
ftell := FilePos(fp^);
|
|
end;
|
|
|
|
function feof(fp : FILEptr) : uInt;
|
|
begin
|
|
feof := 0;
|
|
if Assigned(fp) then
|
|
if eof(fp^) then
|
|
feof := 1
|
|
else
|
|
feof := 0;
|
|
end;
|
|
|
|
{$endif}
|
|
{ ---------------------------------------------------------------- }
|
|
|
|
end.
|