dos_compilers/Borland Turbo Pascal v55/OBJECTS.PAS
2024-07-02 06:49:04 -07:00

459 lines
8.7 KiB
Plaintext
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{ Turbo Objects }
{ Copyright (c) 1989 by Borland International, Inc. }
unit Objects;
{ Turbo Pascal 5.5 object-oriented example.
This unit defines some basic object types.
Refer to OOPDEMOS.DOC for an overview of this unit.
}
{$S-}
interface
const
{ Stream access modes }
SCreate = $3C00; { Create new file }
SOpenRead = $3D00; { Read access only }
SOpenWrite = $3D01; { Write access only }
SOpen = $3D02; { Read and write access }
{ SetPos positioning modes }
PosAbs = 0; { Relative to beginning }
PosCur = 1; { Relative to current position }
PosEnd = 2; { Relative to end }
type
{ General conversion types }
WordRec = record
Lo, Hi: Byte;
end;
LongRec = record
Lo, Hi: Word;
end;
PtrRec = record
Ofs, Seg: Word;
end;
{ Abstract base object type }
BasePtr = ^Base;
Base = object
destructor Done; virtual;
end;
{ Stream type list }
STypeListPtr = ^STypeList;
STypeList = array[1..256] of Word;
{ Stream I/O procedure record }
SProc = object
StoreProc: Pointer;
LoadProc: Pointer;
end;
{ Stream I/O procedure list }
SProcListPtr = ^SProcList;
SProcList = array[1..256] of SProc;
{ Abstract stream object type }
StreamPtr = ^Stream;
Stream = object(Base)
TypeCount: Word;
TypeList: STypeListPtr;
ProcList: SProcListPtr;
Status: Integer;
constructor Init;
destructor Done; virtual;
procedure Error(Code: Integer); virtual;
procedure Flush; virtual;
function GetPos: Longint; virtual;
procedure Read(var Buf; Count: Word); virtual;
procedure RegisterTypes; virtual;
procedure SetPos(Pos: Longint; Mode: Byte); virtual;
procedure Truncate; virtual;
procedure Write(var Buf; Count: Word); virtual;
function Get: BasePtr;
function GetSize: Longint;
procedure Put(B: BasePtr);
procedure Register(TypePtr, StorePtr, LoadPtr: Pointer);
procedure Seek(Pos: Longint);
end;
{ DOS file name string }
FNameStr = string[79];
{ Unbuffered DOS stream }
DosStreamPtr = ^DosStream;
DosStream = object(Stream)
Handle: Word;
constructor Init(FileName: FNameStr; Mode: Word);
destructor Done; virtual;
function GetPos: Longint; virtual;
procedure Read(var Buf; Count: Word); virtual;
procedure SetPos(Pos: Longint; Mode: Byte); virtual;
procedure Truncate; virtual;
procedure Write(var Buf; Count: Word); virtual;
procedure Close;
procedure Open(var Name; Mode: Word);
end;
{ Buffered DOS stream }
BufStreamPtr = ^BufStream;
BufStream = object(DosStream)
Buffer: Pointer;
BufSize: Word;
BufPtr: Word;
BufEnd: Word;
constructor Init(FileName: FNameStr; Mode, Size: Word);
destructor Done; virtual;
procedure Flush; virtual;
function GetPos: Longint; virtual;
procedure Read(var Buf; Count: Word); virtual;
procedure Write(var Buf; Count: Word); virtual;
end;
{ Abstract linked list node type }
NodePtr = ^Node;
Node = object(Base)
Next: NodePtr;
function Prev: NodePtr;
end;
{ Linked list type }
ListPtr = ^List;
List = object
Last: NodePtr;
procedure Append(N: NodePtr);
procedure Clear;
procedure Delete;
function Empty: Boolean;
function First: NodePtr;
procedure Insert(N: NodePtr);
procedure Load(var S: Stream);
function Next(N: NodePtr): NodePtr;
function Prev(N: NodePtr): NodePtr;
procedure Remove(N: NodePtr);
procedure Store(var S: Stream);
end;
{ Abstract notification procedure }
procedure Abstract;
implementation
{$L STREAM} { Stream externals }
{$L DOSSTM} { DosStream externals }
{$L BUFSTM} { BufStream externals }
procedure StreamError; external {STREAM};
{ Base }
destructor Base.Done;
begin
end;
{ Stream }
constructor Stream.Init;
begin
TypeCount := 0;
TypeList := nil;
ProcList := nil;
Status := 0;
RegisterTypes;
GetMem(TypeList, TypeCount * SizeOf(Word));
if TypeList = nil then Fail;
GetMem(ProcList, TypeCount * SizeOf(SProc));
if ProcList = nil then
begin
FreeMem(TypeList, TypeCount * SizeOf(Word));
Fail;
end;
TypeCount := 0;
RegisterTypes;
end;
destructor Stream.Done;
begin
FreeMem(ProcList, TypeCount * SizeOf(SProc));
FreeMem(TypeList, TypeCount * SizeOf(Word));
end;
procedure Stream.Error(Code: Integer);
begin
Status := Code;
end;
procedure Stream.Flush;
begin
end;
function Stream.GetPos: Longint;
begin
Abstract;
end;
procedure Stream.Read(var Buf; Count: Word);
begin
Abstract;
end;
procedure Stream.RegisterTypes;
begin
end;
procedure Stream.SetPos(Pos: Longint; Mode: Byte);
begin
Abstract;
end;
procedure Stream.Truncate;
begin
Abstract;
end;
procedure Stream.Write(var Buf; Count: Word);
begin
Abstract;
end;
function Stream.Get: BasePtr;
external {STREAM};
function Stream.GetSize: Longint;
var
P: Longint;
begin
P := GetPos;
SetPos(0, PosEnd);
GetSize := GetPos;
SetPos(P, PosAbs);
end;
procedure Stream.Put(B: BasePtr);
external {STREAM};
procedure Stream.Register(TypePtr, StorePtr, LoadPtr: Pointer);
begin
Inc(TypeCount);
if TypeList <> nil then
begin
TypeList^[TypeCount] := PtrRec(TypePtr).Ofs;
with ProcList^[TypeCount] do
begin
StoreProc := StorePtr;
LoadProc := LoadPtr;
end;
end;
end;
procedure Stream.Seek(Pos: Longint);
begin
SetPos(Pos, PosAbs);
end;
{ DosStream }
constructor DosStream.Init(FileName: FNameStr; Mode: Word);
var
L: Integer;
begin
if not Stream.Init then Fail;
L := Length(FileName);
Move(FileName[1], FileName[0], L);
FileName[L] := #0;
Open(FileName, Mode);
end;
destructor DosStream.Done;
begin
Close;
Stream.Done;
end;
function DosStream.GetPos: Longint;
external {DOSSTM};
procedure DosStream.Read(var Buf; Count: Word);
external {DOSSTM};
procedure DosStream.SetPos(Pos: Longint; Mode: Byte);
external {DOSSTM};
procedure DosStream.Truncate;
external {DOSSTM};
procedure DosStream.Write(var Buf; Count: Word);
external {DOSSTM};
procedure DosStream.Close;
external {DOSSTM};
procedure DosStream.Open(var Name; Mode: Word);
external {DOSSTM};
{ BufStream }
constructor BufStream.Init(FileName: FNameStr; Mode, Size: Word);
begin
GetMem(Buffer, Size);
if Buffer = nil then Fail;
if not DosStream.Init(FileName, Mode) then
begin
FreeMem(Buffer, Size);
Fail;
end;
BufSize := Size;
BufPtr := 0;
BufEnd := 0;
end;
destructor BufStream.Done;
begin
DosStream.Done;
FreeMem(Buffer, BufSize);
end;
procedure BufStream.Flush;
external {BUFSTM};
function BufStream.GetPos: Longint;
external {BUFSTM};
procedure BufStream.Read(var Buf; Count: Word);
external {BUFSTM};
procedure BufStream.Write(var Buf; Count: Word);
external {BUFSTM};
{ Node }
function Node.Prev: NodePtr;
var
P: NodePtr;
begin
P := @Self;
while P^.Next <> @Self do P := P^.Next;
Prev := P;
end;
{ List }
procedure List.Append(N: NodePtr);
begin
Insert(N);
Last := N;
end;
procedure List.Clear;
begin
Last := nil;
end;
procedure List.Delete;
var
P: NodePtr;
begin
while not Empty do
begin
P := First;
Remove(P);
Dispose(P, Done);
end;
end;
function List.Empty: Boolean;
begin
Empty := Last = nil;
end;
function List.First: NodePtr;
begin
if Last = nil then First := nil else First := Last^.Next;
end;
procedure List.Insert(N: NodePtr);
begin
if Last = nil then Last := N else N^.Next := Last^.Next;
Last^.Next := N;
end;
procedure List.Load(var S: Stream);
var
P: NodePtr;
begin
Clear;
P := NodePtr(S.Get);
while P <> nil do
begin
Append(P);
P := NodePtr(S.Get);
end;
end;
function List.Next(N: NodePtr): NodePtr;
begin
if N = Last then Next := nil else Next := N^.Next;
end;
function List.Prev(N: NodePtr): NodePtr;
begin
if N = First then Prev := nil else Prev := N^.Prev;
end;
procedure List.Remove(N: NodePtr);
var
P: NodePtr;
begin
if Last <> nil then
begin
P := Last;
while (P^.Next <> N) and (P^.Next <> Last) do P := P^.Next;
if P^.Next = N then
begin
P^.Next := N^.Next;
if Last = N then if P = N then Last := nil else Last := P;
end;
end;
end;
procedure List.Store(var S: Stream);
var
P: NodePtr;
begin
P := First;
while P <> nil do
begin
S.Put(P);
P := Next(P);
end;
S.Put(nil);
end;
procedure Abstract;
begin
RunError(211);
end;
end.