home *** CD-ROM | disk | FTP | other *** search
/ BBS 1 / BBS#1.iso / for-dos / newtvsrc.arj / HISTLIST.PAS < prev    next >
Pascal/Delphi Source File  |  1992-10-28  |  5KB  |  248 lines

  1.  
  2. {*******************************************************}
  3. {                                                       }
  4. {       Turbo Pascal Version 7.0                        }
  5. {       Turbo Vision Unit                               }
  6. {                                                       }
  7. {       Copyright (c) 1992 Borland International        }
  8. {                                                       }
  9. {*******************************************************}
  10.  
  11. unit HistList;
  12.  
  13. {$O+,F+,X+,I-,S-}
  14.  
  15. {****************************************************************************
  16.    History buffer structure:
  17.  
  18.     Byte Byte String          Byte Byte String
  19.     +-------------------------+-------------------------+--...--+
  20.     | 0 | Id | History string | 0 | Id | History string |       |
  21.     +-------------------------+-------------------------+--...--+
  22.  
  23.  ***************************************************************************}
  24.  
  25. interface
  26.  
  27. uses Objects;
  28.  
  29. const
  30.   HistoryBlock: Pointer = nil;
  31.   HistorySize: Word = 1024;
  32.   HistoryUsed: Word = 0;
  33.  
  34. procedure HistoryAdd(Id: Byte; const Str: String);
  35. function HistoryCount(Id: Byte): Word;
  36. function HistoryStr(Id: Byte; Index: Integer): String;
  37. procedure ClearHistory;
  38.  
  39. procedure InitHistory;
  40. procedure DoneHistory;
  41.  
  42. procedure StoreHistory(var S: TStream);
  43. procedure LoadHistory(var S: TStream);
  44.  
  45. implementation
  46.  
  47. var
  48.   CurId: Byte;
  49.   CurString: PString;
  50.  
  51. { Advance CurString to next string with an ID of CurId }
  52.  
  53. procedure AdvanceStringPointer; near; assembler;
  54. asm
  55.     PUSH    DS
  56.         MOV     CX,HistoryUsed
  57.         MOV     BL,CurId
  58.     LDS    SI,CurString
  59.         MOV     DX,DS
  60.         MOV     AX,DS
  61.         OR      AX,SI
  62.         JZ      @@3
  63.         CLD
  64.         JMP    @@2
  65. @@1:    LODSW
  66.     CMP    AH,BL { BL = CurId }
  67.         JE    @@3
  68. @@2:    LODSB
  69.         XOR    AH,AH
  70.         ADD    SI,AX
  71.     CMP    SI,CX { CX = HistoryUsed }
  72.         JB    @@1
  73.         XOR    SI,SI
  74.         MOV    DX,SI
  75. @@3:    POP    DS
  76.     MOV    CurString.Word[0],SI
  77.     MOV    CurString.Word[2],DX
  78. end;
  79.  
  80. { Deletes the current string from the table }
  81.  
  82. procedure DeleteString; near; assembler;
  83. asm
  84.     PUSH    DS
  85.         MOV    CX,HistoryUsed
  86.         CLD
  87.         LES    DI,CurString
  88.         MOV     SI,DI
  89.         DEC    DI
  90.         DEC    DI
  91.         PUSH    ES
  92.         POP    DS
  93.         MOV    AL,BYTE PTR [SI]
  94.         XOR    AH,AH
  95.         INC     AX
  96.     ADD    SI,AX
  97.         SUB    CX,SI
  98.         REP    MOVSB
  99.         POP    DS
  100.     MOV    HistoryUsed,DI
  101. end;
  102.  
  103. { Insert a string into the table }
  104.  
  105. procedure InsertString(Id: Byte; const Str: String); near; assembler;
  106. asm
  107.     PUSH    DS
  108.         STD
  109.  
  110.         { Position ES:DI to the end the buffer  }
  111.         {          ES:DX to beginning of buffer }
  112.         LES    DX,HistoryBlock
  113.         MOV    DI,HistoryUsed
  114.     LDS    SI,Str
  115.     MOV    BL,[SI]
  116.         INC    BL
  117.         INC    BL
  118.         INC     BL
  119.         XOR    BH,BH
  120.         POP     DS
  121.         PUSH    DS
  122. @@1:    MOV     AX,DI
  123.         ADD    AX,BX
  124.     SUB    AX,DX { DX = HistoryBlock.Word[0] }
  125.         CMP    AX,HistorySize
  126.         JB    @@2
  127.  
  128.         { Drop the last string off the end of the list }
  129.         DEC     DI
  130.         XOR    AL,AL
  131.         MOV    CX,0FFFFH
  132.         REPNE    SCASB
  133.         INC    DI
  134.         JMP     @@1
  135.  
  136.         { Move the table down the size of the string }
  137. @@2:    MOV    SI,DI
  138.     ADD    DI,BX
  139.         MOV     HistoryUsed,DI
  140.         PUSH    ES
  141.     POP    DS
  142.         MOV    CX,SI
  143.         SUB    CX,DX { DX = HistoryBlock.Word[0] }
  144.     REP    MOVSB
  145.  
  146.         { Copy the string into the position }
  147.         CLD
  148.         MOV     DI,DX { DX = HistoryBlock.Word[0] }
  149.         INC     DI
  150.         MOV    AH,Id
  151.         XOR    AL,AL
  152.     STOSW
  153.         LDS    SI,Str
  154.         LODSB
  155.         STOSB
  156.         MOV    CL,AL
  157.         XOR    CH,CH
  158.         REP    MOVSB
  159.  
  160.         POP    DS
  161. end;
  162.  
  163. procedure StartId(Id: Byte); near;
  164. begin
  165.   CurId := Id;
  166.   CurString := HistoryBlock;
  167. end;
  168.  
  169. function HistoryCount(Id: Byte): Word;
  170. var
  171.   Count: Word;
  172. begin
  173.   StartId(Id);
  174.   Count := 0;
  175.   AdvanceStringPointer;
  176.   while CurString <> nil do
  177.   begin
  178.     Inc(Count);
  179.     AdvanceStringPointer;
  180.   end;
  181.   HistoryCount := Count;
  182. end;
  183.  
  184. procedure HistoryAdd(Id: Byte; const Str: String);
  185. begin
  186.   if Str = '' then Exit;
  187.  
  188.   StartId(Id);
  189.  
  190.   { Delete duplicates }
  191.   AdvanceStringPointer;
  192.   while CurString <> nil do
  193.   begin
  194.     if Str = CurString^ then DeleteString;
  195.     AdvanceStringPointer;
  196.   end;
  197.  
  198.   InsertString(Id, Str);
  199. end;
  200.  
  201. function HistoryStr(Id: Byte; Index: Integer): String;
  202. var
  203.   I: Integer;
  204. begin
  205.   StartId(Id);
  206.   for I := 0 to Index do AdvanceStringPointer;
  207.   if CurString <> nil then
  208.     HistoryStr := CurString^ else
  209.     HistoryStr := '';
  210. end;
  211.  
  212. procedure ClearHistory;
  213. begin
  214.   PChar(HistoryBlock)^ := #0;
  215.   HistoryUsed := PtrRec(HistoryBlock).Ofs + 1;
  216. end;
  217.  
  218. procedure StoreHistory(var S: TStream);
  219. var
  220.   Size: Word;
  221. begin
  222.   Size := HistoryUsed - PtrRec(HistoryBlock).Ofs;
  223.   S.Write(Size, SizeOf(Word));
  224.   S.Write(HistoryBlock^, Size);
  225. end;
  226.  
  227. procedure LoadHistory(var S: TStream);
  228. var
  229.   Size: Word;
  230. begin
  231.   S.Read(Size, SizeOf(Word));
  232.   S.Read(HistoryBlock^, Size);
  233.   HistoryUsed := PtrRec(HistoryBlock).Ofs + Size;
  234. end;
  235.  
  236. procedure InitHistory;
  237. begin
  238.   GetMem(HistoryBlock, HistorySize);
  239.   ClearHistory;
  240. end;
  241.  
  242. procedure DoneHistory;
  243. begin
  244.   FreeMem(HistoryBlock, HistorySize);
  245. end;
  246.  
  247. end.
  248.