- edited description
dwsJson Clone do not copy FItemIndex
I noticed that TdwsJSONObject.DoClone or TdwsJSONArray.DoClone do not copy FItemIndex field. As a result, I cannot get the item name from the Owner.Names property after I get a clone of my json object.
You can see my suggested fix bellow.
function TdwsJSONObject.DoClone: TdwsJSONValue;
var
obj: TdwsJSONObject;
member: TdwsJSONValue;
i: Integer;
begin
obj := TdwsJSONObject.Create;
obj.SetCapacity(FCount);
obj.FCount := FCount;
obj.FItemIndex := FItemIndex; //I added this line
for i := 0 to FCount-1 do begin
obj.FItems[i].Name := FItems[i].Name;
obj.FItems[i].Hash := FItems[i].Hash;
member := FItems[i].Value.Clone;
member.FOwner := obj;
obj.FItems[i].Value := member;
end;
Result := obj;
end;
function TdwsJSONArray.DoClone: TdwsJSONValue;
var
arr: TdwsJSONArray;
elem: TdwsJSONValue;
i: Integer;
begin
arr := TdwsJSONArray.Create;
arr.SetCapacity(FCount);
arr.FCount := FCount;
arr.FItemIndex := FItemIndex; //I added this line
for i := 0 to FCount-1 do begin
elem := FElements^[i].Clone;
elem.FOwner := Self;
arr.FElements^[i] := elem;
end;
Result := arr;
end;
Comments (6)
-
reporter -
repo owner Hi, I do not have an FItemIndex field here, are you using an older version ?
Alternatively, would you have a minimal snippet that would reproduce the issue ? Thanks!
-
reporter It looks like I do have an older or modified version here, anyway, that is the way I found to get the object name for an object in a hierarchy.
For instance, if we have the follow JSON:
{ "objectName": { "objectItem1": { "prop": 1 }, "objectItem2": { "prop": 2 } } }
And I need to get the name of the object that contains “prop” I’d do that:
procedure TesteSuperJSON.TesteTemp(); const str = '{"objectName": {"objectItem1": { "prop": 1 }, "objectItem2": { "prop": 2 } } }'; var json: TdwsJSONValue; item: TdwsJSONValue; i: Integer; begin json := TdwsJSONValue.ParseString(str); i := 0; for item in json.Items['objectName'] do begin Specify.That(item.ToString(), Should.&Not.Equal('')); //Here we have '{"prop":1}' we don't have the property name. //Without FItemIndex, the only way to get the name, is by calculating its Index. Specify.That(item.Owner.Names[i], Should.Equal('objectItem' + IntToStr(i+1))); //But, with FItemIndex I can easily get it this way and get rid of the aux "i" variable. Specify.That(item.Owner.Names[item.ItemIndex], Should.Equal('objectItem' + IntToStr(i+1))); Inc(i); end; end;
As I could see, that is not a bug, since FItemIndex is no part of the official dwsjson library, but It could be an improvement. The best of scenarios would be if we have a property “TdwsJSONValue.Name” that gets the name of the object inside the hierarchy, like it:
property Name: string read GetName; .... function TdwsJSONValue.GetName() begin Result := Owner.Names[ItemIndex]; end;
Regards!
-
reporter -
repo owner I am a bit uncertain of the use case…
If the JSON is dynamically constructed/manipulated, maintaining the FItemIndex would be quite detrimental as the index is both heavily subject to change and meaningless for a JSON object (it’s an hashmap).
When the JSON is static (such as after parsing), it is bound to be hierarchically traversed, so the parent’s name is either known, or only useful for debugging purposes, in which case a “slow” computation (without a maintained FItemIndex) would be enough.Is there another use case I am failing to see ?
-
repo owner - changed status to closed
- Log in to comment