From efe845bd1601d29144a7853ab2d1474c7da8c892 Mon Sep 17 00:00:00 2001 From: BaerMitUmlaut Date: Wed, 27 Oct 2021 23:48:12 +0200 Subject: [PATCH] Add support for encoding and decoding JSON with hash maps --- addons/hashes/fnc_encodeJSON.sqf | 14 ++++++++++ addons/hashes/fnc_parseJSON.sqf | 45 ++++++++++++++++++++++---------- addons/hashes/test_parseJSON.sqf | 6 ++--- 3 files changed, 48 insertions(+), 17 deletions(-) diff --git a/addons/hashes/fnc_encodeJSON.sqf b/addons/hashes/fnc_encodeJSON.sqf index d8a08a193f..6f64bb60e2 100644 --- a/addons/hashes/fnc_encodeJSON.sqf +++ b/addons/hashes/fnc_encodeJSON.sqf @@ -16,6 +16,7 @@ Description: - STRING - TASK - TEAM_MEMBER + - HASHMAP - Everything else will simply be stringified. Parameters: @@ -77,6 +78,19 @@ switch (typeName _object) do { }; }; + case "HASHMAP": { + private _json = ((_object toArray false) apply { + _x params ["_key", ["_value", objNull]]; + + if !(_key isEqualType "") then { + _key = str _key; + }; + + format ["%1: %2", [_key] call CBA_fnc_encodeJSON, [_value] call CBA_fnc_encodeJSON] + }) joinString ", "; + "{" + _json + "}" + }; + default { if !(typeName _object in (supportInfo "u:allVariables*" apply {_x splitString " " select 1})) exitWith { [str _object] call CBA_fnc_encodeJSON diff --git a/addons/hashes/fnc_parseJSON.sqf b/addons/hashes/fnc_parseJSON.sqf index 625f1886a5..d3805fd793 100644 --- a/addons/hashes/fnc_parseJSON.sqf +++ b/addons/hashes/fnc_parseJSON.sqf @@ -6,13 +6,15 @@ Description: Deserializes a JSON string. Parameters: - _json - String containing valid JSON. - _useHashes - Output CBA hashes instead of namespaces - (optional, default: false) + _json - String containing valid JSON. + _objectType - Selects the type used for deserializing objects (optional) + 0, false: CBA namespace (default) + 1, true: CBA hash + 2: Native hash map Returns: - _object - The deserialized JSON object or nil if JSON is invalid. - + _object - The deserialized JSON object or nil if JSON is invalid. + Examples: (begin example) @@ -28,18 +30,33 @@ Author: BaerMitUmlaut ---------------------------------------------------------------------------- */ SCRIPT(parseJSON); -params ["_json", ["_useHashes", false]]; +params ["_json", ["_objectType", 0]]; // Wrappers for creating "objects" and setting values on them private ["_objectSet", "_createObject"]; -if (_useHashes) then { - _createObject = CBA_fnc_hashCreate; - _objectSet = CBA_fnc_hashSet; -} else { - _createObject = CBA_fnc_createNamespace; - _objectSet = { - params ["_obj", "_key", "_val"]; - _obj setVariable [_key, _val]; + +switch (_objectType) do { + case false; + case 0: { + _createObject = CBA_fnc_createNamespace; + _objectSet = { + params ["_obj", "_key", "_val"]; + _obj setVariable [_key, _val]; + }; + }; + + case true; + case 1: { + _createObject = CBA_fnc_hashCreate; + _objectSet = CBA_fnc_hashSet; + }; + + case 2: { + _createObject = { createHashMap }; + _objectSet = { + params ["_obj", "_key", "_val"]; + _obj set [_key, _val]; + }; }; }; diff --git a/addons/hashes/test_parseJSON.sqf b/addons/hashes/test_parseJSON.sqf index 9c02c02a99..f22619d2c7 100644 --- a/addons/hashes/test_parseJSON.sqf +++ b/addons/hashes/test_parseJSON.sqf @@ -108,16 +108,16 @@ private _testCases = [ ]; { - private _useHashes = _x; + private _objectType = _x; { diag_log _x; private _input = _x; - private _object = [_x, _useHashes] call CBA_fnc_parseJSON; + private _object = [_x, _objectType] call CBA_fnc_parseJSON; private _output = [_object] call CBA_fnc_encodeJSON; TEST_OP(_input,==,_output,_fn); } forEach _testCases; -} forEach [true, false]; +} forEach [true, false, 0, 1, 2]; // Special test for complex object because properties are unordered private _json = "{""OBJECT"": null, ""BOOL"": true, ""SCALAR"": 1.2, ""STRING"": ""Hello, World!"", ""ARRAY"": [], ""LOCATION"": {}}";