Skip to content

Porting to Delphi & Path find with dot #19

@hafedh-trimeche

Description

@hafedh-trimeche

Trying to compile JsonTools under Delphi 10.3 some warnings and hints are issued:

The TEnumConverter is used to handle enum types.

{$IF FPC}
{$mode delphi}
{$ENDIF}
[dcc32 Warning] jsontools.pas(326): W1050 WideChar reduced to byte char in set expressions.  Consider using 'CharInSet' function in 'SysUtils' unit.

[dcc32 Hint] jsontools.pas(944): H2443 Inline function 'TList.Remove' has not been expanded because unit 'System.Types' is not specified in USES list

[dcc32 Warning] jsontools.pas(978): W1035 Return value of function 'TJsonNode.Child' might be undefined

The Find function would be replaced by PathToObject to meet path access using (.) delimiter:

  TEnumConverter = class
  public
    class function ToStr<T>(AValue:T):string;
    class function FromStr<T>(AValue:string):T;
  end;

  TJsonData       = TJsonNode;
  TJsonDataHelper = class helper for TJsonData
  private
    function  GetString(const Path:string):string;
    procedure SetString(const Path:string;const AValue:string);
  public
    function  PathToObject(const PathOrIndex:Variant;const NodeKing:TJsonNodeKind=nkNull):TJsonData;
    procedure E_<T>(AName:string;AValue:T);overload;
    procedure _E<T>(AName:string;out AValue:T);overload;
 end;

class function TEnumConverter.ToStr<T>(AValue:T): string;
var
  IEnum : Integer;
begin
  IEnum := 0;
  Move(AValue,IEnum,SizeOf(T));
  Result := GetEnumName(TypeInfo(T),IEnum);
end;

class function TEnumConverter.FromStr<T>(AValue:string):T;
var
  IEnum : Integer;
begin
  IEnum := GetEnumValue(TypeInfo(T),AValue);
  Move(IEnum,Result,SizeOf(T));
end;

function TJsonDataHelper.PathToObject(const PathOrIndex:Variant;const NodeKing:TJsonNodeKind):TJsonData;
var
  sPath   : string;
  i       : Integer;
  Strings : TStringDynArray;
  LObject : TJsonData;
procedure AdjustPath(var Path:string);
begin
  Path := Trim(Path);
  if (Path<>'') and (Path[Length(Path)]='.') then SetLength(Path,Length(Path)-1);
end;
begin
  if VarType(PathOrIndex)=vtInteger then
  begin
    Result := Child(Integer(PathOrIndex)-1);
    Exit;
  end;
  Result := Self;
  sPath  := string(PathOrIndex);
  AdjustPath(sPath);
  if sPath='' then Exit;
  Strings := SplitString(sPath,'.');
  for i:=0 to Length(Strings)-1 do
  begin
    LObject := Result.Child(Strings[i]);
    if (LObject=nil) and (NodeKing<>nkNull) then LObject := Result.Add(Strings[i],NodeKing);
    Result := LObject;
    if Result=nil then Break;
  end;
end;

function TJsonDataHelper.GetString(const Path:string):string;
var
  JsonData : TJsonData;
begin
  Lock;
  JsonData := PathToObject(Path,nkNull);
  if Assigned(JsonData) then Result := JsonData.AsString
                        else Result := '';
  Unlock;
end;

procedure TJsonDataHelper.SetString(const Path:string;const AValue:string);
var
  JsonData : TJsonData;
begin
  Lock;
  JsonData := PathToObject(Path,nkString);
  if Assigned(JsonData) then JsonData.AsString := AValue;
  Unlock;
end;

procedure TJsonDataHelper.E_<T>(AName:string;AValue:T);
var
  sEnum :string;
begin
  sEnum := TEnumConverter.ToStr(AValue);
  SetString(AName,sEnum);
end;

procedure TJsonDataHelper._E<T>(AName:string;out AValue:T);
begin
  AValue := TEnumConverter.FromStr<T>(GetString(AName));
end;

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions