home *** CD-ROM | disk | FTP | other *** search
- Unit OFZip;
- { lecture du contenu d'un fichier ZIP }
- { Kostrzewa Bruno }
- { juin 1994 }
-
- INTERFACE
-
- Uses Dos,
- OBinFile,
- OTableau;
-
- Const
-
- EndDirSign=$06054B50 ; { fin du répertoire des fichiers }
- FileDirSign=$02014B50 ; { entête des fichiers dans le répertoire }
-
- tab_method:Array[0..6] of string[8] =
- ('Stored','Shrunk','Reduc.1','Reduc.2','Reduc.3','Reduc.4','Imploded');
- mois:Array[1..12] of string[3] =
- ('Jan','Fev','Mar','Avr','Mai','Jun','Jul','Aou','Sep','Oct','Nov','Dec');
-
- erFile = $100;
- erNotZip = $101;
- erDisks = $102;
- erFatale = $103;
-
- Type
- TEndDirDesc=record
- sign :longint; { signature fin rép }
- nmr_disk :word; { numéro du disque }
- nmr_disk_dir:word; { disque contenant début rép }
- nb_file_disk:word; { nbre de fichier sur ce disque }
- total_file :word; { nbre total de fichiers dans rép }
- size_dir :longint; { taille du rép }
- start_dir :longint; { offset début rép sur son disque }
- comment_len :word; { longueur du commentaire }
- end;
-
- TFileDirDesc=record
- sign :longint; { signature entête des fichiers }
- version :word; { version du logiciel de compression }
- version_extract:word; { version pour extraire le fichier }
- bit_flag :word; { drapeaux }
- method :word; { méthode de compression }
- time_date :longint; { date et heure de modification }
- crc_32 :longint; { cyclic redundancy check 32 bits du fichier }
- comp_size :longint; { taille fichier compressé }
- uncomp_size :longint; { taille fichier décompressé }
- filenamelen :word; { longueur du nom de fichier }
- extrafieldlen:word; { longueur extra_field }
- filecomlen :word; { longueur du commentaire du fichier }
- disk_nmr :word; { numéro du disque contenant le fichier }
- int_attr :word; { attribut fichier interne }
- ext_attr :longint; { attribut fichier externe }
- start_header:longint; { offset début entête du fichier sur son disque }
- end;
-
- PString=^String;
-
- PFileZipDatas=^TFileZipDatas;
- TFileZipDatas=record
- FileDir:TFileDirDesc;
- FName:PString;
- FComment:PString;
- End;
-
- PZipTab=^TZipTab;
- TZipTab=object(TTabPtr)
- TailleDecomp:Real;
- Constructor Init(NomFichier:PathStr);
- Function GetErrorMsg:String; virtual;
- Procedure Effacer(P: Pointer); virtual;
- Function GetRec(n:Integer):PFileZipDatas;
- end;
-
- { fonctions utilitaires }
- Function Longueur(R:TFileZipDatas):String;
- Function Methode(R:TFileZipDatas):String;
- Function Taille(R:TFileZipDatas):String;
- Function Ratio(R:TFileZipDatas):String;
- Function ZDate(R:TFileZipDatas):String;
- Function ZHeure(R:TFileZipDatas):String;
- Function CRC32(R:TFileZipDatas):String;
- Function ZNom(R:TFileZipDatas):String;
-
- IMPLEMENTATION
-
- Function hexa(nbr:longint;long:integer):string;
- { conversion d'un nombre en hexadécimal }
- Const hexa_tab:array[0..15] of char =
- ('0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F');
- Var i:byte;
- Begin
- if long=0 then long:=trunc(ln(nbr)/ln(16))+1;
- hexa[0]:=char(long);
- for i:=0 to long-1 do
- hexa[long-i]:=hexa_tab[(nbr shr (4*i)) and $000F];
- End;
-
- Function deci(nbr:longint;long:byte;with0:boolean):string;
- { écriture d'un entier sur long chiffres }
- Var i:byte;
- d:string;
- Begin
- if long=0 then long:=trunc(ln(nbr)/ln(10))+1;
- d[0]:=char(long);
- str(nbr:long,d);
- for i:=1 to long do
- if (d[i]=' ') and with0 then d[i]:='0';
- deci:=d;
- End;
-
- Procedure DisposeStr(P:PString);
- Var l:Byte;
- Begin
- l:=ord(P^[0]);
- freemem(P,l+1);
- End;
-
- Function NewStr(S:String):PString;
- Var P:PString;
- Begin
- GetMem(P,length(S)+1);
- P^:=S;
- NewStr:=P;
- End;
-
- { Objet TZipTab }
-
- Constructor TZipTab.Init(NomFichier:PathStr);
- Var f:PBinFile;
- i,p:LongInt;
- S:String;
- EndDir:TEndDirDesc;
- fdatas:PFileZipDatas;
- Begin
- TTabPtr.Init(20,20);
- TailleDecomp:=0;
- f:=New(PBinFile,Init(NomFichier,8*1024));
- if not f^.IsValid
- then begin
- ErrorFlag:=erFile;
- exit;
- end;
-
- { Recherche fin du répertoire des fichiers à partir de la fin }
- p:=f^.datafilesize+1;
- repeat
- dec(p);
- with f^ do
- begin
- setfileposit(p-sizeof(EndDir));
- readvar(EndDir,sizeof(EndDir));
- end;
- until (EndDir.sign=EndDirSign) or (p=sizeof(EndDir));
- if p=sizeof(EndDir)
- then begin
- ErrorFlag:=erNotZip;
- exit;
- end;
- if EndDir.nmr_disk<>0
- then begin
- ErrorFlag:=erDisks;
- exit;
- end;
-
- { lecture des données }
- f^.setfileposit(EndDir.start_dir);
- for i:=1 to EndDir.total_file do
- begin
- new(fdatas);
- fdatas^.fname:=nil;
- fdatas^.fcomment:=nil;
- f^.readvar(fdatas^.FileDir,sizeof(TFileDirDesc));
- Ajouter(fdatas);
- with fdatas^ do
- begin
- { vérification signature }
- if FileDir.sign<>FileDirSign
- then begin
- ErrorFlag:=erFatale;
- exit;
- end
- else begin
- { mise à jour taille totale }
- TailleDecomp:=TailleDecomp+FileDir.uncomp_size;
- { nom du fichier }
- f^.readvar(s[1],FileDir.filenamelen);
- s[0]:=chr(FileDir.filenamelen);
- fname:=newstr(s);
- { commentaire fichier }
- f^.setfileposit(f^.getfileposit+FileDir.extrafieldlen);
- if FileDir.filecomlen<>0
- then begin
- f^.readvar(s[1],FileDir.filecomlen);
- s[0]:=chr(FileDir.filecomlen);
- fcomment:=newstr(s);
- end;
- end;
- end; {with}
- end; {for}
- dispose(f,done);
- End;
-
- Function TZipTab.GetErrorMsg:String;
- Begin
- case ErrorFlag of
- erFile : GetErrorMsg:='Ouverture du fichier impossible.';
- erNotZip : GetErrorMsg:='Format du fichier non reconnu.';
- erDisks : GetErrorMsg:='Les fichiers sont sur plusieurs disques.';
- erFatale : GetErrorMsg:='Erreur fatale dans le fichier ZIP.';
- else GetErrorMsg:=TTabPtr.GetErrorMsg;
- end;
- End;
-
- Procedure TZipTab.Effacer(P:Pointer);
- Var w:PFileZipDatas;
- Begin
- w:=PFileZipDatas(p);
- with w^ do
- begin
- if fname<>nil then disposestr(fname);
- if fcomment<>nil then disposestr(fcomment);
- end;
- Dispose(w);
- End;
-
- Function TZipTab.GetRec(n:Integer):PFileZipDatas;
- Var P:PFileZipDatas;
- Begin
- if (n<1) or (n>NombreItems)
- then P:=nil
- else Lire(P,n);
- GetRec:=P;
- End;
-
- Function Longueur(R:TFileZipDatas):String;
- Begin
- Longueur:=deci(R.FileDir.uncomp_size,8,false);
- End;
-
- Function Methode(R:TFileZipDatas):String;
- Begin
- Methode:=Tab_Method[R.FileDir.method];
- End;
-
- Function Taille(R:TFileZipDatas):String;
- Begin
- Taille:=deci(R.FileDir.comp_size,9,false);
- End;
-
- Function Ratio(R:TFileZipDatas):String;
- Begin
- Ratio:=deci(100-R.FileDir.comp_size*100 div R.FileDir.uncomp_size,
- 4,false)+'%';
- End;
-
- Function ZDate(R:TFileZipDatas):String;
- Var t:DateTime;
- Begin
- UnPackTime(R.FileDir.time_date,t);
- ZDate:=deci(t.day,2,true)+' '+mois[t.month]+' '+deci(t.year,4,true);
- End;
-
- Function ZHeure(R:TFileZipDatas):String;
- Var t:DateTime;
- Begin
- UnPackTime(R.FileDir.time_date,t);
- ZHeure:=deci(t.hour,2,true)+':'+deci(t.min,2,true)+':'+deci(t.sec,2,true);
- End;
-
- Function CRC32(R:TFileZipDatas):String;
- Begin
- CRC32:=hexa(R.FileDir.crc_32,8);
- End;
-
- Function ZNom(R:TFileZipDatas):String;
- Var fd:DirStr;
- fn:NameStr;
- fe:ExtStr;
- Begin
- fsplit(R.fname^,fd,fn,fe);
- fd:=fn+fe;
- while length(fd)<12 do fd:=fd+' ';
- ZNom:=fd;
- End;
-
- END.
-
- { Fin du fichier OFZip.Pas }
-