diff --git a/sources/Text/JSON/JSONAPI.uc b/sources/Text/JSON/JSONAPI.uc index 9caf7f8..3c425e2 100644 --- a/sources/Text/JSON/JSONAPI.uc +++ b/sources/Text/JSON/JSONAPI.uc @@ -1381,6 +1381,93 @@ private final function int GetEscapedVersion(int codePoint) return codePoint; } +/** + * Performs a deep copy of the `inputData`. This means it copies not only + * `inputData` itself, but (in case it is a container) all of the values + * within it, instead of simply storing the same references (as opposed to + * shallow copy). Stored values also recursively deep copied. + * + * @param inputData Data to copy. Can be any JSON-compatible value. + * @return Copy of the `inputData`. Any non-JSON values are copied as `none`. + */ +public final function AcediaObject Copy(AcediaObject inputData) +{ + if (inputData == none) { + return none; + } + if (inputData.class == class'IntBox') { + return _.box.int(IntBox(inputData).Get()); + } + if (inputData.class == class'IntRef') { + return _.ref.int(IntRef(inputData).Get()); + } + if (inputData.class == class'BoolBox') { + return _.box.bool(BoolBox(inputData).Get()); + } + if (inputData.class == class'BoolRef') { + return _.ref.bool(BoolRef(inputData).Get()); + } + if (inputData.class == class'FloatBox') { + return _.box.float(FloatBox(inputData).Get()); + } + if (inputData.class == class'FloatRef') { + return _.ref.float(FloatRef(inputData).Get()); + } + if (inputData.class == class'Text') { + return Text(inputData).Copy(); + } + if (inputData.class == class'MutableText') { + return MutableText(inputData).MutableCopy(); + } + if (inputData.class == class'ArrayList') { + return CopyArrayList(ArrayList(inputData)); + } + if (inputData.class == class'HashTable') { + return CopyHashTable(HashTable(inputData)); + } + return none; +} + +private final function ArrayList CopyArrayList(ArrayList inputList) +{ + local int i, inputListLength; + local ArrayList result; + local AcediaObject nextObject, nextCopy; + + result = _.collections.EmptyArrayList(); + inputListLength = inputList.GetLength(); + for (i = 0; i < inputListLength; i += 1) + { + nextObject = inputList.GetItem(i); + nextCopy = Copy(nextObject); + result.AddItem(nextCopy); + _.memory.Free(nextCopy); + _.memory.Free(nextObject); + } + return result; +} + +private final function HashTable CopyHashTable(HashTable inputTable) +{ + local int i; + local HashTable result; + local array textKeys; + local AcediaObject nextObject, nextCopy; + + result = _.collections.EmptyHashTable(); + textKeys = inputTable.GetTextKeys(); + for (i = 0; i < textKeys.length; i += 1) + { + nextObject = inputTable.GetItem(textKeys[i]); + nextCopy = Copy(nextObject); + result.SetItem(textKeys[i], nextCopy); + _.memory.Free(nextCopy); + _.memory.Free(nextObject); + } + _.memory.FreeMany(textKeys); + return result; +} + defaultproperties { MAX_FLOAT_PRECISION = 4