lcontrolstack.pp 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. { Control stack
  2. CopyRight (C) 2004-2008 Ales Katona
  3. This library is Free software; you can rediStribute it and/or modify it
  4. under the terms of the GNU Library General Public License as published by
  5. the Free Software Foundation; either version 2 of the License, or (at your
  6. option) any later version.
  7. This program is diStributed in the hope that it will be useful, but WITHOUT
  8. ANY WARRANTY; withOut even the implied warranty of MERCHANTABILITY or
  9. FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License
  10. for more details.
  11. You should have received a Copy of the GNU Library General Public License
  12. along with This library; if not, Write to the Free Software Foundation,
  13. Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  14. This license has been modified. See File LICENSE for more inFormation.
  15. Should you find these sources withOut a LICENSE File, please contact
  16. me at [email protected]
  17. }
  18. unit lControlStack;
  19. {$mode objfpc}
  20. interface
  21. const
  22. TL_CSLENGTH = 3;
  23. type
  24. TLOnFull = procedure of object;
  25. TLControlStack = class
  26. private
  27. FItems: array of Char;
  28. FIndex: Byte;
  29. FAllowInflation: Boolean;
  30. FOnFull: TLOnFull;
  31. function GetFull: Boolean;
  32. function GetItem(const i: Byte): Char;
  33. procedure SetItem(const i: Byte; const Value: Char);
  34. procedure SetAllowInflation(const b: boolean);
  35. public
  36. constructor Create;
  37. procedure Clear;
  38. procedure Push(const Value: Char);
  39. property ItemIndex: Byte read FIndex;
  40. property AllowInflation: Boolean read FAllowInflation write SetAllowInflation;
  41. property Items[i: Byte]: Char read GetItem write SetItem; default;
  42. property Full: Boolean read GetFull;
  43. property OnFull: TLOnFull read FOnFull write FOnFull;
  44. end;
  45. implementation
  46. uses
  47. lTelnet;
  48. (* The normal situation is that there are up to TL_CSLENGTH items on the stack. *)
  49. (* However this may be relaxed in cases (assumed to be rare) where subcommand *)
  50. (* parameters are being accumulated. *)
  51. constructor TLControlStack.Create;
  52. begin
  53. FOnFull:=nil;
  54. FIndex:=0; (* Next insertion point, [0] when empty *)
  55. FAllowInflation := false;
  56. SetLength(FItems, TL_CSLENGTH);
  57. end;
  58. function TLControlStack.GetFull: Boolean;
  59. begin
  60. Result:=False; (* It's full when it has a complete *)
  61. if FIndex >= TL_CSLENGTH then (* command, irrespective of whether the *)
  62. Result:=True; (* stack's inflated by a subcommand. *)
  63. end;
  64. function TLControlStack.GetItem(const i: Byte): Char;
  65. begin
  66. Result:=TS_NOP;
  67. if not FAllowInflation then begin
  68. if i < TL_CSLENGTH then
  69. Result:=FItems[i]
  70. end else
  71. if i < Length(FItems) then
  72. Result:=FItems[i]
  73. end;
  74. procedure TLControlStack.SetItem(const i: Byte; const Value: Char);
  75. begin
  76. if not FAllowInflation then begin
  77. if i < TL_CSLENGTH then
  78. FItems[i]:=Value
  79. end else begin
  80. while i >= Length(FItems) do begin
  81. SetLength(FItems, Length(FItems) + 1);
  82. FItems[Length(FItems) - 1] := TS_NOP
  83. end;
  84. FItems[i] := Value
  85. end
  86. end;
  87. procedure TLControlStack.SetAllowInflation(const b: boolean);
  88. begin
  89. FAllowInflation := b;
  90. if not b then (* No more funny stuff please *)
  91. Clear
  92. end;
  93. procedure TLControlStack.Clear;
  94. begin
  95. FIndex:=0;
  96. FAllowInflation := false;
  97. SetLength(FItems, TL_CSLENGTH) (* In case inflation was allowed *)
  98. end;
  99. procedure TLControlStack.Push(const Value: Char);
  100. begin
  101. if not FAllowInflation then
  102. if FIndex < TL_CSLENGTH then begin
  103. FItems[FIndex]:=Value;
  104. Inc(FIndex)
  105. end else begin end
  106. else begin
  107. SetLength(FItems, Length(FItems) + 1);
  108. FItems[Length(FItems) - 1] := Value;
  109. FIndex := Length(FItems)
  110. end;
  111. if Full and Assigned(FOnFull) then
  112. FOnFull;
  113. end;
  114. end.