home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
DP Tool Club 19
/
CD_ASCQ_19_010295.iso
/
dos
/
prg
/
pas
/
ktools
/
source
/
obinfile.pas
< prev
next >
Wrap
Pascal/Delphi Source File
|
1994-11-02
|
8KB
|
300 lines
Unit OBinFile;
{ Gestion bufférisée d'un fichier }
{ K.B. avril-novembre 1994 }
{
Utilisé par OFText (fichier texte),
OFPcx (fichier PCX),
OFHelp (fichier d'aide),
OFZip (fichier ZIP),
}
{
Cette unité définit l'objet TBinFile qui permet d'utiliser un fichier en
lecture ou en écriture à travers un buffer. Les opérations de lecture et
d'écriture se font ainsi en mémoire, les accès au disque dur ou à la
disquette n'ayant lieu que lorsque le buffer est plein.
ATTENTION : la taille du buffer est définie lors de l'initialisation de
l'objet; ELLE DOIT IMPERATIVEMENT ETRE SUPERIEURE AU DOUBLE DE LA PLUS
GRANDE VARIABLE UTILISEE.
}
{$IFDEF debug}
{$A+,B-,D+,E-,F-,I-,L+,N-,R+,S+,V-,W+,X+}
{$ELSE}
{$A+,B-,D-,E-,F-,I-,L-,N-,R-,S-,V-,W+,X+}
{$ENDIF}
INTERFACE
Uses Dos,OFile;
Const
{ taille maximale d'une variable -1 }
MaxIndex=65518; { taille maximale d'une variable -1 }
{ codes d'erreurs }
erMemoire = $101;
Type
PDatas=^TDatas; { tableau représentant le buffer du fichier }
TDatas=array[0..MaxIndex] of byte;
PBinFile=^TBinFile;
TBinFile=object(TFile)
DataBuf:PDatas; { pointeur sur buffer }
DataFileSize:LongInt; { taille du fichier en tenant compte des changements }
DataFilePosit:LongInt; { position courante dans le fichier }
MaxBufSize:Word; { taille maximale du buffer }
BufSize:Word; { taille du buffer }
BufDeb:LongInt; { début du buffer dans le fichier }
WriteFlag:Boolean; { drapeau indiquant la nécessité de sauver le
buffer sur disque }
Constructor Init(NomDeFichier:PathStr; ABufSize:Word);
{ ouverture d'un fichier existant et attribution de mémoire
au buffer }
Constructor Create(NomDeFichier:PathStr; ABufSize:Word);
{ création d'un fichier et attribution de mémoire au buffer }
Destructor Done;virtual;
{ fermeture du fichier et libération mémoire }
Function GetErrorMsg:String;virtual;
{ renvoie un éventuel message d'erreur }
Procedure SetFilePosit(num:longint);
{ fixe la position de lecture/écriture dans le fichier }
Function GetFilePosit:LongInt;
{ renvoie la position actuelle dans le fichier }
Procedure SetEndPosit;
{ fixe la position de lecture/écriture à la fin du fichier }
Function EndOfFile:Boolean;
{ indique la fin du fichier }
Function ReadByte:byte;
{ lecture de l'octet num dans le fichier }
Procedure ReadVar(Var V; len:word);
{ lecture d'une variable V de longueur len à la position courante dans
le fichier }
Procedure ReadBuf;
{ chargement du buffer }
Procedure WriteByte(b:byte);
{ écriture de l'octet b à la position courante dans le fichier }
Procedure WriteVar(Var V; len:word);
{ écriture d'une variable V de longueur len à la position courante dans
le fichier }
Procedure WriteBuf;
{ écriture du buffer dans le fichier sur disque }
Function Find(S:String):Boolean;
{ recherche la chaine S à partir de la position courante dans le fichier
et fixe la position courante au début de l'emplacement trouvé en cas
de succès et à la fin du fichier en cas d'échec. }
End;
IMPLEMENTATION
{ Objet TBinFile }
Constructor TBinFile.Init(NomDeFichier:PathStr;ABufSize:Word);
Begin
TFile.Init(NomDeFichier,stOpen);
{initialisation des champs}
WriteFlag:=false;
DataBuf:=nil;
DataFileSize:=0;
DataFilePosit:=0;
BufDeb:=0;
BufSize:=0;
if ABufSize>MaxIndex then ABufSize:=MaxIndex;
MaxBufSize:=ABufSize;
if not IsValid
then exit;
{ taille du fichier }
DataFileSize:=FSize;
{allocation de mémoire pour le buffer}
if MaxAvail< MaxBufSize+1024
then ErrorFlag:=erMemoire
else begin
GetMem(DataBuf,MaxBufSize);
{ initialisation du buffer }
ReadBuf;
end;
End;
Constructor TBinFile.Create(NomDeFichier:PathStr;ABufSize:Word);
Begin
TFile.Init(NomDeFichier,stCreate);
{initialisation des champs}
WriteFlag:=false;
DataBuf:=nil;
DataFileSize:=0;
DataFilePosit:=0;
BufDeb:=0;
BufSize:=0;
if ABufSize>MaxIndex then ABufSize:=MaxIndex;
MaxBufSize:=ABufSize;
if not IsValid
then exit;
{allocation de mémoire pour le buffer}
if MaxAvail< MaxBufSize+1024
then ErrorFlag:=erMemoire
else GetMem(DataBuf,MaxBufSize);
End;
Destructor TBinFile.Done;
Begin
if IsValid
then WriteBuf;
if DataBuf<>nil
then FreeMem(DataBuf,MaxBufSize);
TFile.Done;
End;
Function TBinFile.GetErrorMsg:String;
Begin
case ErrorFlag of
erMemoire : GetErrorMsg:='Mémoire insuffisante pour créer le buffer'+chr(13)
+'du fichier '+FName+FExt;
else GetErrorMsg:=TFile.GetErrorMsg;
end;
End;
Procedure TBinFile.SetFilePosit(num:LongInt);
Begin
if num<0 then num:=0;
if num>DataFileSize
then begin
SetEndPosit;
repeat
WriteByte(32);
until (DataFilePosit=num) or (ErrorFlag<>0);
end
else DataFilePosit:=num;
End;
Function TBinFile.GetFilePosit:LongInt;
Begin
GetFilePosit:=DataFilePosit;
End;
Procedure TBinFile.SetEndPosit;
Begin
DataFilePosit:=DataFileSize;
End;
Function TBinFile.EndOfFile:Boolean;
Begin
EndOfFile:=DataFilePosit>=DataFileSize;
End;
Procedure TBinFile.ReadBuf;
Var avant:LongInt;
Begin
avant:=MaxBufSize div 2;
if DataFilePosit-avant<0
then BufDeb:=0
else BufDeb:=DataFilePosit-avant;
FSeek(BufDeb);
FReadC(DataBuf^[0],MaxBufSize,BufSize);
End;
Procedure TBinFile.WriteBuf;
Begin
if WriteFlag
then begin
FSeek(BufDeb);
FWrite(DataBuf^[0],BufSize);
end;
WriteFlag:=false;
End;
Function TBinFile.ReadByte:byte;
Begin
ReadByte:=0;
if EndOfFile then exit;
if (DataFilePosit<BufDeb) or (DataFilePosit>=BufDeb+MaxBufSize)
then begin
WriteBuf;
ReadBuf;
end;
ReadByte:=DataBuf^[DataFilePosit-BufDeb];
SetFilePosit(DataFilePosit+1);
End;
Procedure TBinFile.ReadVar(Var V; len:word);
Var n:word;
Begin
if EndOfFile then exit;
if (DataFilePosit-BufDeb<0) or (DataFilePosit-BufDeb+len>=MaxBufSize)
then begin
WriteBuf;
ReadBuf;
end;
Move(DataBuf^[DataFilePosit-BufDeb],V,len);
SetFilePosit(DataFilePosit+len);
End;
Procedure TBinFile.WriteByte(b:byte);
Begin
if (DataFilePosit<BufDeb) or (DataFilePosit-BufDeb>=MaxBufSize)
then begin
WriteBuf;
ReadBuf;
end;
DataBuf^[DataFilePosit-BufDeb]:=b;
WriteFlag:=true;
if EndOfFile
then begin
inc(BufSize);
inc(DataFileSize);
end;
SetFilePosit(DataFilePosit+1);
End;
Procedure TBinFile.WriteVar(Var V; len:word);
Begin
if (DataFilePosit-BufDeb<0) or (DataFilePosit-BufDeb+len>=MaxBufSize)
then begin
WriteBuf;
ReadBuf;
end;
Move(V,DataBuf^[DataFilePosit-BufDeb],len);
WriteFlag:=true;
if EndOfFile
then begin
inc(BufSize,len);
inc(DataFileSize,len);
end;
SetFilePosit(DataFilePosit+len);
End;
Function TBinFile.Find(S:String):Boolean;
{ recherche d'une chaine de caractères en utilisant la fonction Pos de
Turbo Pascal }
Var W:String;
l,p:Byte;
ok,fin:Boolean;
Begin
ok:=false;
fin:=false;
repeat
if DataFileSize-DataFilePosit>255
then l:=255
else l:=DataFileSize-DataFilePosit;
W[0]:=chr(l);
ReadVar(W[1],l);
if EndOfFile
then fin:=true;
p:=Pos(S,W);
if p<>0
then begin
ok:=true;
SetFilePosit(DataFilePosit-l+p-1);
end
else SetFilePosit(DataFilePosit-length(S));
until ok or fin or (not IsValid);
Find:=ok;
End;
END.
{ Fin du fichier OBinFile.Pas }