unit uStrStck;
{$mode ObjFPC}{$H+}
interface
uses
Classes, SysUtils, Contnrs;
type
{ TStringStack }
TStringStack = class(TObject)
private
fStack: TStack;
function ssStrAlloc(aLen: cardinal): pchar;
function ssStrCopy(aStr: pchar): string;
procedure ssStrDispose(aStr: pchar);
function ssStrFree(aStr: pchar): string;
function ssStrLength(aStr: pchar): cardinal;
function ssStrNew(aStr: string): pchar;
public
constructor Create;
destructor Destroy; override;
procedure Clear;
function Count: ptrint;
function IsEmpty: boolean;
procedure Push(const anItem: string);
function Pop: string;
Function Peek: string;
end;
implementation
{ TStringStack }
function TStringStack.ssStrAlloc(aLen: cardinal): pchar;
begin
inc(aLen,sizeof(cardinal)); // add 4 bytes
getmem(result,aLen); // get total memory
fillchar(Result^,aLen,#0); // initialize total memory to 0
cardinal(pointer(result)^):= aLen; // set length @4 bytes before the actual datapointer
inc(result,sizeof(cardinal)); // set point result to actual data
end;
function TStringStack.ssStrCopy(aStr: pchar): string;
var L: cardinal;
begin
if aStr = nil then exit('');
L:= ssStrLength(aStr)-1; { skip trailing #0 }
SetLength(Result,L);
move(aStr^,Result[1],L); { skip trailing #0 }
end;
procedure TStringStack.ssStrDispose(aStr: pchar);
begin
if (aStr <> nil) then begin
dec(aStr,sizeof(cardinal));
freemem(aStr,cardinal(pointer(aStr)^));
end;
end;
function TStringStack.ssStrFree(aStr: pchar): string;
begin
if (aStr <> nil) then begin
Result:= ssStrCopy(aStr);
ssStrDispose(aStr);
end else exit('');
end;
function TStringStack.ssStrLength(aStr: pchar): cardinal;
begin
if aStr <> nil then Result:= cardinal(pointer(aStr - SizeOf(cardinal))^) - sizeof(cardinal)
else Result:= 0;
end;
function TStringStack.ssStrNew(aStr: string): pchar;
var Len: longint;
begin
Result:= nil;
if aStr = '' then exit;
Len:= Length(aStr)+1; { for the 0# }
Result:= ssStrAlloc(Len);
if Result <> nil then move(aStr[1],Result^,len); { includes terminating null #0 }
end;
constructor TStringStack.Create;
begin
inherited Create;
fStack:= TStack.Create;
end;
destructor TStringStack.Destroy;
begin
clear;
fStack.Free;
inherited Destroy;
end;
procedure TStringStack.Clear;
begin
while not IsEmpty do ssStrDispose(fStack.Pop);
end;
function TStringStack.Count: ptrint;
begin
Result:= fStack.Count;
end;
function TStringStack.IsEmpty: boolean;
begin
Result:= (fStack.Count = 0);
end;
procedure TStringStack.Push(const anItem: string);
begin
fStack.Push(ssStrNew(anItem));
end;
function TStringStack.Pop: string;
begin
Result:= ssStrFree(fStack.Pop);
end;
function TStringStack.Peek: string;
begin
Result:= ssStrCopy(fStack.Peek);
end;
end.