Skip to content

Commit b672552

Browse files
committed
Json: keep item order when renaming key & make sure to truncate file on save
1 parent 6a0747c commit b672552

File tree

2 files changed

+30
-4
lines changed

2 files changed

+30
-4
lines changed

Source/simba.json.pas

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -229,10 +229,31 @@ procedure TSimbaJSONItemHelper.SetAsUnicodeString(AValue: UnicodeString);
229229
end;
230230

231231
procedure TSimbaJSONItemHelper.SetKey(Index: Integer; AValue: String);
232+
var
233+
Items: array of record
234+
Key: TJSONStringType;
235+
Value: TJSONData;
236+
end;
237+
I: Integer;
232238
begin
233239
CheckIsObject();
240+
if (Index < 0) or (Index >= TJSONObject(Self).Count) then
241+
SimbaException('Index %d is out of range', [Index]);
242+
243+
// not ideal since FPC doesn't provide access to FHashList but should be fine
244+
// no new objects are made, just rehashing
245+
SetLength(Items, TJSONObject(Self).Count);
246+
I := High(Items); // looping down probs more efficent for deletes
247+
while (TJSONObject(Self).Count > 0) do
248+
begin
249+
Items[I].Key := TJSONObject(Self).Names[I];
250+
Items[I].Value := TJSONObject(Self).Extract(I);
251+
Dec(I);
252+
end;
234253

235-
TJSONObject(Self).Add(AValue, TJSONObject(Self).Extract(Index));
254+
Items[Index].Key := AValue;
255+
for I := 0 to High(Items) do
256+
TJSONObject(Self).Add(Items[I].Key, Items[I].Value);
236257
end;
237258

238259
procedure TSimbaJSONItemHelper.Add(AKey: String; Value: TSimbaJSONItem);
@@ -461,7 +482,7 @@ procedure TSimbaJSONItemHelper.Save(FileName: String; Options: EJSONFormatOption
461482
else
462483
Stream := TFileStream.Create(FileName, fmCreate);
463484
try
464-
Stream.Write(Text[1], Length(Text));
485+
Stream.Size := Stream.Write(Text[1], Length(Text));
465486
finally
466487
Stream.Free();
467488
end;

Tests/json.simba

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,13 @@ begin
5858
' "obj" : {}' + LINE_SEP +
5959
'}'
6060
);
61-
json.Key[0] := 'text';
62-
Assert(json.Has('text', EJSONType.STR));
61+
62+
Assert(json.key[0] = 'str');
63+
Assert(json.key[4] = 'arr');
64+
json.Key[0] := 'str_but_renamed';
65+
json.Key[4] := 'arr_but_renamed';
66+
Assert(json.key[0] = 'str_but_renamed');
67+
Assert(json.key[4] = 'arr_but_renamed');
6368
end;
6469

6570
procedure TestParseArray;

0 commit comments

Comments
 (0)