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 >
Pascal/Delphi Source File  |  1994-11-02  |  8KB  |  300 lines

  1. Unit OBinFile;
  2. { Gestion bufférisée d'un fichier }
  3. { K.B. avril-novembre 1994 }
  4.  
  5. {
  6. Utilisé par OFText (fichier texte),
  7.             OFPcx  (fichier PCX),
  8.             OFHelp (fichier d'aide),
  9.             OFZip  (fichier ZIP),
  10. }
  11.  
  12. {
  13.   Cette unité définit l'objet TBinFile qui permet d'utiliser un fichier en
  14. lecture ou en écriture à travers un buffer. Les opérations de lecture et
  15. d'écriture se font ainsi en mémoire, les accès au disque dur ou à la
  16. disquette n'ayant lieu que lorsque le buffer est plein.
  17.  
  18.   ATTENTION : la taille du buffer est définie lors de l'initialisation de
  19. l'objet; ELLE DOIT IMPERATIVEMENT ETRE SUPERIEURE AU DOUBLE DE LA PLUS
  20. GRANDE VARIABLE UTILISEE.
  21. }
  22.  
  23. {$IFDEF debug}
  24.  {$A+,B-,D+,E-,F-,I-,L+,N-,R+,S+,V-,W+,X+}
  25. {$ELSE}
  26.  {$A+,B-,D-,E-,F-,I-,L-,N-,R-,S-,V-,W+,X+}
  27. {$ENDIF}
  28.  
  29. INTERFACE
  30.  
  31. Uses Dos,OFile;
  32.  
  33. Const
  34. { taille maximale d'une variable -1 }
  35.  MaxIndex=65518;   { taille maximale d'une variable -1 }
  36.  
  37. { codes d'erreurs }
  38.  erMemoire    = $101;
  39.  
  40. Type
  41.   PDatas=^TDatas;        { tableau représentant le buffer du fichier }
  42.   TDatas=array[0..MaxIndex] of byte;
  43.  
  44.   PBinFile=^TBinFile;
  45.   TBinFile=object(TFile)
  46.    DataBuf:PDatas;        { pointeur sur buffer }
  47.    DataFileSize:LongInt;  { taille du fichier en tenant compte des changements }
  48.    DataFilePosit:LongInt; { position courante dans le fichier }
  49.    MaxBufSize:Word;       { taille maximale du buffer }
  50.    BufSize:Word;          { taille du buffer }
  51.    BufDeb:LongInt;        { début du buffer dans le fichier }
  52.    WriteFlag:Boolean;     { drapeau indiquant la nécessité de sauver le
  53.                             buffer sur disque }
  54.  
  55.    Constructor Init(NomDeFichier:PathStr; ABufSize:Word);
  56.    { ouverture d'un fichier existant et attribution de mémoire
  57.      au buffer }
  58.    Constructor Create(NomDeFichier:PathStr; ABufSize:Word);
  59.    { création d'un fichier et attribution de mémoire au buffer }
  60.    Destructor Done;virtual;
  61.    { fermeture du fichier et libération mémoire }
  62.    Function GetErrorMsg:String;virtual;
  63.    { renvoie un éventuel message d'erreur }
  64.    Procedure SetFilePosit(num:longint);
  65.    { fixe la position de lecture/écriture dans le fichier }
  66.    Function GetFilePosit:LongInt;
  67.    { renvoie la position actuelle dans le fichier }
  68.    Procedure SetEndPosit;
  69.    { fixe la position de lecture/écriture à la fin du fichier }
  70.    Function EndOfFile:Boolean;
  71.    { indique la fin du fichier }
  72.    Function ReadByte:byte;
  73.    { lecture de l'octet num dans le fichier }
  74.    Procedure ReadVar(Var V; len:word);
  75.    { lecture d'une variable V de longueur len à la position courante dans
  76.      le fichier }
  77.    Procedure ReadBuf;
  78.    { chargement du buffer }
  79.    Procedure WriteByte(b:byte);
  80.    { écriture de l'octet b à la position courante dans le fichier }
  81.    Procedure WriteVar(Var V; len:word);
  82.    { écriture d'une variable V de longueur len à la position courante dans
  83.      le fichier }
  84.    Procedure WriteBuf;
  85.    { écriture du buffer dans le fichier sur disque }
  86.    Function Find(S:String):Boolean;
  87.    { recherche la chaine S à partir de la position courante dans le fichier
  88.      et fixe la position courante au début de l'emplacement trouvé en cas
  89.      de succès et à la fin du fichier en cas d'échec. }
  90.    End;
  91.  
  92. IMPLEMENTATION
  93.  
  94. { Objet TBinFile }
  95.  
  96. Constructor TBinFile.Init(NomDeFichier:PathStr;ABufSize:Word);
  97. Begin
  98.  TFile.Init(NomDeFichier,stOpen);
  99.  {initialisation des champs}
  100.  WriteFlag:=false;
  101.  DataBuf:=nil;
  102.  DataFileSize:=0;
  103.  DataFilePosit:=0;
  104.  BufDeb:=0;
  105.  BufSize:=0;
  106.  if ABufSize>MaxIndex then ABufSize:=MaxIndex;
  107.  MaxBufSize:=ABufSize;
  108.  if not IsValid
  109.     then exit;
  110.  { taille du fichier }
  111.  DataFileSize:=FSize;
  112.  {allocation de mémoire pour le buffer}
  113.  if MaxAvail< MaxBufSize+1024
  114.     then ErrorFlag:=erMemoire
  115.     else begin
  116.           GetMem(DataBuf,MaxBufSize);
  117.           { initialisation du buffer }
  118.           ReadBuf;
  119.          end;
  120. End;
  121.  
  122. Constructor TBinFile.Create(NomDeFichier:PathStr;ABufSize:Word);
  123. Begin
  124.  TFile.Init(NomDeFichier,stCreate);
  125.  {initialisation des champs}
  126.  WriteFlag:=false;
  127.  DataBuf:=nil;
  128.  DataFileSize:=0;
  129.  DataFilePosit:=0;
  130.  BufDeb:=0;
  131.  BufSize:=0;
  132.  if ABufSize>MaxIndex then ABufSize:=MaxIndex;
  133.  MaxBufSize:=ABufSize;
  134.  if not IsValid
  135.     then exit;
  136.  {allocation de mémoire pour le buffer}
  137.  if MaxAvail< MaxBufSize+1024
  138.     then ErrorFlag:=erMemoire
  139.     else GetMem(DataBuf,MaxBufSize);
  140. End;
  141.  
  142. Destructor TBinFile.Done;
  143. Begin
  144.  if IsValid
  145.     then WriteBuf;
  146.  if DataBuf<>nil
  147.     then FreeMem(DataBuf,MaxBufSize);
  148.  TFile.Done;
  149. End;
  150.  
  151. Function TBinFile.GetErrorMsg:String;
  152. Begin
  153.  case ErrorFlag of
  154.   erMemoire : GetErrorMsg:='Mémoire insuffisante pour créer le buffer'+chr(13)
  155.                            +'du fichier '+FName+FExt;
  156.   else GetErrorMsg:=TFile.GetErrorMsg;
  157.   end;
  158. End;
  159.  
  160. Procedure TBinFile.SetFilePosit(num:LongInt);
  161. Begin
  162.  if num<0 then num:=0;
  163.  if num>DataFileSize
  164.     then begin
  165.           SetEndPosit;
  166.           repeat
  167.            WriteByte(32);
  168.           until (DataFilePosit=num) or (ErrorFlag<>0);
  169.          end
  170.     else DataFilePosit:=num;
  171. End;
  172.  
  173. Function TBinFile.GetFilePosit:LongInt;
  174. Begin
  175.  GetFilePosit:=DataFilePosit;
  176. End;
  177.  
  178. Procedure TBinFile.SetEndPosit;
  179. Begin
  180.  DataFilePosit:=DataFileSize;
  181. End;
  182.  
  183. Function TBinFile.EndOfFile:Boolean;
  184. Begin
  185.  EndOfFile:=DataFilePosit>=DataFileSize;
  186. End;
  187.  
  188. Procedure TBinFile.ReadBuf;
  189. Var avant:LongInt;
  190. Begin
  191.  avant:=MaxBufSize div 2;
  192.  if DataFilePosit-avant<0
  193.     then BufDeb:=0
  194.     else BufDeb:=DataFilePosit-avant;
  195.  FSeek(BufDeb);
  196.  FReadC(DataBuf^[0],MaxBufSize,BufSize);
  197. End;
  198.  
  199. Procedure TBinFile.WriteBuf;
  200. Begin
  201.  if WriteFlag
  202.     then begin
  203.           FSeek(BufDeb);
  204.           FWrite(DataBuf^[0],BufSize);
  205.          end;
  206.  WriteFlag:=false;
  207. End;
  208.  
  209. Function TBinFile.ReadByte:byte;
  210. Begin
  211.  ReadByte:=0;
  212.  if EndOfFile then exit;
  213.  if (DataFilePosit<BufDeb) or (DataFilePosit>=BufDeb+MaxBufSize)
  214.     then begin
  215.           WriteBuf;
  216.           ReadBuf;
  217.          end;
  218.  ReadByte:=DataBuf^[DataFilePosit-BufDeb];
  219.  SetFilePosit(DataFilePosit+1);
  220. End;
  221.  
  222. Procedure TBinFile.ReadVar(Var V; len:word);
  223. Var n:word;
  224. Begin
  225.  if EndOfFile then exit;
  226.  if (DataFilePosit-BufDeb<0) or (DataFilePosit-BufDeb+len>=MaxBufSize)
  227.     then begin
  228.           WriteBuf;
  229.           ReadBuf;
  230.          end;
  231.  Move(DataBuf^[DataFilePosit-BufDeb],V,len);
  232.  SetFilePosit(DataFilePosit+len);
  233. End;
  234.  
  235. Procedure TBinFile.WriteByte(b:byte);
  236. Begin
  237.  if (DataFilePosit<BufDeb) or (DataFilePosit-BufDeb>=MaxBufSize)
  238.     then begin
  239.           WriteBuf;
  240.           ReadBuf;
  241.          end;
  242.  DataBuf^[DataFilePosit-BufDeb]:=b;
  243.  WriteFlag:=true;
  244.  if EndOfFile
  245.     then begin
  246.           inc(BufSize);
  247.           inc(DataFileSize);
  248.          end;
  249.  SetFilePosit(DataFilePosit+1);
  250. End;
  251.  
  252. Procedure TBinFile.WriteVar(Var V; len:word);
  253. Begin
  254.  if (DataFilePosit-BufDeb<0) or (DataFilePosit-BufDeb+len>=MaxBufSize)
  255.     then begin
  256.           WriteBuf;
  257.           ReadBuf;
  258.          end;
  259.  Move(V,DataBuf^[DataFilePosit-BufDeb],len);
  260.  WriteFlag:=true;
  261.  if EndOfFile
  262.     then begin
  263.           inc(BufSize,len);
  264.           inc(DataFileSize,len);
  265.          end;
  266.  SetFilePosit(DataFilePosit+len);
  267. End;
  268.  
  269. Function TBinFile.Find(S:String):Boolean;
  270. { recherche d'une chaine de caractères en utilisant la fonction Pos de
  271.   Turbo Pascal }
  272. Var W:String;
  273.     l,p:Byte;
  274.     ok,fin:Boolean;
  275. Begin
  276.  ok:=false;
  277.  fin:=false;
  278.  repeat
  279.   if DataFileSize-DataFilePosit>255
  280.      then l:=255
  281.      else l:=DataFileSize-DataFilePosit;
  282.   W[0]:=chr(l);
  283.   ReadVar(W[1],l);
  284.   if EndOfFile
  285.      then fin:=true;
  286.   p:=Pos(S,W);
  287.   if p<>0
  288.      then begin
  289.            ok:=true;
  290.            SetFilePosit(DataFilePosit-l+p-1);
  291.           end
  292.      else SetFilePosit(DataFilePosit-length(S));
  293.  until ok or fin or (not IsValid);
  294.  Find:=ok;
  295. End;
  296.  
  297. END.
  298.  
  299. {                        Fin du fichier OBinFile.Pas                        }
  300.