[Back to OOP SWAG index] [Back to Main SWAG index] [Original]
{
LARRY HADLEY
>Right now, I have an Array of Pointers that point to the beginning
>of each page. The entire File is loaded into memory using BlockRead.
>To jump to a page, it checks the current page number, jumps to that
>offset (as specified by the Page Array) and dumps the contents
>to the screen Until it reaches the bottom.
I think I see. You have a monolithic block of memory...problem!
> There are a lot of ways to do it. One way would be to store the
> File as Arrays of *Pointers* to Strings...this would allow 64k of
> *sentences*, not just 64k of Text. It's a Variation on the old
Actually, this is wrong. Since TP use 4 Byte Pointers, you can
only <g> store 16k of sentences in a single Array, but even
though that should still be plenty, you can use linked lists to
overcome that limitation!
>I have an Array of Pointers to the offset of each page. Could you
>provide a short code fragment?
Instead of treating the Pointers as offsets, you should be using
them as actual data collections.
{
*****************************************************************
Strings Unit With StrArray Object. Manage linked lists of Strings
transparently.
By Larry Hadley - May be used freely, provided credit is given
wherever this code is used.
*****************************************************************
}
Unit Strings;
Interface
Type
PString = ^String;
PStringList = ^StringList;
StringList = Record
P : PString;
Next : PStringList;
end;
pStrArray = ^oStrArray;
oStrArray = Object
Root : PStringList;
total : Word;
eolist : Boolean; {end of list - only valid after calling At,
AtInsert, and AtDelete}
Constructor Init;
Destructor Done;
Procedure Insert(s : String);
Procedure Delete;
Function At(item : Word) : PString;
Procedure AtInsert(item : Word; s : String);
Procedure AtDelete(item : Word);
Function First : PString;
Function Last : PString;
Private
Procedure NewNode(N : PStringList);
Function AllocateS(s : String) : PString;
Procedure DeallocateS(Var P : PString);
end;
Implementation
Constructor oStrArray.Init;
begin
Root := NIL;
total := 0;
eolist := False;
end;
Destructor oStrArray.Done;
Var
T : PStringList;
begin
While Root <> NIL do
begin
T := Root^.Next;
if Root^.P <> NIL then
DeallocateS(Root^.P);
Dispose(Root);
Root := T;
end;
end;
Procedure oStrArray.Insert(s : String);
Var
T, T1 : PStringList;
begin
NewNode(T1);
T1^.P := AllocateS(s);
Inc(total);
if Root <> NIL then
begin
T := Root;
While T^.Next <> NIL do
T := T^.Next;
T^.Next := T1;
end
else
Root := T1;
end;
Procedure oStrArray.Delete;
Var
T, T1 : PStringList;
begin
T := Root;
if T <> NIL then
While T^.Next <> NIL do
begin
T1 := T;
T := T^.Next;
end;
T1^.Next := T^.Next;
if T^.P <> NIL then
DeallocateS(T^.P);
Dispose(T);
Dec(total);
end;
Function oStrArray.At(item : Word) : PString;
Var
count : Word;
T : PStringList;
begin
if item>total then
eolist := True
else
eolist := False;
count := 1; {1 based offset}
T := Root;
While (count < item) and (T^.Next <> NIL) do
begin
T := T^.Next;
Inc(count);
end;
At := T^.P;
end;
Procedure oStrArray.AtInsert(item : Word; s : String);
Var
count : Word;
T, T1 : PStringList;
begin
if item > total then
eolist := True
else
eolist := False;
NewNode(T1);
T1^.P := AllocateS(s);
Inc(total);
count := 1;
if Root <> NIL then
begin
T := Root;
While (count < Item) and (T^.Next <> NIL) do
begin
T := T^.Next;
Inc(count);
end;
T1^.Next := T^.Next;
T^.Next := T1;
end
else
Root := T1;
end;
Procedure oStrArray.AtDelete(item : Word);
Var
count : Word;
T, T1 : PStringList;
begin
if item > total then { don't delete if item bigger than list total -
explicit only! }
begin
eolist := True;
Exit;
end
else
eolist := False;
count := 1;
T := Root;
T1 := NIL;
While (count < item) and (T^.Next <> NIL) do
begin
T1 := T;
T := T^.Next;
Inc(count);
end;
if T1 = NIL then
Root := Root^.Next
else
T1^.Next := T^.Next;
DeallocateS(T^.P);
Dispose(T);
Dec(total);
end;
Function oStrArray.First : PString;
begin
First := Root^.P;
end;
Function oStrArray.Last : PString;
Var
T : PStringList;
begin
T := Root;
if T <> NIL then
While T^.Next <> NIL do
T := T^.Next;
Last := T^.P;
end;
Procedure oStrArray.NewNode(N : PStringList);
Var
T : PStringList;
begin
New(T);
T^.Next := NIL;
T^.P := NIL;
if N = NIL then
N := T
else
begin
T^.Next := N^.Next;
N^.Next := T;
end;
end;
Function oStrArray.AllocateS(s : String) : PString;
Var
P : PString;
begin
GetMem(P, Ord(s[0]) + 1);
P^ := s;
AllocateS := P;
end;
Procedure oStrArray.DeallocateS(Var P : PString);
begin
FreeMem(P, Ord(P^[0]) + 1);
P := NIL; {for error checking}
end;
end. {Unit StringS}
{
Code fragment :
Var
TextList : pStrArray;
...
New(TextList, Init);
...
Repeat
ReadLn(TextFile, s);
TextList^.Insert(s);
Until Eof(TextFile) or LowMemory;
...
For Loop := 1 to PageLen do
if Not(TextList^.eolist) then
Writeln(TextList^At(PageTop + Loop)^);
...
etc.
}
[Back to OOP SWAG index] [Back to Main SWAG index] [Original]