home *** CD-ROM | disk | FTP | other *** search
- Program Linked;
-
- Type
- FileDescriptor =
- Object
- Fpt : File;
- Name : String[80];
- HeaderSize: Word;
- RecordSize: Word;
- RecordPtr : Pointer;
- SoftPut : Boolean;
- IsOpen : Boolean;
- CurRec : LongInt;
-
- Constructor Init(Nam : String; Hdr : Word; Size : Word; Buff : Pointer;
- Put : Boolean);
- Destructor Done; Virtual;
- Procedure OpenFile; Virtual;
- Procedure CloseFile; Virtual;
- Procedure GetRecord(Rec : LongInt);
- Procedure PutRecord(Rec : LongInt);
- end;
-
- FileLable =
- Record
- Eof : LongInt;
- MRD : LongInt;
- Act : LongInt;
- Val : LongInt;
- Sync: LongInt;
- end;
-
- LabeledFile =
- Object(FileDescriptor)
- Header : FileLable;
-
- Constructor Init(Nam : String; Size : Word; Buff : Pointer; Put :
- Boolean);
- Destructor Done; Virtual;
- Procedure OpenFile; Virtual;
- Procedure CloseFile; Virtual;
- Procedure WriteHeader;
- Procedure ReadHeader;
- Procedure AddRecord;
- Procedure DelRecord(Rec : LongInt);
- end;
-
- DetailHeaderPtr = ^DetailHeader;
- DetailHeader =
- Record
- Master : LongInt;
- Prev : LongInt;
- Next : LongInt;
- end;
-
- MasterHeaderPtr = ^MasterHeader;
- MasterHeader =
- Record
- First : LongInt;
- Last : LongInt;
- end;
-
- DetailFileDetailPtr = ^DetailFileDetail;
- DetailFileDetail =
- Object(LabeledFile)
- Constructor Init(Nam : String; Size : Word; Buff : Pointer; Put :
- Boolean);
- Procedure LinkChain(MR, Last, Curr : LongInt);
- Procedure DelinkChain(Rec : LongInt);
- end;
-
- DetailFileMaster =
- Object(LabeledFile)
- Constructor Init(Nam : String; Size : Word; Buff : Pointer; Put :
- Boolean);
- Procedure LinkDetail(DF : DetailFileDetailPtr);
- Procedure DelinkDetail(DF : DetailFileDetailPtr; DR : LongInt);
- Procedure GetFirst(DF : DetailFileDetailPtr);
- Procedure GetLast(DF : DetailFileDetailPtr);
- Procedure GetNext(DF : DetailFileDetailPtr);
- Procedure GetPrev(DF : DetailFileDetailPtr);
- end;
-
- {---------------------------------------------------------------------------}
-
- Constructor FileDescriptor.Init(Nam : String; Hdr : Word; Size : Word; Buff :
- Pointer; Put : Boolean);
- begin
- IsOpen := False;
- Name := Nam;
- HeaderSize := Hdr;
- RecordSize := Size;
- RecordPtr := Buff;
- SoftPut := Put;
- CurRec := -1;
- end;
-
- Destructor FileDescriptor.Done;
- begin
- if SoftPut and (CurRec <> -1) then
- PutRecord(CurRec);
- if IsOpen then
- CloseFile;
- end;
-
- Procedure FileDescriptor.OpenFile;
- begin
- if IsOpen then
- Exit;
- Assign(Fpt,Name);
- {$I-}
- Reset(Fpt,1);
- if IoResult <> 0 then
- ReWrite(Fpt,1);
- if IoResult = 0 then
- IsOpen := True;
- {$I+}
- CurRec := -1;
- end;
-
- Procedure FileDescriptor.CloseFile;
- begin
- if not IsOpen then
- Exit;
- {$I-}
- Close(Fpt);
- if IoResult = 0 then
- IsOpen := False;
- {$I+}
- CurRec := -1;
- end;
-
- Procedure FileDescriptor.GetRecord(Rec : LongInt);
- Var
- Result : Word;
- begin
- if not IsOpen then
- Exit;
- if CurRec = Rec then
- Exit;
- if SoftPut and (CurRec <> -1) then
- PutRecord(CurRec);
- {$I-}
- if Rec = 0 then
- begin
- Seek(Fpt,0);
- if IoResult = 0 then
- begin
- BlockRead(Fpt,RecordPtr^,HeaderSize,Result);
- if (Result <> HeaderSize) or (IoResult <> 0) then
- {Error Routine};
- end;
- end
- else
- begin
- Seek(Fpt,HeaderSize + (Rec - 1) * RecordSize);
- if IoResult = 0 then
- begin
- BlockRead(Fpt,RecordPtr^,RecordSize,Result);
- if (Result <> RecordSize) or (IoResult <> 0) then
- {Error Routine};
- end;
- end;
- {$I+}
- CurRec := Rec;
- end;
-
- Procedure FileDescriptor.PutRecord(Rec : LongInt);
- Var
- Result : Word;
- begin
- if not IsOpen then
- Exit;
- {$I-}
- if Rec = 0 then
- begin
- Seek(Fpt,0);
- if IoResult = 0 then
- begin
- BlockWrite(Fpt,RecordPtr^,HeaderSize,Result);
- if (Result <> HeaderSize) or (IoResult <> 0) then
- {Error Routine};
- end;
- end
- else
- begin
- Seek(Fpt,HeaderSize + (Rec - 1) * RecordSize);
- if IoResult = 0 then
- begin
- BlockWrite(Fpt,RecordPtr^,RecordSize,Result);
- if (Result <> RecordSize) or (IoResult <> 0) then
- {Error Routine};
- end;
- end;
- CurRec := Rec;
- {$I+}
- end;
-
- {---------------------------------------------------------------------------}
-
- Constructor LabeledFile.Init(Nam : String; Size : Word; Buff : Pointer; Put :
- Boolean);
- begin
- if Size < 4 then
- begin
- WriteLN('Record size must be 4 or larger');
- Fail;
- end;
- FileDescriptor.Init(Nam,Sizeof(Header),Size,Buff,Put);
- Header.Eof := 0;
- Header.MRD := 0;
- Header.Act := 0;
- Header.Val := 0;
- Header.Sync:= 0;
- end;
-
- Destructor LabeledFile.Done;
- begin
- CloseFile;
- FileDescriptor.Done;
- end;
-
- Procedure LabeledFile.OpenFile;
- begin
- FileDescriptor.OpenFile;
- if IsOpen then
- ReadHeader;
- end;
-
- Procedure LabeledFile.CloseFile;
- begin
- {$I-}
- if IsOpen then
- begin
- if SoftPut and (CurRec <> -1) then
- PutRecord(CurRec);
- Header.Val := 0;
- WriteHeader;
- CurRec := -1;
- end;
- FileDescriptor.CloseFile;
- {$I+}
- end;
-
- Procedure LabeledFile.ReadHeader;
- Var
- Result : Word;
- begin
- {$I-}
- Seek(Fpt,0);
- if IoResult = 0 then
- begin
- BlockRead(Fpt,Header,HeaderSize,Result);
- if (Result <> HeaderSize) or (IoResult <> 0) then
- {Error Routine};
- end;
- {$I+}
- end;
-
- Procedure LabeledFile.WriteHeader;
- Var
- Result : Word;
- begin
- {$I-}
- Seek(Fpt,0);
- if IoResult = 0 then
- begin
- BlockWrite(Fpt,Header,HeaderSize,Result);
- if (Result <> HeaderSize) or (IoResult <> 0) then
- {Error Routine};
- end;
- {$I+}
- end;
-
- Procedure LabeledFile.AddRecord;
- Var
- TmpRec : Pointer;
- Result : Word;
- Next : LongInt;
- begin
- {$I-}
- if Header.MRD <> 0 then
- begin
- GetMem(TmpRec,RecordSize);
- Seek(Fpt,HeaderSize + (Header.MRD - 1) * RecordSize);
- if IoResult = 0 then
- begin
- BlockRead(Fpt,TmpRec^,RecordSize,Result);
- if (Result <> RecordSize) or (IoResult <> 0) then
- {Error Routine};
- Next := LongInt(TmpRec^);
- PutRecord(Header.MRD);
- Header.MRD := Next;
- Header.Act := Header.Act + 1;
- end;
- FreeMem(TmpRec,RecordSize);
- end
- else
- begin
- PutRecord(Header.Eof);
- Header.Eof := Header.Eof + 1;
- Header.Act := Header.Act + 1;
- end;
- WriteHeader;
- {$I+}
- end;
-
- Procedure LabeledFile.DelRecord(Rec : LongInt);
- Var
- TmpRec : Pointer;
- Result : Word;
- begin
- {$I-}
- GetMem(TmpRec,RecordSize);
- Seek(Fpt,HeaderSize + (Rec - 1) * RecordSize);
- if IoResult = 0 then
- begin
- BlockRead(Fpt,TmpRec^,RecordSize,Result);
- LongInt(TmpRec^) := Header.MRD;
- BlockWrite(Fpt,TmpRec^,RecordSize,Result);
- if (Result <> RecordSize) or (IoResult <> 0) then
- {Error Routine};
- Header.MRD := Rec;
- Header.Act := Header.Act - 1;
- WriteHeader;
- end;
- {$I+}
- end;
-
- {---------------------------------------------------------------------------}
-
- Constructor DetailFileDetail.Init(Nam : String; Size : Word; Buff : Pointer;
- Put : Boolean);
- begin
- if Size < 12 then
- begin
- WriteLn('Detail File Records must be 12 Bytes or more');
- Fail;
- end;
- LabeledFile.Init(Nam,Size,Buff,Put);
- end;
-
- Procedure DetailFileDetail.LinkChain(MR, Last, Curr : LongInt);
- Var
- Hdr : DetailHeaderPtr;
- begin
- Hdr := RecordPtr;
- if Last <> 0 then
- begin
- GetRecord(Last);
- Hdr^.Next := Curr;
- PutRecord(Last);
- end;
- GetRecord(Curr);
- Hdr^.Prev := Last;
- Hdr^.Master := MR;
- Hdr^.Next := 0;
- PutRecord(Curr);
- end;
-
- Procedure DetailFileDetail.DelinkChain(Rec : LongInt); Var
- Hdr : DetailHeaderPtr;
- Tmp : LongInt;
- begin
- Hdr := RecordPtr;
- GetRecord(Rec);
- if Hdr^.Next <> 0 then
- begin
- Tmp := Hdr^.Prev;
- GetRecord(Hdr^.Next);
- Hdr^.Prev := Tmp;
- PutRecord(CurRec);
- GetRecord(Rec);
- end;
- if Hdr^.Prev <> 0 then
- begin
- Tmp := Hdr^.Next;
- GetRecord(Hdr^.Prev);
- Hdr^.Next := Tmp;
- PutRecord(CurRec);
- GetRecord(Rec);
- end;
- Hdr^.Master := 0;
- Hdr^.Next := 0;
- Hdr^.Prev := 0;
- PutRecord(Rec);
- end;
-
- {---------------------------------------------------------------------------}
-
- Constructor DetailFileMaster.Init(Nam : String; Size : Word; Buff : Pointer;
- Put : Boolean);
- begin
- if Size < 8 then
- begin
- WriteLn('Master File Records must be 8 Bytes or more');
- Fail;
- end;
- LabeledFile.Init(Nam,Size,Buff,Put);
- end;
-
- Procedure DetailFileMaster.LinkDetail(DF : DetailFileDetailPtr);
- Var
- Hdr : MasterHeaderPtr;
- begin
- Hdr := RecordPtr;
- DF^.AddRecord;
- DF^.LinkChain(CurRec,Hdr^.Last,DF^.CurRec);
- Hdr^.Last := DF^.CurRec;
- if Hdr^.First = 0 then Hdr^.First := DF^.CurRec;
- PutRecord(CurRec);
- end;
-
- Procedure DetailFileMaster.DelinkDetail(DF : DetailFileDetailPtr; DR :
- LongInt);
- Var
- Hdr : MasterHeaderPtr;
- begin
- Hdr := RecordPtr;
- DF^.GetRecord(DR);
- if Hdr^.Last = DR then
- Hdr^.Last := DetailHeader(DF^.RecordPtr^).Prev;
- if Hdr^.First = DR then
- Hdr^.First := DetailHeader(DF^.RecordPtr^).Next;
- DF^.DelinkChain(DR);
- PutRecord(CurRec);
- end;
-
- Procedure DetailFileMaster.GetFirst(DF : DetailFileDetailPtr);
- Var
- Hdr : MasterHeaderPtr;
- begin
- Hdr := RecordPtr;
- if Hdr^.First = 0 then
- begin
- FillChar(DF^.RecordPtr^,DF^.RecordSize,#0);
- DF^.CurRec := -1;
- Exit;
- end;
- DF^.GetRecord(Hdr^.First);
- end;
-
- Procedure DetailFileMaster.GetLast(DF : DetailFileDetailPtr);
- Var
- Hdr : MasterHeaderPtr;
- begin
- Hdr := RecordPtr;
- if Hdr^.Last = 0 then
- begin
- FillChar(DF^.RecordPtr^,DF^.RecordSize,#0);
- DF^.CurRec := -1;
- Exit;
- end;
- DF^.GetRecord(Hdr^.Last);
- end;
-
- Procedure DetailFileMaster.GetNext(DF : DetailFileDetailPtr);
- Var
- Hdr : DetailHeaderPtr;
- begin
- Hdr := DF^.RecordPtr;
- if Hdr^.Next = 0 then
- begin
- FillChar(DF^.RecordPtr^,DF^.RecordSize,#0);
- DF^.CurRec := -1;
- Exit;
- end;
- DF^.GetRecord(Hdr^.Next);
- end;
-
- Procedure DetailFileMaster.GetPrev(DF : DetailFileDetailPtr);
- Var
- Hdr : DetailHeaderPtr;
- begin
- Hdr := DF^.RecordPtr;
- if Hdr^.Prev = 0 then
- begin
- FillChar(DF^.RecordPtr^,DF^.RecordSize,#0);
- DF^.CurRec := -1;
- Exit;
- end;
- DF^.GetRecord(Hdr^.Prev);
- end;
-
- {---------------------------------------------------------------------------}
-
- begin
- end.
-