home *** CD-ROM | disk | FTP | other *** search
- {
- 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.
- }