Follow along with the video below to see how to install our site as a web app on your home screen.
Note: This feature may not be available in some browsers.
const
Delim = '|';
var
L: TStringList;
S, T: String
P, Z: Integer;
begin
L:= TStringList.Create;
try
S:= FullStringToBeParsed; //Grab a copy of the full string which needs to be parsed
P:= Pos(Delim, S); //Find the position of the next deliminator
T:= Copy(S, 1, P-1); //Copy up to the deliminator
Delete(S, 1, P); //Delete up to and including the deliminator
Z:= StrToIntDef(T, 0); //Convert copied string to integer for the size
T:= Copy(S, 1, Z); //Copy the amount of data as the size
Delete(S, 1, Z); //Delete what was copied
L.Add(T); //Add the copied data to the list
finally
L.Free;
end;
end;
unit JD.Utils;
interface
uses
Winapi.Windows, System.Classes, System.SysUtils;
const
JD_DELIM = '|';
type
TJDParseList = class(TPersistent)
private
FList: TStringList;
FLock: TRTLCriticalSection;
FDelim: String;
FPrefix: String;
function Lock: TStringList;
procedure Unlock;
function GetAsString: String;
procedure SetAsString(const Value: String);
procedure SetDelim(const Value: String);
procedure SetPrefix(const Value: String);
function GetItem(Index: Integer): String;
procedure SetItem(Index: Integer; const Value: String);
public
constructor Create; overload;
constructor Create(const Data: String); overload;
destructor Destroy; override;
procedure Clear;
function Count: Integer;
procedure Add(const S: String);
procedure Delete(const Index: Integer);
procedure Insert(const S: String; const Index: Integer);
property Items[Index: Integer]: String read GetItem write SetItem;
published
property Deliminator: String read FDelim write SetDelim;
property Prefix: String read FPrefix write SetPrefix;
property AsString: String read GetAsString write SetAsString;
end;
function GetToDelim(var S: String; const Delim: String = JD_DELIM): String;
function CopyDel(var S: String; const Index, Count: Integer): String;
function ParseNext(const Value: String): String;
function SizedText(const S: String; const Delim: String = JD_DELIM): String;
implementation
{ Global }
function GetToDelim(var S: String; const Delim: String = JD_DELIM): String;
var
P: Integer;
begin
Result:= ''; //Initialize result
P:= Pos(JD_DELIM, S); //Identify delim position
if P > 0 then begin //Make sure delim exists
Result:= Copy(S, 1, P-1); //Copy data to result without delim
Delete(S, 1, P); //Delete copied data and delim
end;
end;
function CopyDel(var S: String; const Index, Count: Integer): String;
begin
Result:= Copy(S, Index, Count); //Copy data to result
Delete(S, Index, Count); //Delete copied data
end;
function ParseNext(const Value: String): String;
var
S: String;
Z: Integer;
begin
Result:= ''; //Initialize result
S:= Value; //Copy value to temp
Z:= StrToIntDef(GetToDelim(S), 0); //Extract data size
Result:= CopyDel(S, 1, Z); //Extract data to result
end;
function SizedText(const S: String; const Delim: String = JD_DELIM): String;
begin
Result:= IntToStr(Length(S)) + Delim + S;
end;
{ TJDParseList }
constructor TJDParseList.Create;
begin
inherited Create;
FDelim:= '|';
FPrefix:= '';
FList:= TStringList.Create;
InitializeCriticalSection(FLock);
end;
constructor TJDParseList.Create(const Data: String);
begin
Create;
AsString:= Data;
end;
destructor TJDParseList.Destroy;
begin
DeleteCriticalSection(FLock);
FList.Free;
inherited;
end;
procedure TJDParseList.SetDelim(const Value: String);
begin
if Length(Value) = 1 then begin
FDelim := Value;
end else begin
raise Exception.Create('Deliminator must be 1 character.');
end;
end;
procedure TJDParseList.SetPrefix(const Value: String);
begin
FPrefix := Value;
end;
function TJDParseList.Lock: TStringList;
begin
Result:= nil;
EnterCriticalSection(FLock);
Result:= FList;
end;
procedure TJDParseList.Unlock;
begin
LeaveCriticalSection(FLock);
end;
procedure TJDParseList.Add(const S: String);
var
L: TStringList;
begin
L:= Lock;
try
L.Add(S);
finally
Unlock;
end;
end;
procedure TJDParseList.Clear;
var
L: TStringList;
begin
L:= Lock;
try
L.Clear;
finally
Unlock;
end;
end;
function TJDParseList.Count: Integer;
var
L: TStringList;
begin
Result:= 0;
L:= Lock;
try
Result:= L.Count;
finally
Unlock;
end;
end;
procedure TJDParseList.Delete(const Index: Integer);
var
L: TStringList;
begin
L:= Lock;
try
L.Delete(Index);
finally
Unlock;
end;
end;
procedure TJDParseList.SetItem(Index: Integer; const Value: String);
var
L: TStringList;
begin
L:= Lock;
try
L[Index]:= Value;
finally
Unlock;
end;
end;
function TJDParseList.GetItem(Index: Integer): String;
var
L: TStringList;
begin
Result:= '';
L:= Lock;
try
Result:= L[Index];
finally
Unlock;
end;
end;
procedure TJDParseList.Insert(const S: String; const Index: Integer);
var
L: TStringList;
begin
L:= Lock;
try
L.Insert(Index, S);
finally
Unlock;
end;
end;
function TJDParseList.GetAsString: String;
var
X: Integer;
L: TStringList;
begin
Result:= '';
L:= Lock;
try
Result:= FPrefix + FDelim;
Result:= Result + IntToStr(L.Count) + FDelim;
for X := 0 to L.Count - 1 do
Result:= Result + SizedText(L[X]);
finally
Unlock;
end;
end;
procedure TJDParseList.SetAsString(const Value: String);
var
T, S: String;
P, C, X: Integer;
L: TStringList;
begin
S:= Value;
P:= Pos(FDelim, S);
T:= Copy(S, 1, P-1);
System.Delete(S, 1, P);
if T = FPrefix then begin
L:= Lock;
try
L.Clear;
P:= Pos(FDelim, S);
T:= Copy(S, 1, P-1);
System.Delete(S, 1, P);
C:= StrToIntDef(T, 0);
for X := 0 to C - 1 do begin
P:= Pos(FDelim, S);
T:= Copy(S, 1, P-1);
System.Delete(S, 1, P);
P:= StrToIntDef(T, 0);
T:= Copy(S, 1, P);
System.Delete(S, 1, P);
L.Append(T);
end;
finally
Unlock;
end;
end else begin
raise Exception.Create('Prefix does not match.');
end;
end;
end.