11-- ----------------------------------------------------------------------------
22-- G N A T C O L L --
33-- --
4- -- Copyright (C) 2011-2022 , AdaCore --
4+ -- Copyright (C) 2011-2024 , AdaCore --
55-- --
66-- This library is free software; you can redistribute it and/or modify it --
77-- under terms of the GNU General Public License as published by the Free --
@@ -38,6 +38,8 @@ package body GNATCOLL.JSON is
3838 new Ada.Unchecked_Deallocation (JSON_Array_Internal, JSON_Array_Access);
3939 procedure Free is
4040 new Ada.Unchecked_Deallocation (JSON_Object_Internal, JSON_Object_Access);
41+ procedure Free is
42+ new Ada.Unchecked_Deallocation (JSON_String_Internal, JSON_String_Access);
4143
4244 procedure Write
4345 (Item : JSON_Value;
@@ -673,7 +675,7 @@ package body GNATCOLL.JSON is
673675 end ;
674676
675677 when JSON_String_Type =>
676- Append (Ret, JSON.Utility.Escape_String (Item.Data.Str_Value));
678+ Append (Ret, JSON.Utility.Escape_String (Item.Data.Str_Value.Str ));
677679
678680 when JSON_Array_Type =>
679681 Append (Ret, ' [' );
@@ -718,14 +720,14 @@ package body GNATCOLL.JSON is
718720 Do_Indent (Indent + 1 );
719721 Append
720722 (Ret,
721- GNATCOLL.JSON.Utility.Escape_String (Element (J).Key ));
723+ GNATCOLL.JSON.Utility.Escape_String (Key (J)));
722724
723725 Append (Ret, ' :' );
724726 if not Compact then
725727 Append (Ret, ' ' );
726728 end if ;
727729
728- Write (Element (J).Val , Compact, Indent + 1 , Ret);
730+ Write (Element (J), Compact, Indent + 1 , Ret);
729731
730732 Next (J);
731733
@@ -823,19 +825,14 @@ package body GNATCOLL.JSON is
823825 (Val : in out JSON_Value;
824826 Less : access function (Left, Right : JSON_Value) return Boolean)
825827 is
826- function " <" (Left, Right : Object_Item) return Boolean;
827-
828- function " <" (Left, Right : Object_Item) return Boolean is
829- begin
830- return Less (Left.Val, Right.Val);
831- end " <" ;
832-
833- package Sorting is new Object_Items_Pkg.Generic_Sorting (" <" );
828+ -- package Sorting is new Object_Items_Pkg.Generic_Sorting ("<");
834829
835830 begin
836831 case Val.Kind is
837832 when JSON_Array_Type => Sort (Val.Data.Arr_Value.Arr, Less);
838- when JSON_Object_Type => Sorting.Sort (Val.Data.Obj_Value.Vals);
833+ when JSON_Object_Type =>
834+ -- Sorting.Sort (Val.Data.Obj_Value.Vals);
835+ null ;
839836 when others => null ;
840837 end case ;
841838 end Sort ;
@@ -893,6 +890,10 @@ package body GNATCOLL.JSON is
893890 overriding procedure Adjust (Obj : in out JSON_Value) is
894891 begin
895892 case Obj.Data.Kind is
893+ when JSON_String_Type =>
894+ if Obj.Data.Str_Value /= null then
895+ Increment (Obj.Data.Str_Value.Cnt);
896+ end if ;
896897 when JSON_Array_Type =>
897898 if Obj.Data.Arr_Value /= null then
898899 Increment (Obj.Data.Arr_Value.Cnt);
@@ -913,6 +914,12 @@ package body GNATCOLL.JSON is
913914 overriding procedure Finalize (Obj : in out JSON_Value) is
914915 begin
915916 case Obj.Data.Kind is
917+ when JSON_String_Type =>
918+ if Obj.Data.Str_Value /= null and then
919+ Decrement (Obj.Data.Str_Value.Cnt)
920+ then
921+ Free (Obj.Data.Str_Value);
922+ end if ;
916923 when JSON_Array_Type =>
917924 declare
918925 Arr : JSON_Array_Access := Obj.Data.Arr_Value;
@@ -992,23 +999,31 @@ package body GNATCOLL.JSON is
992999 function Create (Val : UTF8_String) return JSON_Value is
9931000 Ret : JSON_Value;
9941001 begin
995- Ret.Data := (JSON_String_Type, Str_Value => <>);
996- Ret.Data.Str_Value.Set (Val);
1002+ Ret.Data := (
1003+ Kind => JSON_String_Type,
1004+ Str_Value => new JSON_String_Internal'
1005+ (Cnt => 1 , Str => Null_XString));
1006+ Ret.Data.Str_Value.Str.Set (Val);
9971007 return Ret;
9981008 end Create ;
9991009
10001010 function Create (Val : UTF8_Unbounded_String) return JSON_Value is
10011011 Ret : JSON_Value;
10021012 begin
1003- Ret.Data := (Kind => JSON_String_Type, Str_Value => Null_XString);
1004- Ret.Data.Str_Value.Set (To_String (Val));
1013+ Ret.Data := (
1014+ Kind => JSON_String_Type,
1015+ Str_Value => new JSON_String_Internal'
1016+ (Cnt => 1 , Str => Null_XString));
1017+ Ret.Data.Str_Value.Str.Set (To_String (Val));
10051018 return Ret;
10061019 end Create ;
10071020
10081021 function Create (Val : UTF8_XString) return JSON_Value is
10091022 Ret : JSON_Value;
10101023 begin
1011- Ret.Data := (Kind => JSON_String_Type, Str_Value => Val);
1024+ Ret.Data := (
1025+ Kind => JSON_String_Type,
1026+ Str_Value => new JSON_String_Internal'(Cnt => 1 , Str => Val));
10121027 return Ret;
10131028 end Create ;
10141029
@@ -1040,14 +1055,10 @@ package body GNATCOLL.JSON is
10401055 (Val : JSON_Value;
10411056 Field_Name : UTF8_String)
10421057 is
1043- Vals : Object_Items_Pkg.Vector renames Val.Data.Obj_Value.Vals;
1058+ use Object_Items_Pkg;
1059+ Vals : Object_Items_Pkg.Map renames Val.Data.Obj_Value.Vals;
10441060 begin
1045- for J in Vals.First_Index .. Vals.Last_Index loop
1046- if Vals.Element (J).Key = Field_Name then
1047- Val.Data.Obj_Value.Vals.Delete (J);
1048- return ;
1049- end if ;
1050- end loop ;
1061+ Exclude (Vals, To_XString (Field_Name));
10511062 end Unset_Field ;
10521063
10531064 -- -------------
@@ -1059,37 +1070,21 @@ package body GNATCOLL.JSON is
10591070 Field_Name : UTF8_String;
10601071 Field : JSON_Value)
10611072 is
1062- Vals : Object_Items_Pkg.Vector renames Val.Data.Obj_Value.Vals;
1073+ use Object_Items_Pkg;
1074+ Vals : Object_Items_Pkg.Map renames Val.Data.Obj_Value.Vals;
10631075 begin
1064- for J in Vals.First_Index .. Vals.Last_Index loop
1065- if Field_Name = Vals.Element (J).Key then
1066- Vals.Replace_Element (J, (Vals.Element (J).Key, Field));
1067- return ;
1068- end if ;
1069- end loop ;
1070-
1071- Vals.Append
1072- (Object_Item'(Key => To_XString (Field_Name),
1073- Val => Field));
1076+ Include (Vals, To_XString (Field_Name), Field);
10741077 end Set_Field ;
10751078
10761079 procedure Set_Field
10771080 (Val : JSON_Value;
10781081 Field_Name : UTF8_XString;
10791082 Field : JSON_Value)
10801083 is
1081- Vals : Object_Items_Pkg.Vector renames Val.Data.Obj_Value.Vals;
1084+ use Object_Items_Pkg;
1085+ Vals : Object_Items_Pkg.Map renames Val.Data.Obj_Value.Vals;
10821086 begin
1083- for J in Vals.First_Index .. Vals.Last_Index loop
1084- if Field_Name = Vals.Element (J).Key then
1085- Vals.Replace_Element (J, (Field_Name, Field));
1086- return ;
1087- end if ;
1088- end loop ;
1089-
1090- Vals.Append
1091- (Object_Item'(Key => Field_Name,
1092- Val => Field));
1087+ Include (Vals, Field_Name, Field);
10931088 end Set_Field ;
10941089
10951090 procedure Set_Field
@@ -1236,32 +1231,33 @@ package body GNATCOLL.JSON is
12361231
12371232 function Get (Val : JSON_Value) return UTF8_String is
12381233 begin
1239- return To_String (Val.Data.Str_Value);
1234+ return To_String (Val.Data.Str_Value.Str );
12401235 end Get ;
12411236
12421237 function Get (Val : JSON_Value) return UTF8_XString is
12431238 begin
1244- return Val.Data.Str_Value;
1239+ return Val.Data.Str_Value.Str ;
12451240 end Get ;
12461241
12471242 function Get (Val : JSON_Value) return UTF8_Unbounded_String is
12481243 begin
1249- return To_Unbounded_String (Val.Data.Str_Value.To_String);
1244+ return To_Unbounded_String (Val.Data.Str_Value.Str. To_String);
12501245 end Get ;
12511246
12521247 function Get
12531248 (Val : JSON_Value;
12541249 Field : UTF8_String) return JSON_Value
12551250 is
1256- Vals : Object_Items_Pkg.Vector renames Val.Data.Obj_Value.Vals;
1251+ use Object_Items_Pkg;
1252+ Vals : Object_Items_Pkg.Map renames Val.Data.Obj_Value.Vals;
1253+ Result : Object_Items_Pkg.Cursor;
12571254 begin
1258- for J in Vals.First_Index .. Vals.Last_Index loop
1259- if Field = Vals.Element (J).Key then
1260- return Vals.Element (J).Val;
1261- end if ;
1262- end loop ;
1263-
1264- return JSON_Null;
1255+ Result := Find (Vals, To_XString (Field));
1256+ if Has_Element (Result) then
1257+ return Element (Result);
1258+ else
1259+ return JSON_Null;
1260+ end if ;
12651261 end Get ;
12661262
12671263 function Get (Val : JSON_Value) return JSON_Array is
@@ -1274,11 +1270,10 @@ package body GNATCOLL.JSON is
12741270 -- -------------
12751271
12761272 function Has_Field (Val : JSON_Value; Field : UTF8_String) return Boolean is
1277- Vals : Object_Items_Pkg.Vector renames Val.Data.Obj_Value.Vals;
1273+ use Object_Items_Pkg;
1274+ Vals : Object_Items_Pkg.Map renames Val.Data.Obj_Value.Vals;
12781275 begin
1279- return
1280- (for some J in Vals.First_Index .. Vals.Last_Index =>
1281- Field = Vals.Element (J).Key);
1276+ return Has_Element (Find (Vals, To_XString (Field)));
12821277 end Has_Field ;
12831278
12841279 -- -------
@@ -1348,7 +1343,7 @@ package body GNATCOLL.JSON is
13481343 return Create (Val.Data.Flt_Value);
13491344
13501345 when JSON_String_Type =>
1351- return Create (Val.Data.Str_Value);
1346+ return Create (Val.Data.Str_Value.Str );
13521347
13531348 when JSON_Array_Type =>
13541349 declare
@@ -1365,10 +1360,14 @@ package body GNATCOLL.JSON is
13651360
13661361 when JSON_Object_Type =>
13671362 declare
1363+ use Object_Items_Pkg;
13681364 Result : constant JSON_Value := Create_Object;
1365+ From_Cursor : Cursor := Val.Data.Obj_Value.Vals.First;
13691366 begin
1370- for E of Val.Data.Obj_Value.Vals loop
1371- Result.Set_Field (To_String (E.Key), Clone (E.Val));
1367+ while Has_Element (From_Cursor) loop
1368+ Result.Set_Field
1369+ (Key (From_Cursor), Clone (Element (From_Cursor)));
1370+ Next (From_Cursor);
13721371 end loop ;
13731372 return Result;
13741373 end ;
@@ -1380,7 +1379,6 @@ package body GNATCOLL.JSON is
13801379 -- -------
13811380
13821381 function "=" (Left, Right : JSON_Value) return Boolean is
1383- Found : Boolean;
13841382 begin
13851383 if Left.Data.Kind /= Right.Data.Kind then
13861384 return False;
@@ -1400,7 +1398,7 @@ package body GNATCOLL.JSON is
14001398 return Left.Data.Flt_Value = Right.Data.Flt_Value;
14011399
14021400 when JSON_String_Type =>
1403- return Left.Data.Str_Value = Right.Data.Str_Value;
1401+ return Left.Data.Str_Value. all = Right.Data.Str_Value. all ;
14041402
14051403 when JSON_Array_Type =>
14061404 -- Same pointer ?
@@ -1430,24 +1428,12 @@ package body GNATCOLL.JSON is
14301428 then
14311429 return False;
14321430 else
1433- -- We have the same number of elements, and no duplicates
1434- for L of Left.Data.Obj_Value.Vals loop
1435- Found := False;
1436- for R of Right.Data.Obj_Value.Vals loop
1437- if R.Key = L.Key then
1438- if not (R.Val = L.Val) then -- recursive
1439- return False;
1440- end if ;
1441- Found := True;
1442- exit ;
1443- end if ;
1444- end loop ;
1445-
1446- if not Found then
1447- return False;
1448- end if ;
1449- end loop ;
1450- return True;
1431+ declare
1432+ use Object_Items_Pkg;
1433+ begin
1434+ return Left.Data.Obj_Value.Vals =
1435+ Right.Data.Obj_Value.Vals;
1436+ end ;
14511437 end if ;
14521438 end case ;
14531439 end "=" ;
@@ -1460,10 +1446,12 @@ package body GNATCOLL.JSON is
14601446 (Val : JSON_Value;
14611447 CB : access procedure (Name : UTF8_String; Value : JSON_Value))
14621448 is
1463- Vals : Object_Items_Pkg.Vector renames Val.Data.Obj_Value.Vals;
1449+ use Object_Items_Pkg;
1450+ C : Cursor := Val.Data.Obj_Value.Vals.First;
14641451 begin
1465- for J in Vals.First_Index .. Vals.Last_Index loop
1466- CB (To_String (Vals.Element (J).Key), Vals.Element (J).Val);
1452+ while Has_Element (C) loop
1453+ CB (To_String (Key (C)), Element (C));
1454+ Next (C);
14671455 end loop ;
14681456 end Map_JSON_Object ;
14691457
0 commit comments