Refactor JSON implementation
Change base class for JSON objects from `Object` to `AcediaObject`. Rename some classes/functions/structures/variables to be more compact and/or better convey their meaning. Add appropriate API that contains constructors for JSON objects.
This commit is contained in:
		
							parent
							
								
									076ebe8fcf
								
							
						
					
					
						commit
						53caa5766f
					
				@ -21,14 +21,14 @@
 | 
				
			|||||||
 * You should have received a copy of the GNU General Public License
 | 
					 * You should have received a copy of the GNU General Public License
 | 
				
			||||||
 * along with Acedia.  If not, see <https://www.gnu.org/licenses/>.
 | 
					 * along with Acedia.  If not, see <https://www.gnu.org/licenses/>.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
class JSONArray extends JSONBase;
 | 
					class JArray extends JSON;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//  Data will simply be stored as an array of JSON values
 | 
					//  Data will simply be stored as an array of JSON values
 | 
				
			||||||
var private array<JSONStorageValue> data;
 | 
					var private array<JStorageAtom> data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//  Return type of value stored at a given index.
 | 
					//  Return type of value stored at a given index.
 | 
				
			||||||
//  Returns `JSON_Undefined` if and only if given index is out of bounds.
 | 
					//  Returns `JSON_Undefined` if and only if given index is out of bounds.
 | 
				
			||||||
public final function JSONType GetType(int index)
 | 
					public final function JType GetTypeOf(int index)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    if (index < 0)              return JSON_Undefined;
 | 
					    if (index < 0)              return JSON_Undefined;
 | 
				
			||||||
    if (index >= data.length)   return JSON_Undefined;
 | 
					    if (index >= data.length)   return JSON_Undefined;
 | 
				
			||||||
@ -105,22 +105,22 @@ public final function bool IsNull(int index)
 | 
				
			|||||||
    return (data[index].type == JSON_Null);
 | 
					    return (data[index].type == JSON_Null);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public final function JSONArray GetArray(int index)
 | 
					public final function JArray GetArray(int index)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    if (index < 0)                      return none;
 | 
					    if (index < 0)                      return none;
 | 
				
			||||||
    if (index >= data.length)           return none;
 | 
					    if (index >= data.length)           return none;
 | 
				
			||||||
    if (data[index].type != JSON_Array) return none;
 | 
					    if (data[index].type != JSON_Array) return none;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return JSONArray(data[index].complexValue);
 | 
					    return JArray(data[index].complexValue);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public final function JSONObject GetObject(int index)
 | 
					public final function JObject GetObject(int index)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    if (index < 0)                          return none;
 | 
					    if (index < 0)                          return none;
 | 
				
			||||||
    if (index >= data.length)               return none;
 | 
					    if (index >= data.length)               return none;
 | 
				
			||||||
    if (data[index].type != JSON_Object)    return none;
 | 
					    if (data[index].type != JSON_Object)    return none;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return JSONObject(data[index].complexValue);
 | 
					    return JObject(data[index].complexValue);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//      Following functions provide simple setters for boolean, string, number
 | 
					//      Following functions provide simple setters for boolean, string, number
 | 
				
			||||||
@ -132,14 +132,14 @@ public final function JSONObject GetObject(int index)
 | 
				
			|||||||
//  `false` (nothing will be done in this case).
 | 
					//  `false` (nothing will be done in this case).
 | 
				
			||||||
//      They return object itself, allowing user to chain calls like this:
 | 
					//      They return object itself, allowing user to chain calls like this:
 | 
				
			||||||
//  `array.SetNumber("num1", 1).SetNumber("num2", 2);`.
 | 
					//  `array.SetNumber("num1", 1).SetNumber("num2", 2);`.
 | 
				
			||||||
public final function JSONArray SetNumber
 | 
					public final function JArray SetNumber
 | 
				
			||||||
(
 | 
					(
 | 
				
			||||||
    int index,
 | 
					    int index,
 | 
				
			||||||
    float value,
 | 
					    float value,
 | 
				
			||||||
    optional bool preventExpansion
 | 
					    optional bool preventExpansion
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    local JSONStorageValue newStorageValue;
 | 
					    local JStorageAtom newStorageValue;
 | 
				
			||||||
    if (index < 0) return self;
 | 
					    if (index < 0) return self;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (index >= data.length)
 | 
					    if (index >= data.length)
 | 
				
			||||||
@ -159,14 +159,14 @@ public final function JSONArray SetNumber
 | 
				
			|||||||
    return self;
 | 
					    return self;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public final function JSONArray SetString
 | 
					public final function JArray SetString
 | 
				
			||||||
(
 | 
					(
 | 
				
			||||||
    int index,
 | 
					    int index,
 | 
				
			||||||
    string value,
 | 
					    string value,
 | 
				
			||||||
    optional bool preventExpansion
 | 
					    optional bool preventExpansion
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    local JSONStorageValue newStorageValue;
 | 
					    local JStorageAtom newStorageValue;
 | 
				
			||||||
    if (index < 0) return self;
 | 
					    if (index < 0) return self;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (index >= data.length)
 | 
					    if (index >= data.length)
 | 
				
			||||||
@ -186,14 +186,14 @@ public final function JSONArray SetString
 | 
				
			|||||||
    return self;
 | 
					    return self;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public final function JSONArray SetBoolean
 | 
					public final function JArray SetBoolean
 | 
				
			||||||
(
 | 
					(
 | 
				
			||||||
    int index,
 | 
					    int index,
 | 
				
			||||||
    bool value,
 | 
					    bool value,
 | 
				
			||||||
    optional bool preventExpansion
 | 
					    optional bool preventExpansion
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    local JSONStorageValue newStorageValue;
 | 
					    local JStorageAtom newStorageValue;
 | 
				
			||||||
    if (index < 0) return self;
 | 
					    if (index < 0) return self;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (index >= data.length)
 | 
					    if (index >= data.length)
 | 
				
			||||||
@ -213,13 +213,13 @@ public final function JSONArray SetBoolean
 | 
				
			|||||||
    return self;
 | 
					    return self;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public final function JSONArray SetNull
 | 
					public final function JArray SetNull
 | 
				
			||||||
(
 | 
					(
 | 
				
			||||||
    int index,
 | 
					    int index,
 | 
				
			||||||
    optional bool preventExpansion
 | 
					    optional bool preventExpansion
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    local JSONStorageValue newStorageValue;
 | 
					    local JStorageAtom newStorageValue;
 | 
				
			||||||
    if (index < 0) return self;
 | 
					    if (index < 0) return self;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (index >= data.length)
 | 
					    if (index >= data.length)
 | 
				
			||||||
@ -247,13 +247,13 @@ public final function JSONArray SetNull
 | 
				
			|||||||
//  `false` (nothing will be done in this case).
 | 
					//  `false` (nothing will be done in this case).
 | 
				
			||||||
//      They return object itself, allowing user to chain calls like this:
 | 
					//      They return object itself, allowing user to chain calls like this:
 | 
				
			||||||
//  `array.CreateObject("sub object").CreateArray("sub array");`.
 | 
					//  `array.CreateObject("sub object").CreateArray("sub array");`.
 | 
				
			||||||
public final function JSONArray CreateArray
 | 
					public final function JArray CreateArray
 | 
				
			||||||
(
 | 
					(
 | 
				
			||||||
    int index,
 | 
					    int index,
 | 
				
			||||||
    optional bool preventExpansion
 | 
					    optional bool preventExpansion
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    local JSONStorageValue newStorageValue;
 | 
					    local JStorageAtom newStorageValue;
 | 
				
			||||||
    if (index < 0) return self;
 | 
					    if (index < 0) return self;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (index >= data.length)
 | 
					    if (index >= data.length)
 | 
				
			||||||
@ -268,18 +268,18 @@ public final function JSONArray CreateArray
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    newStorageValue.type            = JSON_Array;
 | 
					    newStorageValue.type            = JSON_Array;
 | 
				
			||||||
    newStorageValue.complexValue    = new class'JSONArray';
 | 
					    newStorageValue.complexValue    = _.json.newArray();
 | 
				
			||||||
    data[index] = newStorageValue;
 | 
					    data[index] = newStorageValue;
 | 
				
			||||||
    return self;
 | 
					    return self;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public final function JSONArray CreateObject
 | 
					public final function JArray CreateObject
 | 
				
			||||||
(
 | 
					(
 | 
				
			||||||
    int index,
 | 
					    int index,
 | 
				
			||||||
    optional bool preventExpansion
 | 
					    optional bool preventExpansion
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    local JSONStorageValue newStorageValue;
 | 
					    local JStorageAtom newStorageValue;
 | 
				
			||||||
    if (index < 0) return self;
 | 
					    if (index < 0) return self;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (index >= data.length)
 | 
					    if (index >= data.length)
 | 
				
			||||||
@ -294,51 +294,51 @@ public final function JSONArray CreateObject
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    newStorageValue.type            = JSON_Object;
 | 
					    newStorageValue.type            = JSON_Object;
 | 
				
			||||||
    newStorageValue.complexValue    = new class'JSONObject';
 | 
					    newStorageValue.complexValue    = _.json.newObject();
 | 
				
			||||||
    data[index] = newStorageValue;
 | 
					    data[index] = newStorageValue;
 | 
				
			||||||
    return self;
 | 
					    return self;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//      Wrappers for setter functions that don't take index or
 | 
					//      Wrappers for setter functions that don't take index or
 | 
				
			||||||
//  `preventExpansion` parameters and add/create value at the end of the array.
 | 
					//  `preventExpansion` parameters and add/create value at the end of the array.
 | 
				
			||||||
public final function JSONArray AddNumber(float value)
 | 
					public final function JArray AddNumber(float value)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    return SetNumber(data.length, value);
 | 
					    return SetNumber(data.length, value);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public final function JSONArray AddString(string value)
 | 
					public final function JArray AddString(string value)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    return SetString(data.length, value);
 | 
					    return SetString(data.length, value);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public final function JSONArray AddBoolean(bool value)
 | 
					public final function JArray AddBoolean(bool value)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    return SetBoolean(data.length, value);
 | 
					    return SetBoolean(data.length, value);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public final function JSONArray AddNull()
 | 
					public final function JArray AddNull()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    return SetNull(data.length);
 | 
					    return SetNull(data.length);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public final function JSONArray AddArray()
 | 
					public final function JArray AddArray()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    return CreateArray(data.length);
 | 
					    return CreateArray(data.length);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public final function JSONArray AddObject()
 | 
					public final function JArray AddObject()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    return CreateObject(data.length);
 | 
					    return CreateObject(data.length);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//  Removes up to `amount` of values, starting from a given index.
 | 
					//  Removes up to `amount` (minimum of `1`) of values, starting from
 | 
				
			||||||
 | 
					//  a given index.
 | 
				
			||||||
//      If `index` falls outside array boundaries - nothing will be done.
 | 
					//      If `index` falls outside array boundaries - nothing will be done.
 | 
				
			||||||
//  Returns `true` if value was actually removed and `false` if it didn't exist.
 | 
					//  Returns `true` if value was actually removed and `false` if it didn't exist.
 | 
				
			||||||
public final function bool RemoveValue(int index, optional int amount)
 | 
					public final function bool RemoveValue(int index, optional int amount)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    if (index < 0)              return false;
 | 
					    if (index < 0)              return false;
 | 
				
			||||||
    if (index >= data.length)   return false;
 | 
					    if (index >= data.length)   return false;
 | 
				
			||||||
    if (amount < 1)             return false;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    amount = Max(amount, 1);
 | 
					    amount = Max(amount, 1);
 | 
				
			||||||
    amount = Min(amount, data.length - index);
 | 
					    amount = Min(amount, data.length - index);
 | 
				
			||||||
							
								
								
									
										265
									
								
								sources/Data/JObject.uc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										265
									
								
								sources/Data/JObject.uc
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,265 @@
 | 
				
			|||||||
 | 
					/**
 | 
				
			||||||
 | 
					 *      This class implements JSON object storage capabilities.
 | 
				
			||||||
 | 
					 *      Whenever one wants to store JSON data, they need to define such object.
 | 
				
			||||||
 | 
					 *  It stores name-value pairs, where names are strings and values can be:
 | 
				
			||||||
 | 
					 *      ~ Boolean, string, null or number (float in this implementation) data;
 | 
				
			||||||
 | 
					 *      ~ Other JSON objects;
 | 
				
			||||||
 | 
					 *      ~ JSON Arrays (see `JArray` class).
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *      This implementation provides getters and setters for boolean, string,
 | 
				
			||||||
 | 
					 *  null or number types that allow to freely set and fetch their values
 | 
				
			||||||
 | 
					 *  by name.
 | 
				
			||||||
 | 
					 *      JSON objects and arrays can be fetched by getters, but you cannot
 | 
				
			||||||
 | 
					 *  add existing object or array to another object. Instead one has to create
 | 
				
			||||||
 | 
					 *  a new, empty object with a certain name and then fill it with data.
 | 
				
			||||||
 | 
					 *  This allows to avoid loop situations, where object is contained in itself.
 | 
				
			||||||
 | 
					 *      Functions to remove existing values are also provided and are applicable
 | 
				
			||||||
 | 
					 *  to all variable types.
 | 
				
			||||||
 | 
					 *      Setters can also be used to overwrite any value by a different value,
 | 
				
			||||||
 | 
					 *  even of a different type.
 | 
				
			||||||
 | 
					 *      Copyright 2020 Anton Tarasenko
 | 
				
			||||||
 | 
					 *------------------------------------------------------------------------------
 | 
				
			||||||
 | 
					 * This file is part of Acedia.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Acedia is free software: you can redistribute it and/or modify
 | 
				
			||||||
 | 
					 * it under the terms of the GNU General Public License as published by
 | 
				
			||||||
 | 
					 * the Free Software Foundation, version 3 of the License, or
 | 
				
			||||||
 | 
					 * (at your option) any later version.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Acedia is distributed in the hope that it will be useful,
 | 
				
			||||||
 | 
					 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
 | 
					 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
				
			||||||
 | 
					 * GNU General Public License for more details.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * You should have received a copy of the GNU General Public License
 | 
				
			||||||
 | 
					 * along with Acedia.  If not, see <https://www.gnu.org/licenses/>.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					class JObject extends JSON;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//  We will store all our properties as a simple array of name-value pairs.
 | 
				
			||||||
 | 
					struct JProperty
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    var string          name;
 | 
				
			||||||
 | 
					    var JStorageAtom    value;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					var private array<JProperty> properties;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//  Returns index of name-value pair in `properties` for a given name.
 | 
				
			||||||
 | 
					//  Returns `-1` if such a pair does not exist.
 | 
				
			||||||
 | 
					private final function int GetPropertyIndex(string name)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    local int i;
 | 
				
			||||||
 | 
					    for (i = 0; i < properties.length; i += 1)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if (name == properties[i].name)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            return i;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return -1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//      Returns `JType` of a variable with a given name in our properties.
 | 
				
			||||||
 | 
					//      This function can be used to check if certain variable exists
 | 
				
			||||||
 | 
					//  in this object, since if such variable does not exist -
 | 
				
			||||||
 | 
					//  function will return `JSON_Undefined`.
 | 
				
			||||||
 | 
					public final function JType GetTypeOf(string name)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    local int index;
 | 
				
			||||||
 | 
					    index = GetPropertyIndex(name);
 | 
				
			||||||
 | 
					    if (index < 0) return JSON_Undefined;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return properties[index].value.type;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//      Following functions are getters for various types of variables.
 | 
				
			||||||
 | 
					//      Getter for null value simply checks if it's null
 | 
				
			||||||
 | 
					//  and returns true/false as a result.
 | 
				
			||||||
 | 
					//      Getters for simple types (number, string, boolean) can have optional
 | 
				
			||||||
 | 
					//  default value specified, that will be returned if requested variable
 | 
				
			||||||
 | 
					//  doesn't exist or has a different type.
 | 
				
			||||||
 | 
					//      Getters for object and array types don't take default values and
 | 
				
			||||||
 | 
					//  will simply return `none`.
 | 
				
			||||||
 | 
					public final function float GetNumber(string name, optional float defaultValue)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    local int index;
 | 
				
			||||||
 | 
					    index = GetPropertyIndex(name);
 | 
				
			||||||
 | 
					    if (index < 0)                                      return defaultValue;
 | 
				
			||||||
 | 
					    if (properties[index].value.type != JSON_Number)    return defaultValue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return properties[index].value.numberValue;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public final function string GetString
 | 
				
			||||||
 | 
					(
 | 
				
			||||||
 | 
					    string name,
 | 
				
			||||||
 | 
					    optional string defaultValue
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    local int index;
 | 
				
			||||||
 | 
					    index = GetPropertyIndex(name);
 | 
				
			||||||
 | 
					    if (index < 0)                                      return defaultValue;
 | 
				
			||||||
 | 
					    if (properties[index].value.type != JSON_String)    return defaultValue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return properties[index].value.stringValue;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public final function bool GetBoolean(string name, optional bool defaultValue)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    local int index;
 | 
				
			||||||
 | 
					    index = GetPropertyIndex(name);
 | 
				
			||||||
 | 
					    if (index < 0)                                      return defaultValue;
 | 
				
			||||||
 | 
					    if (properties[index].value.type != JSON_Boolean)   return defaultValue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return properties[index].value.booleanValue;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public final function bool IsNull(string name)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    local int index;
 | 
				
			||||||
 | 
					    index = GetPropertyIndex(name);
 | 
				
			||||||
 | 
					    if (index < 0)                                  return false;
 | 
				
			||||||
 | 
					    if (properties[index].value.type != JSON_Null)  return false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return (properties[index].value.type == JSON_Null);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public final function JArray GetArray(string name)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    local int index;
 | 
				
			||||||
 | 
					    index = GetPropertyIndex(name);
 | 
				
			||||||
 | 
					    if (index < 0)                                  return none;
 | 
				
			||||||
 | 
					    if (properties[index].value.type != JSON_Array) return none;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return JArray(properties[index].value.complexValue);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public final function JObject GetObject(string name)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    local int index;
 | 
				
			||||||
 | 
					    index = GetPropertyIndex(name);
 | 
				
			||||||
 | 
					    if (index < 0)                                      return none;
 | 
				
			||||||
 | 
					    if (properties[index].value.type != JSON_Object)    return none;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return JObject(properties[index].value.complexValue);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//      Following functions provide simple setters for boolean, string, number
 | 
				
			||||||
 | 
					//  and null values.
 | 
				
			||||||
 | 
					//      They return object itself, allowing user to chain calls like this:
 | 
				
			||||||
 | 
					//  `object.SetNumber("num1", 1).SetNumber("num2", 2);`.
 | 
				
			||||||
 | 
					public final function JObject SetNumber(string name, float value)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    local int       index;
 | 
				
			||||||
 | 
					    local JProperty newProperty;
 | 
				
			||||||
 | 
					    index = GetPropertyIndex(name);
 | 
				
			||||||
 | 
					    if (index < 0)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        index = properties.length;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    newProperty.name                = name;
 | 
				
			||||||
 | 
					    newProperty.value.type          = JSON_Number;
 | 
				
			||||||
 | 
					    newProperty.value.numberValue   = value;
 | 
				
			||||||
 | 
					    properties[index] = newProperty;
 | 
				
			||||||
 | 
					    return self;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public final function JObject SetString(string name, string value)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    local int       index;
 | 
				
			||||||
 | 
					    local JProperty newProperty;
 | 
				
			||||||
 | 
					    index = GetPropertyIndex(name);
 | 
				
			||||||
 | 
					    if (index < 0)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        index = properties.length;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    newProperty.name                = name;
 | 
				
			||||||
 | 
					    newProperty.value.type          = JSON_String;
 | 
				
			||||||
 | 
					    newProperty.value.stringValue   = value;
 | 
				
			||||||
 | 
					    properties[index] = newProperty;
 | 
				
			||||||
 | 
					    return self;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public final function JObject SetBoolean(string name, bool value)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    local int       index;
 | 
				
			||||||
 | 
					    local JProperty newProperty;
 | 
				
			||||||
 | 
					    index = GetPropertyIndex(name);
 | 
				
			||||||
 | 
					    if (index < 0)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        index = properties.length;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    newProperty.name                = name;
 | 
				
			||||||
 | 
					    newProperty.value.type          = JSON_Boolean;
 | 
				
			||||||
 | 
					    newProperty.value.booleanValue  = value;
 | 
				
			||||||
 | 
					    properties[index] = newProperty;
 | 
				
			||||||
 | 
					    return self;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public final function JObject SetNull(string name)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    local int       index;
 | 
				
			||||||
 | 
					    local JProperty newProperty;
 | 
				
			||||||
 | 
					    index = GetPropertyIndex(name);
 | 
				
			||||||
 | 
					    if (index < 0)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        index = properties.length;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    newProperty.name        = name;
 | 
				
			||||||
 | 
					    newProperty.value.type  = JSON_Null;
 | 
				
			||||||
 | 
					    properties[index] = newProperty;
 | 
				
			||||||
 | 
					    return self;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//      JSON array and object types don't have setters, but instead have
 | 
				
			||||||
 | 
					//  functions to create a new, empty array/object under a certain name.
 | 
				
			||||||
 | 
					//      They return object itself, allowing user to chain calls like this:
 | 
				
			||||||
 | 
					//  `object.CreateObject("folded object").CreateArray("names list");`.
 | 
				
			||||||
 | 
					public final function JObject CreateArray(string name)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    local int       index;
 | 
				
			||||||
 | 
					    local JProperty newProperty;
 | 
				
			||||||
 | 
					    index = GetPropertyIndex(name);
 | 
				
			||||||
 | 
					    if (index < 0)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        index = properties.length;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    newProperty.name                = name;
 | 
				
			||||||
 | 
					    newProperty.value.type          = JSON_Array;
 | 
				
			||||||
 | 
					    newProperty.value.complexValue  = _.json.newArray();
 | 
				
			||||||
 | 
					    properties[index] = newProperty;
 | 
				
			||||||
 | 
					    return self;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public final function JObject CreateObject(string name)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    local int       index;
 | 
				
			||||||
 | 
					    local JProperty newProperty;
 | 
				
			||||||
 | 
					    index = GetPropertyIndex(name);
 | 
				
			||||||
 | 
					    if (index < 0)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        index = properties.length;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    newProperty.name                = name;
 | 
				
			||||||
 | 
					    newProperty.value.type          = JSON_Object;
 | 
				
			||||||
 | 
					    newProperty.value.complexValue  = _.json.newObject();
 | 
				
			||||||
 | 
					    properties[index] = newProperty;
 | 
				
			||||||
 | 
					    return self;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//  Removes values with a given name.
 | 
				
			||||||
 | 
					//  Returns `true` if value was actually removed and `false` if it didn't exist.
 | 
				
			||||||
 | 
					public final function bool RemoveValue(string name)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    local int index;
 | 
				
			||||||
 | 
					    index = GetPropertyIndex(name);
 | 
				
			||||||
 | 
					    if (index < 0) return false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    properties.Remove(index, 1);
 | 
				
			||||||
 | 
					    return true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					defaultproperties
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -28,10 +28,11 @@
 | 
				
			|||||||
 * You should have received a copy of the GNU General Public License
 | 
					 * You should have received a copy of the GNU General Public License
 | 
				
			||||||
 * along with Acedia.  If not, see <https://www.gnu.org/licenses/>.
 | 
					 * along with Acedia.  If not, see <https://www.gnu.org/licenses/>.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
class JSONBase extends Object;
 | 
					class JSON extends AcediaActor
 | 
				
			||||||
 | 
					    abstract;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//  Enumeration for possible types of JSON values.
 | 
					//  Enumeration for possible types of JSON values.
 | 
				
			||||||
enum JSONType
 | 
					enum JType
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    //  Technical type, used to indicate that requested value is missing.
 | 
					    //  Technical type, used to indicate that requested value is missing.
 | 
				
			||||||
    //  Undefined values are not part of JSON format.
 | 
					    //  Undefined values are not part of JSON format.
 | 
				
			||||||
@ -53,18 +54,31 @@ enum JSONType
 | 
				
			|||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//  Stores a single JSON value
 | 
					//  Stores a single JSON value
 | 
				
			||||||
struct JSONStorageValue
 | 
					struct JStorageAtom
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    //  What type is stored exactly?
 | 
					    //  What type is stored exactly?
 | 
				
			||||||
    //  Depending on that, uses one of the other fields as a storage.
 | 
					    //  Depending on that, uses one of the other fields as a storage.
 | 
				
			||||||
    var public JSONType     type;
 | 
					    var protected JType     type;
 | 
				
			||||||
    var protected float     numberValue;
 | 
					    var protected float     numberValue;
 | 
				
			||||||
    var protected string    stringValue;
 | 
					    var protected string    stringValue;
 | 
				
			||||||
    var protected bool      booleanValue;
 | 
					    var protected bool      booleanValue;
 | 
				
			||||||
    //  Used for storing both JSON objects and arrays.
 | 
					    //  Used for storing both JSON objects and arrays.
 | 
				
			||||||
    var protected JSONBase  complexValue;
 | 
					    var protected JSON      complexValue;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//  TODO:   Rewrite JSON object to use more efficient storage data structures
 | 
				
			||||||
 | 
					//          that will support subtypes:
 | 
				
			||||||
 | 
					//              ~ Number: byte, int, float
 | 
				
			||||||
 | 
					//              ~ String: string, class
 | 
				
			||||||
 | 
					//          (maybe move to auto generated code?).
 | 
				
			||||||
 | 
					//  TODO:   Add cleanup queue to efficiently and without crashes clean up
 | 
				
			||||||
 | 
					//          removed objects.
 | 
				
			||||||
 | 
					//  TODO:   Add `JValue` - a reference type for number / string / boolean / null
 | 
				
			||||||
 | 
					//  TODO:   Add accessors for last values.
 | 
				
			||||||
 | 
					//  TODO:   Add path-getters.
 | 
				
			||||||
 | 
					//  TODO:   Add iterators.
 | 
				
			||||||
 | 
					//  TODO:   Add parsing/printing.
 | 
				
			||||||
 | 
					//  TODO:   Add functions for deep copy.
 | 
				
			||||||
defaultproperties
 | 
					defaultproperties
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
							
								
								
									
										41
									
								
								sources/Data/JSONAPI.uc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								sources/Data/JSONAPI.uc
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,41 @@
 | 
				
			|||||||
 | 
					/**
 | 
				
			||||||
 | 
					 *      Singleton is an auxiliary class, meant to be used as a base for others,
 | 
				
			||||||
 | 
					 *  that allows for only one instance of it to exist.
 | 
				
			||||||
 | 
					 *      To make sure your child class properly works, either don't overload
 | 
				
			||||||
 | 
					 *  'PreBeginPlay' or make sure to call it's parent's version.
 | 
				
			||||||
 | 
					 *      Copyright 2019 Anton Tarasenko
 | 
				
			||||||
 | 
					 *------------------------------------------------------------------------------
 | 
				
			||||||
 | 
					 * This file is part of Acedia.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Acedia is free software: you can redistribute it and/or modify
 | 
				
			||||||
 | 
					 * it under the terms of the GNU General Public License as published by
 | 
				
			||||||
 | 
					 * the Free Software Foundation, version 3 of the License, or
 | 
				
			||||||
 | 
					 * (at your option) any later version.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Acedia is distributed in the hope that it will be useful,
 | 
				
			||||||
 | 
					 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
 | 
					 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
				
			||||||
 | 
					 * GNU General Public License for more details.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * You should have received a copy of the GNU General Public License
 | 
				
			||||||
 | 
					 * along with Acedia.  If not, see <https://www.gnu.org/licenses/>.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					class JSONAPI extends Singleton;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public function JObject newObject()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    local JObject newObject;
 | 
				
			||||||
 | 
					    newObject = Spawn(class'JObject');
 | 
				
			||||||
 | 
					    return newObject;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public function JArray newArray()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    local JArray newArray;
 | 
				
			||||||
 | 
					    newArray = Spawn(class'JArray');
 | 
				
			||||||
 | 
					    return newArray;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					defaultproperties
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -1,272 +0,0 @@
 | 
				
			|||||||
/**
 | 
					 | 
				
			||||||
 *      This class implements JSON object storage capabilities.
 | 
					 | 
				
			||||||
 *      Whenever one wants to store JSON data, they need to define such object.
 | 
					 | 
				
			||||||
 *  It stores name-value pairs, where names are strings and values can be:
 | 
					 | 
				
			||||||
 *      ~ Boolean, string, null or number (float in this implementation) data;
 | 
					 | 
				
			||||||
 *      ~ Other JSON objects;
 | 
					 | 
				
			||||||
 *      ~ JSON Arrays (see `JSONArray` class).
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 *      This implementation provides getters and setters for boolean, string,
 | 
					 | 
				
			||||||
 *  null or number types that allow to freely set and fetch their values
 | 
					 | 
				
			||||||
 *  by name.
 | 
					 | 
				
			||||||
 *      JSON objects and arrays can be fetched by getters, but you cannot
 | 
					 | 
				
			||||||
 *  add existing object or array to another object. Instead one has to create
 | 
					 | 
				
			||||||
 *  a new, empty object with a certain name and then fill it with data.
 | 
					 | 
				
			||||||
 *  This allows to avoid loop situations, where object is contained in itself.
 | 
					 | 
				
			||||||
 *      Functions to remove existing values are also provided and are applicable
 | 
					 | 
				
			||||||
 *  to all variable types.
 | 
					 | 
				
			||||||
 *      Setters can also be used to overwrite any value by a different value,
 | 
					 | 
				
			||||||
 *  even of a different type.
 | 
					 | 
				
			||||||
 *      Copyright 2020 Anton Tarasenko
 | 
					 | 
				
			||||||
 *------------------------------------------------------------------------------
 | 
					 | 
				
			||||||
 * This file is part of Acedia.
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * Acedia is free software: you can redistribute it and/or modify
 | 
					 | 
				
			||||||
 * it under the terms of the GNU General Public License as published by
 | 
					 | 
				
			||||||
 * the Free Software Foundation, version 3 of the License, or
 | 
					 | 
				
			||||||
 * (at your option) any later version.
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * Acedia is distributed in the hope that it will be useful,
 | 
					 | 
				
			||||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
					 | 
				
			||||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
					 | 
				
			||||||
 * GNU General Public License for more details.
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * You should have received a copy of the GNU General Public License
 | 
					 | 
				
			||||||
 * along with Acedia.  If not, see <https://www.gnu.org/licenses/>.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
class JSONObject extends JSONBase;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
//  We will store all our data as a simple array of key(name)-value pairs.
 | 
					 | 
				
			||||||
struct JSONKeyValuePair
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    var string              key;
 | 
					 | 
				
			||||||
    var JSONStorageValue    value;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
var private array<JSONKeyValuePair> data;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
//  Returns index of key-value pair in `data` with a given key.
 | 
					 | 
				
			||||||
//  Returns `-1` if such a pair does not exist in `data`.
 | 
					 | 
				
			||||||
private final function int GetIndex(string key)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    local int i;
 | 
					 | 
				
			||||||
    for (i = 0; i < data.length; i += 1)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        if (key == data[i].key)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            return i;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    return -1;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
//      Returns `JSONType` of a variable with a given key in our data.
 | 
					 | 
				
			||||||
//      This function can be used to check if certain variable exists
 | 
					 | 
				
			||||||
//  in this object, since if such variable does not exist -
 | 
					 | 
				
			||||||
//  function will return `JSON_Undefined`.
 | 
					 | 
				
			||||||
public final function JSONType GetType(string key)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    local int index;
 | 
					 | 
				
			||||||
    index = GetIndex(key);
 | 
					 | 
				
			||||||
    if (index < 0) return JSON_Undefined;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return data[index].value.type;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
//      Following functions are getters for various types of variables.
 | 
					 | 
				
			||||||
//      Getter for null value simply checks if it's null
 | 
					 | 
				
			||||||
//  and returns true/false as a result.
 | 
					 | 
				
			||||||
//      Getters for simple types (number, string, boolean) can have optional
 | 
					 | 
				
			||||||
//  default value specified, that will be returned if requested variable
 | 
					 | 
				
			||||||
//  doesn't exist or has a different type.
 | 
					 | 
				
			||||||
//      Getters for object and array types don't take default values and
 | 
					 | 
				
			||||||
//  will simply return `none`.
 | 
					 | 
				
			||||||
public final function float GetNumber(string key, optional float defaultValue)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    local int index;
 | 
					 | 
				
			||||||
    index = GetIndex(key);
 | 
					 | 
				
			||||||
    if (index < 0)                              return defaultValue;
 | 
					 | 
				
			||||||
    if (data[index].value.type != JSON_Number)  return defaultValue;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return data[index].value.numberValue;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
public final function string GetString(string key, optional string defaultValue)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    local int index;
 | 
					 | 
				
			||||||
    index = GetIndex(key);
 | 
					 | 
				
			||||||
    if (index < 0)                              return defaultValue;
 | 
					 | 
				
			||||||
    if (data[index].value.type != JSON_String)  return defaultValue;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return data[index].value.stringValue;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
public final function bool GetBoolean(string key, optional bool defaultValue)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    local int index;
 | 
					 | 
				
			||||||
    index = GetIndex(key);
 | 
					 | 
				
			||||||
    if (index < 0)                              return defaultValue;
 | 
					 | 
				
			||||||
    if (data[index].value.type != JSON_Boolean) return defaultValue;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return data[index].value.booleanValue;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
public final function bool IsNull(string key)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    local int index;
 | 
					 | 
				
			||||||
    index = GetIndex(key);
 | 
					 | 
				
			||||||
    if (index < 0)                              return false;
 | 
					 | 
				
			||||||
    if (data[index].value.type != JSON_Null)    return false;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return (data[index].value.type == JSON_Null);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
public final function JSONArray GetArray(string key)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    local int index;
 | 
					 | 
				
			||||||
    index = GetIndex(key);
 | 
					 | 
				
			||||||
    if (index < 0)                              return none;
 | 
					 | 
				
			||||||
    if (data[index].value.type != JSON_Array)   return none;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return JSONArray(data[index].value.complexValue);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
public final function JSONObject GetObject(string key)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    local int index;
 | 
					 | 
				
			||||||
    index = GetIndex(key);
 | 
					 | 
				
			||||||
    if (index < 0)                              return none;
 | 
					 | 
				
			||||||
    if (data[index].value.type != JSON_Object)  return none;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return JSONObject(data[index].value.complexValue);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
//      Following functions provide simple setters for boolean, string, number
 | 
					 | 
				
			||||||
//  and null values.
 | 
					 | 
				
			||||||
//      They return object itself, allowing user to chain calls like this:
 | 
					 | 
				
			||||||
//  `object.SetNumber("num1", 1).SetNumber("num2", 2);`.
 | 
					 | 
				
			||||||
public final function JSONObject SetNumber(string key, float value)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    local int               index;
 | 
					 | 
				
			||||||
    local JSONKeyValuePair  newKeyValuePair;
 | 
					 | 
				
			||||||
    local JSONStorageValue  newStorageValue;
 | 
					 | 
				
			||||||
    index = GetIndex(key);
 | 
					 | 
				
			||||||
    if (index < 0)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        index = data.length;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    newStorageValue.type        = JSON_Number;
 | 
					 | 
				
			||||||
    newStorageValue.numberValue = value;
 | 
					 | 
				
			||||||
    newKeyValuePair.key     = key;
 | 
					 | 
				
			||||||
    newKeyValuePair.value   = newStorageValue;
 | 
					 | 
				
			||||||
    data[index] = newKeyValuePair;
 | 
					 | 
				
			||||||
    return self;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
public final function JSONObject SetString(string key, string value)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    local int               index;
 | 
					 | 
				
			||||||
    local JSONKeyValuePair  newKeyValuePair;
 | 
					 | 
				
			||||||
    local JSONStorageValue  newStorageValue;
 | 
					 | 
				
			||||||
    index = GetIndex(key);
 | 
					 | 
				
			||||||
    if (index < 0)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        index = data.length;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    newStorageValue.type        = JSON_String;
 | 
					 | 
				
			||||||
    newStorageValue.stringValue = value;
 | 
					 | 
				
			||||||
    newKeyValuePair.key     = key;
 | 
					 | 
				
			||||||
    newKeyValuePair.value   = newStorageValue;
 | 
					 | 
				
			||||||
    data[index] = newKeyValuePair;
 | 
					 | 
				
			||||||
    return self;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
public final function JSONObject SetBoolean(string key, bool value)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    local int               index;
 | 
					 | 
				
			||||||
    local JSONKeyValuePair  newKeyValuePair;
 | 
					 | 
				
			||||||
    local JSONStorageValue  newStorageValue;
 | 
					 | 
				
			||||||
    index = GetIndex(key);
 | 
					 | 
				
			||||||
    if (index < 0)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        index = data.length;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    newStorageValue.type            = JSON_Boolean;
 | 
					 | 
				
			||||||
    newStorageValue.booleanValue    = value;
 | 
					 | 
				
			||||||
    newKeyValuePair.key     = key;
 | 
					 | 
				
			||||||
    newKeyValuePair.value   = newStorageValue;
 | 
					 | 
				
			||||||
    data[index] = newKeyValuePair;
 | 
					 | 
				
			||||||
    return self;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
public final function JSONObject SetNull(string key)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    local int               index;
 | 
					 | 
				
			||||||
    local JSONKeyValuePair  newKeyValuePair;
 | 
					 | 
				
			||||||
    local JSONStorageValue  newStorageValue;
 | 
					 | 
				
			||||||
    index = GetIndex(key);
 | 
					 | 
				
			||||||
    if (index < 0)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        index = data.length;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    newStorageValue.type    = JSON_Null;
 | 
					 | 
				
			||||||
    newKeyValuePair.key     = key;
 | 
					 | 
				
			||||||
    newKeyValuePair.value   = newStorageValue;
 | 
					 | 
				
			||||||
    data[index] = newKeyValuePair;
 | 
					 | 
				
			||||||
    return self;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
//      JSON array and object types don't have setters, but instead have
 | 
					 | 
				
			||||||
//  functions to create a new, empty array/object under a certain name.
 | 
					 | 
				
			||||||
//      They return object itself, allowing user to chain calls like this:
 | 
					 | 
				
			||||||
//  `object.CreateObject("folded object").CreateArray("names list");`.
 | 
					 | 
				
			||||||
public final function JSONObject CreateArray(string key)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    local int               index;
 | 
					 | 
				
			||||||
    local JSONKeyValuePair  newKeyValuePair;
 | 
					 | 
				
			||||||
    local JSONStorageValue  newStorageValue;
 | 
					 | 
				
			||||||
    index = GetIndex(key);
 | 
					 | 
				
			||||||
    if (index < 0)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        index = data.length;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    newStorageValue.type            = JSON_Array;
 | 
					 | 
				
			||||||
    newStorageValue.complexValue    = new class'JSONArray';
 | 
					 | 
				
			||||||
    newKeyValuePair.key     = key;
 | 
					 | 
				
			||||||
    newKeyValuePair.value   = newStorageValue;
 | 
					 | 
				
			||||||
    data[index] = newKeyValuePair;
 | 
					 | 
				
			||||||
    return self;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
public final function JSONObject CreateObject(string key)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    local int               index;
 | 
					 | 
				
			||||||
    local JSONKeyValuePair  newKeyValuePair;
 | 
					 | 
				
			||||||
    local JSONStorageValue  newStorageValue;
 | 
					 | 
				
			||||||
    index = GetIndex(key);
 | 
					 | 
				
			||||||
    if (index < 0)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        index = data.length;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    newStorageValue.type            = JSON_Object;
 | 
					 | 
				
			||||||
    newStorageValue.complexValue    = new class'JSONObject';
 | 
					 | 
				
			||||||
    newKeyValuePair.key     = key;
 | 
					 | 
				
			||||||
    newKeyValuePair.value   = newStorageValue;
 | 
					 | 
				
			||||||
    data[index] = newKeyValuePair;
 | 
					 | 
				
			||||||
    return self;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
//  Removes values with a given name.
 | 
					 | 
				
			||||||
//  Returns `true` if value was actually removed and `false` if it didn't exist.
 | 
					 | 
				
			||||||
public final function bool RemoveValue(string key)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    local int index;
 | 
					 | 
				
			||||||
    index = GetIndex(key);
 | 
					 | 
				
			||||||
    if (index < 0) return false;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    data.Remove(index, 1);
 | 
					 | 
				
			||||||
    return true;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
defaultproperties
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,6 +1,6 @@
 | 
				
			|||||||
/**
 | 
					/**
 | 
				
			||||||
 *      Set of tests for JSON data storage, implemented via
 | 
					 *      Set of tests for JSON data storage, implemented via
 | 
				
			||||||
 *  `JSONObject` and `JSONArray`.
 | 
					 *  `JObject` and `JArray`.
 | 
				
			||||||
 *      Copyright 2020 Anton Tarasenko
 | 
					 *      Copyright 2020 Anton Tarasenko
 | 
				
			||||||
 *------------------------------------------------------------------------------
 | 
					 *------------------------------------------------------------------------------
 | 
				
			||||||
 * This file is part of Acedia.
 | 
					 * This file is part of Acedia.
 | 
				
			||||||
@ -23,8 +23,8 @@ class TEST_JSON extends TestCase
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
protected static function TESTS()
 | 
					protected static function TESTS()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    local JSONObject jsonData;
 | 
					    local JObject jsonData;
 | 
				
			||||||
    jsonData = new class'JSONObject';
 | 
					    jsonData = _().json.newObject();
 | 
				
			||||||
    Test_ObjectGetSetRemove();
 | 
					    Test_ObjectGetSetRemove();
 | 
				
			||||||
    Test_ArrayGetSetRemove();
 | 
					    Test_ArrayGetSetRemove();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -56,14 +56,15 @@ protected static function Test_ArrayGetSetRemove()
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
protected static function SubTest_Undefined()
 | 
					protected static function SubTest_Undefined()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    local JSONObject testJSON;
 | 
					    local JObject testJSON;
 | 
				
			||||||
    testJSON = new class'JSONObject';
 | 
					    testJSON = _().json.newObject();
 | 
				
			||||||
    Context("Testing how `JSONObject` handles undefined values");
 | 
					 | 
				
			||||||
    Issue("Undefined variable doesn't have proper type.");
 | 
					 | 
				
			||||||
    TEST_ExpectTrue(testJSON.GetType("some_var") == JSON_Undefined);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Issue("There is a variable in an empty object after `GetType` call.");
 | 
					    Context("Testing how `JObject` handles undefined values");
 | 
				
			||||||
    TEST_ExpectTrue(testJSON.GetType("some_var") == JSON_Undefined);
 | 
					    Issue("Undefined variable doesn't have proper type.");
 | 
				
			||||||
 | 
					    TEST_ExpectTrue(testJSON.GetTypeOf("some_var") == JSON_Undefined);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Issue("There is a variable in an empty object after `GetTypeOf` call.");
 | 
				
			||||||
 | 
					    TEST_ExpectTrue(testJSON.GetTypeOf("some_var") == JSON_Undefined);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Issue("Getters don't return default values for undefined variables.");
 | 
					    Issue("Getters don't return default values for undefined variables.");
 | 
				
			||||||
    TEST_ExpectTrue(testJSON.GetNumber("some_var", 0) == 0);
 | 
					    TEST_ExpectTrue(testJSON.GetNumber("some_var", 0) == 0);
 | 
				
			||||||
@ -75,14 +76,14 @@ protected static function SubTest_Undefined()
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
protected static function SubTest_BooleanGetSetRemove()
 | 
					protected static function SubTest_BooleanGetSetRemove()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    local JSONObject testJSON;
 | 
					    local JObject testJSON;
 | 
				
			||||||
    testJSON = new class'JSONObject';
 | 
					    testJSON = _().json.newObject();
 | 
				
			||||||
    testJSON.SetBoolean("some_boolean", true);
 | 
					    testJSON.SetBoolean("some_boolean", true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Context("Testing `JSONObject`'s get/set/remove functions for" @
 | 
					    Context("Testing `JObject`'s get/set/remove functions for" @
 | 
				
			||||||
            "boolean variables");
 | 
					            "boolean variables");
 | 
				
			||||||
    Issue("Boolean type isn't properly set by `SetBoolean`");
 | 
					    Issue("Boolean type isn't properly set by `SetBoolean`");
 | 
				
			||||||
    TEST_ExpectTrue(testJSON.GetType("some_boolean") == JSON_Boolean);
 | 
					    TEST_ExpectTrue(testJSON.GetTypeOf("some_boolean") == JSON_Boolean);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Issue("Variable value is incorrectly assigned by `SetBoolean`");
 | 
					    Issue("Variable value is incorrectly assigned by `SetBoolean`");
 | 
				
			||||||
    TEST_ExpectTrue(testJSON.GetBoolean("some_boolean") == true);
 | 
					    TEST_ExpectTrue(testJSON.GetBoolean("some_boolean") == true);
 | 
				
			||||||
@ -97,7 +98,7 @@ protected static function SubTest_BooleanGetSetRemove()
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    Issue("Boolean variable isn't being properly removed");
 | 
					    Issue("Boolean variable isn't being properly removed");
 | 
				
			||||||
    testJSON.RemoveValue("some_boolean");
 | 
					    testJSON.RemoveValue("some_boolean");
 | 
				
			||||||
    TEST_ExpectTrue(testJSON.GetType("some_boolean") == JSON_Undefined);
 | 
					    TEST_ExpectTrue(testJSON.GetTypeOf("some_boolean") == JSON_Undefined);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Issue(  "Getters don't return default value for missing key that" @
 | 
					    Issue(  "Getters don't return default value for missing key that" @
 | 
				
			||||||
            "previously stored boolean value, that got removed");
 | 
					            "previously stored boolean value, that got removed");
 | 
				
			||||||
@ -106,14 +107,14 @@ protected static function SubTest_BooleanGetSetRemove()
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
protected static function SubTest_StringGetSetRemove()
 | 
					protected static function SubTest_StringGetSetRemove()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    local JSONObject testJSON;
 | 
					    local JObject testJSON;
 | 
				
			||||||
    testJSON = new class'JSONObject';
 | 
					    testJSON = _().json.newObject();
 | 
				
			||||||
    testJSON.SetString("some_string", "first string");
 | 
					    testJSON.SetString("some_string", "first string");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Context("Testing `JSONObject`'s get/set/remove functions for" @
 | 
					    Context("Testing `JObject`'s get/set/remove functions for" @
 | 
				
			||||||
            "string variables");
 | 
					            "string variables");
 | 
				
			||||||
    Issue("String type isn't properly set by `SetString`");
 | 
					    Issue("String type isn't properly set by `SetString`");
 | 
				
			||||||
    TEST_ExpectTrue(testJSON.GetType("some_string") == JSON_String);
 | 
					    TEST_ExpectTrue(testJSON.GetTypeOf("some_string") == JSON_String);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Issue("Value is incorrectly assigned by `SetString`");
 | 
					    Issue("Value is incorrectly assigned by `SetString`");
 | 
				
			||||||
    TEST_ExpectTrue(testJSON.GetString("some_string") == "first string");
 | 
					    TEST_ExpectTrue(testJSON.GetString("some_string") == "first string");
 | 
				
			||||||
@ -133,7 +134,7 @@ protected static function SubTest_StringGetSetRemove()
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    Issue("String variable isn't being properly removed");
 | 
					    Issue("String variable isn't being properly removed");
 | 
				
			||||||
    testJSON.RemoveValue("some_string");
 | 
					    testJSON.RemoveValue("some_string");
 | 
				
			||||||
    TEST_ExpectTrue(testJSON.GetType("some_string") == JSON_Undefined);
 | 
					    TEST_ExpectTrue(testJSON.GetTypeOf("some_string") == JSON_Undefined);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Issue(  "Getters don't return default value for missing key that" @
 | 
					    Issue(  "Getters don't return default value for missing key that" @
 | 
				
			||||||
            "previously stored string value, but got removed");
 | 
					            "previously stored string value, but got removed");
 | 
				
			||||||
@ -142,14 +143,14 @@ protected static function SubTest_StringGetSetRemove()
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
protected static function SubTest_NumberGetSetRemove()
 | 
					protected static function SubTest_NumberGetSetRemove()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    local JSONObject testJSON;
 | 
					    local JObject testJSON;
 | 
				
			||||||
    testJSON = new class'JSONObject';
 | 
					    testJSON = _().json.newObject();
 | 
				
			||||||
    testJSON.SetNumber("some_number", 3.5);
 | 
					    testJSON.SetNumber("some_number", 3.5);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Context("Testing `JSONObject`'s get/set/remove functions for" @
 | 
					    Context("Testing `JObject`'s get/set/remove functions for" @
 | 
				
			||||||
            "number variables");
 | 
					            "number variables");
 | 
				
			||||||
    Issue("Number type isn't properly set by `SetNumber`");
 | 
					    Issue("Number type isn't properly set by `SetNumber`");
 | 
				
			||||||
    TEST_ExpectTrue(testJSON.GetType("some_number") == JSON_Number);
 | 
					    TEST_ExpectTrue(testJSON.GetTypeOf("some_number") == JSON_Number);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Issue("Value is incorrectly assigned by `SetNumber`");
 | 
					    Issue("Value is incorrectly assigned by `SetNumber`");
 | 
				
			||||||
    TEST_ExpectTrue(testJSON.GetNumber("some_number") == 3.5);
 | 
					    TEST_ExpectTrue(testJSON.GetNumber("some_number") == 3.5);
 | 
				
			||||||
@ -168,7 +169,7 @@ protected static function SubTest_NumberGetSetRemove()
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    Issue("Number type isn't being properly removed");
 | 
					    Issue("Number type isn't being properly removed");
 | 
				
			||||||
    testJSON.RemoveValue("some_number");
 | 
					    testJSON.RemoveValue("some_number");
 | 
				
			||||||
    TEST_ExpectTrue(testJSON.GetType("some_number") == JSON_Undefined);
 | 
					    TEST_ExpectTrue(testJSON.GetTypeOf("some_number") == JSON_Undefined);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Issue(  "Getters don't return default value for missing key that" @
 | 
					    Issue(  "Getters don't return default value for missing key that" @
 | 
				
			||||||
            "previously stored number value, that got removed");
 | 
					            "previously stored number value, that got removed");
 | 
				
			||||||
@ -177,10 +178,10 @@ protected static function SubTest_NumberGetSetRemove()
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
protected static function SubTest_NullGetSetRemove()
 | 
					protected static function SubTest_NullGetSetRemove()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    local JSONObject testJSON;
 | 
					    local JObject testJSON;
 | 
				
			||||||
    testJSON = new class'JSONObject';
 | 
					    testJSON = _().json.newObject();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Context("Testing `JSONObject`'s get/set/remove functions for" @
 | 
					    Context("Testing `JObject`'s get/set/remove functions for" @
 | 
				
			||||||
            "null values");
 | 
					            "null values");
 | 
				
			||||||
    Issue("Undefined variable is incorrectly considered `null`");
 | 
					    Issue("Undefined variable is incorrectly considered `null`");
 | 
				
			||||||
    TEST_ExpectFalse(testJSON.IsNull("some_var"));
 | 
					    TEST_ExpectFalse(testJSON.IsNull("some_var"));
 | 
				
			||||||
@ -202,35 +203,35 @@ protected static function SubTest_NullGetSetRemove()
 | 
				
			|||||||
    TEST_ExpectTrue(testJSON.IsNull("some_var"));
 | 
					    TEST_ExpectTrue(testJSON.IsNull("some_var"));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Issue("Null type isn't properly set by `SetNumber`");
 | 
					    Issue("Null type isn't properly set by `SetNumber`");
 | 
				
			||||||
    TEST_ExpectTrue(testJSON.GetType("some_var") == JSON_Null);
 | 
					    TEST_ExpectTrue(testJSON.GetTypeOf("some_var") == JSON_Null);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Issue("Null value isn't being properly removed.");
 | 
					    Issue("Null value isn't being properly removed.");
 | 
				
			||||||
    testJSON.RemoveValue("some_var");
 | 
					    testJSON.RemoveValue("some_var");
 | 
				
			||||||
    TEST_ExpectTrue(testJSON.GetType("some_var") == JSON_Undefined);
 | 
					    TEST_ExpectTrue(testJSON.GetTypeOf("some_var") == JSON_Undefined);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
protected static function SubTest_MultipleVariablesGetSet()
 | 
					protected static function SubTest_MultipleVariablesGetSet()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    local int           i;
 | 
					    local int           i;
 | 
				
			||||||
    local bool          correctValue, allValuesCorrect;
 | 
					    local bool          correctValue, allValuesCorrect;
 | 
				
			||||||
    local JSONObject    testJSON;
 | 
					    local JObject    testJSON;
 | 
				
			||||||
    testJSON = new class'JSONObject';
 | 
					    testJSON = _().json.newObject();
 | 
				
			||||||
    Context("Testing how `JSONObject` handles addition, change and removal" @
 | 
					    Context("Testing how `JObject` handles addition, change and removal" @
 | 
				
			||||||
            "of relatively large (hundreds) number of variables");
 | 
					            "of relatively large (hundreds) number of variables");
 | 
				
			||||||
    for (i = 0;i < 2000; i += 1)
 | 
					    for (i = 0; i < 2000; i += 1)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        testJSON.SetNumber("num" $ string(i), 4 * i*i - 2.6 * i + 0.75);
 | 
					        testJSON.SetNumber("num" $ string(i), 4 * i*i - 2.6 * i + 0.75);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    for (i = 0;i < 500; i += 1)
 | 
					    for (i = 0; i < 500; i += 1)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        testJSON.SetString("num" $ string(i), "str" $ string(Sin(i)));
 | 
					        testJSON.SetString("num" $ string(i), "str" $ string(Sin(i)));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    for (i = 1500;i < 2000; i += 1)
 | 
					    for (i = 1500; i < 2000; i += 1)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        testJSON.RemoveValue("num" $ string(i));
 | 
					        testJSON.RemoveValue("num" $ string(i));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    allValuesCorrect = true;
 | 
					    allValuesCorrect = true;
 | 
				
			||||||
    for (i = 0;i < 200; i += 1)
 | 
					    for (i = 0; i < 200; i += 1)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        if (i < 500)
 | 
					        if (i < 500)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
@ -246,7 +247,7 @@ protected static function SubTest_MultipleVariablesGetSet()
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
        else
 | 
					        else
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            correctValue = (    testJSON.GetType("num" $ string(i))
 | 
					            correctValue = (    testJSON.GetTypeOf("num" $ string(i))
 | 
				
			||||||
                            ==  JSON_Undefined);
 | 
					                            ==  JSON_Undefined);
 | 
				
			||||||
            Issue("Variables aren't removed");
 | 
					            Issue("Variables aren't removed");
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@ -261,9 +262,9 @@ protected static function SubTest_MultipleVariablesGetSet()
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
protected static function SubTest_Object()
 | 
					protected static function SubTest_Object()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    local JSONObject testObject;
 | 
					    local JObject testObject;
 | 
				
			||||||
    Context("Testing setters and getters for folded objects");
 | 
					    Context("Testing setters and getters for folded objects");
 | 
				
			||||||
    testObject = new class'JSONObject';
 | 
					    testObject = _().json.newObject();
 | 
				
			||||||
    testObject.CreateObject("folded");
 | 
					    testObject.CreateObject("folded");
 | 
				
			||||||
    testObject.GetObject("folded").CreateObject("folded");
 | 
					    testObject.GetObject("folded").CreateObject("folded");
 | 
				
			||||||
    testObject.SetString("out", "string outside");
 | 
					    testObject.SetString("out", "string outside");
 | 
				
			||||||
@ -285,17 +286,17 @@ protected static function SubTest_Object()
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
protected static function SubTest_ArrayUndefined()
 | 
					protected static function SubTest_ArrayUndefined()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    local JSONArray testJSON;
 | 
					    local JArray testJSON;
 | 
				
			||||||
    testJSON = new class'JSONArray';
 | 
					    testJSON = _().json.newArray();
 | 
				
			||||||
    Context("Testing how `JSONArray` handles undefined values");
 | 
					    Context("Testing how `JArray` handles undefined values");
 | 
				
			||||||
    Issue("Undefined variable doesn't have `JSON_Undefined` type");
 | 
					    Issue("Undefined variable doesn't have `JSON_Undefined` type");
 | 
				
			||||||
    TEST_ExpectTrue(testJSON.GetType(0) == JSON_Undefined);
 | 
					    TEST_ExpectTrue(testJSON.GetTypeOf(0) == JSON_Undefined);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Issue("There is a variable in an empty object after `GetType` call");
 | 
					    Issue("There is a variable in an empty object after `GetTypeOf` call");
 | 
				
			||||||
    TEST_ExpectTrue(testJSON.GetType(0) == JSON_Undefined);
 | 
					    TEST_ExpectTrue(testJSON.GetTypeOf(0) == JSON_Undefined);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Issue("Negative index refers to a defined value");
 | 
					    Issue("Negative index refers to a defined value");
 | 
				
			||||||
    TEST_ExpectTrue(testJSON.GetType(-1) == JSON_Undefined);
 | 
					    TEST_ExpectTrue(testJSON.GetTypeOf(-1) == JSON_Undefined);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Issue("Getters don't return default values for undefined variables");
 | 
					    Issue("Getters don't return default values for undefined variables");
 | 
				
			||||||
    TEST_ExpectTrue(testJSON.GetNumber(0, 0) == 0);
 | 
					    TEST_ExpectTrue(testJSON.GetNumber(0, 0) == 0);
 | 
				
			||||||
@ -313,14 +314,14 @@ protected static function SubTest_ArrayUndefined()
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
protected static function SubTest_ArrayBooleanGetSetRemove()
 | 
					protected static function SubTest_ArrayBooleanGetSetRemove()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    local JSONArray testJSON;
 | 
					    local JArray testJSON;
 | 
				
			||||||
    testJSON = new class'JSONArray';
 | 
					    testJSON = _().json.newArray();
 | 
				
			||||||
    testJSON.SetBoolean(0, true);
 | 
					    testJSON.SetBoolean(0, true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Context("Testing `JSONArray`'s get/set/remove functions for" @
 | 
					    Context("Testing `JArray`'s get/set/remove functions for" @
 | 
				
			||||||
            "boolean variables");
 | 
					            "boolean variables");
 | 
				
			||||||
    Issue("Boolean type isn't properly set by `SetBoolean`");
 | 
					    Issue("Boolean type isn't properly set by `SetBoolean`");
 | 
				
			||||||
    TEST_ExpectTrue(testJSON.GetType(0) == JSON_Boolean);
 | 
					    TEST_ExpectTrue(testJSON.GetTypeOf(0) == JSON_Boolean);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Issue("Value is incorrectly assigned by `SetBoolean`");
 | 
					    Issue("Value is incorrectly assigned by `SetBoolean`");
 | 
				
			||||||
    TEST_ExpectTrue(testJSON.GetBoolean(0) == true);
 | 
					    TEST_ExpectTrue(testJSON.GetBoolean(0) == true);
 | 
				
			||||||
@ -335,7 +336,7 @@ protected static function SubTest_ArrayBooleanGetSetRemove()
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    Issue("Boolean variable isn't being properly removed");
 | 
					    Issue("Boolean variable isn't being properly removed");
 | 
				
			||||||
    testJSON.RemoveValue(0);
 | 
					    testJSON.RemoveValue(0);
 | 
				
			||||||
    TEST_ExpectTrue( testJSON.GetType(0) == JSON_Undefined);
 | 
					    TEST_ExpectTrue( testJSON.GetTypeOf(0) == JSON_Undefined);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Issue(  "Getters don't return default value for missing key that" @
 | 
					    Issue(  "Getters don't return default value for missing key that" @
 | 
				
			||||||
            "previously stored boolean value, but got removed");
 | 
					            "previously stored boolean value, but got removed");
 | 
				
			||||||
@ -344,14 +345,14 @@ protected static function SubTest_ArrayBooleanGetSetRemove()
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
protected static function SubTest_ArrayStringGetSetRemove()
 | 
					protected static function SubTest_ArrayStringGetSetRemove()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    local JSONArray testJSON;
 | 
					    local JArray testJSON;
 | 
				
			||||||
    testJSON = new class'JSONArray';
 | 
					    testJSON = _().json.newArray();
 | 
				
			||||||
    testJSON.SetString(0, "first string");
 | 
					    testJSON.SetString(0, "first string");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Context("Testing `JSONArray`'s get/set/remove functions for" @
 | 
					    Context("Testing `JArray`'s get/set/remove functions for" @
 | 
				
			||||||
            "string variables");
 | 
					            "string variables");
 | 
				
			||||||
    Issue("String type isn't properly set by `SetString`");
 | 
					    Issue("String type isn't properly set by `SetString`");
 | 
				
			||||||
    TEST_ExpectTrue(testJSON.GetType(0) == JSON_String);
 | 
					    TEST_ExpectTrue(testJSON.GetTypeOf(0) == JSON_String);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Issue("Value is incorrectly assigned by `SetString`");
 | 
					    Issue("Value is incorrectly assigned by `SetString`");
 | 
				
			||||||
    TEST_ExpectTrue(testJSON.GetString(0) == "first string");
 | 
					    TEST_ExpectTrue(testJSON.GetString(0) == "first string");
 | 
				
			||||||
@ -370,7 +371,7 @@ protected static function SubTest_ArrayStringGetSetRemove()
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    Issue("Boolean variable isn't being properly removed");
 | 
					    Issue("Boolean variable isn't being properly removed");
 | 
				
			||||||
    testJSON.RemoveValue(0);
 | 
					    testJSON.RemoveValue(0);
 | 
				
			||||||
    TEST_ExpectTrue(testJSON.GetType(0) == JSON_Undefined);
 | 
					    TEST_ExpectTrue(testJSON.GetTypeOf(0) == JSON_Undefined);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Issue(  "Getters don't return default value for missing key that" @
 | 
					    Issue(  "Getters don't return default value for missing key that" @
 | 
				
			||||||
            "previously stored string value, but got removed");
 | 
					            "previously stored string value, but got removed");
 | 
				
			||||||
@ -379,14 +380,14 @@ protected static function SubTest_ArrayStringGetSetRemove()
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
protected static function SubTest_ArrayNumberGetSetRemove()
 | 
					protected static function SubTest_ArrayNumberGetSetRemove()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    local JSONArray testJSON;
 | 
					    local JArray testJSON;
 | 
				
			||||||
    testJSON = new class'JSONArray';
 | 
					    testJSON = _().json.newArray();
 | 
				
			||||||
    testJSON.SetNumber(0, 3.5);
 | 
					    testJSON.SetNumber(0, 3.5);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Context("Testing `JSONArray`'s get/set/remove functions for" @
 | 
					    Context("Testing `JArray`'s get/set/remove functions for" @
 | 
				
			||||||
            "number variables");
 | 
					            "number variables");
 | 
				
			||||||
    Issue("Number type isn't properly set by `SetNumber`");
 | 
					    Issue("Number type isn't properly set by `SetNumber`");
 | 
				
			||||||
    TEST_ExpectTrue(testJSON.GetType(0) == JSON_Number);
 | 
					    TEST_ExpectTrue(testJSON.GetTypeOf(0) == JSON_Number);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Issue("Value is incorrectly assigned by `SetNumber`");
 | 
					    Issue("Value is incorrectly assigned by `SetNumber`");
 | 
				
			||||||
    TEST_ExpectTrue(testJSON.GetNumber(0) == 3.5);
 | 
					    TEST_ExpectTrue(testJSON.GetNumber(0) == 3.5);
 | 
				
			||||||
@ -405,7 +406,7 @@ protected static function SubTest_ArrayNumberGetSetRemove()
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    Issue("Number type isn't being properly removed");
 | 
					    Issue("Number type isn't being properly removed");
 | 
				
			||||||
    testJSON.RemoveValue(0);
 | 
					    testJSON.RemoveValue(0);
 | 
				
			||||||
    TEST_ExpectTrue(testJSON.GetType(0) == JSON_Undefined);
 | 
					    TEST_ExpectTrue(testJSON.GetTypeOf(0) == JSON_Undefined);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Issue(  "Getters don't return default value for missing key that" @
 | 
					    Issue(  "Getters don't return default value for missing key that" @
 | 
				
			||||||
            "previously stored number value, but got removed");
 | 
					            "previously stored number value, but got removed");
 | 
				
			||||||
@ -414,10 +415,10 @@ protected static function SubTest_ArrayNumberGetSetRemove()
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
protected static function SubTest_ArrayNullGetSetRemove()
 | 
					protected static function SubTest_ArrayNullGetSetRemove()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    local JSONArray testJSON;
 | 
					    local JArray testJSON;
 | 
				
			||||||
    testJSON = new class'JSONArray';
 | 
					    testJSON = _().json.newArray();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Context("Testing `JSONArray`'s get/set/remove functions for" @
 | 
					    Context("Testing `JArray`'s get/set/remove functions for" @
 | 
				
			||||||
            "null values");
 | 
					            "null values");
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    Issue("Undefined variable is incorrectly considered `null`");
 | 
					    Issue("Undefined variable is incorrectly considered `null`");
 | 
				
			||||||
@ -442,19 +443,19 @@ protected static function SubTest_ArrayNullGetSetRemove()
 | 
				
			|||||||
    TEST_ExpectTrue(testJSON.IsNull(0));
 | 
					    TEST_ExpectTrue(testJSON.IsNull(0));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Issue("Null type isn't properly set by `SetNumber`");
 | 
					    Issue("Null type isn't properly set by `SetNumber`");
 | 
				
			||||||
    TEST_ExpectTrue(testJSON.GetType(0) == JSON_Null);
 | 
					    TEST_ExpectTrue(testJSON.GetTypeOf(0) == JSON_Null);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Issue("Null value isn't being properly removed");
 | 
					    Issue("Null value isn't being properly removed");
 | 
				
			||||||
    testJSON.RemoveValue(0);
 | 
					    testJSON.RemoveValue(0);
 | 
				
			||||||
    TEST_ExpectTrue(testJSON.GetType(0) == JSON_Undefined);
 | 
					    TEST_ExpectTrue(testJSON.GetTypeOf(0) == JSON_Undefined);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//  Returns following array:
 | 
					//  Returns following array:
 | 
				
			||||||
//  [10.0, "test string", "another string", true, 0.0, {"var": 7.0}]
 | 
					//  [10.0, "test string", "another string", true, 0.0, {"var": 7.0}]
 | 
				
			||||||
protected static function JSONArray Prepare_Array()
 | 
					protected static function JArray Prepare_Array()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    local JSONArray testArray;
 | 
					    local JArray testArray;
 | 
				
			||||||
    testArray = new class'JSONArray';
 | 
					    testArray = _().json.newArray();
 | 
				
			||||||
    testArray.AddNumber(10.0f)
 | 
					    testArray.AddNumber(10.0f)
 | 
				
			||||||
        .AddString("test string")
 | 
					        .AddString("test string")
 | 
				
			||||||
        .AddString("another string")
 | 
					        .AddString("another string")
 | 
				
			||||||
@ -467,10 +468,10 @@ protected static function JSONArray Prepare_Array()
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
protected static function SubTest_ArrayMultipleVariablesStorage()
 | 
					protected static function SubTest_ArrayMultipleVariablesStorage()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    local JSONArray testArray;
 | 
					    local JArray testArray;
 | 
				
			||||||
    testArray = Prepare_Array();
 | 
					    testArray = Prepare_Array();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Context("Testing how `JSONArray` handles adding and" @
 | 
					    Context("Testing how `JArray` handles adding and" @
 | 
				
			||||||
            "changing several variables");
 | 
					            "changing several variables");
 | 
				
			||||||
    Issue("Stored values are compromised.");
 | 
					    Issue("Stored values are compromised.");
 | 
				
			||||||
    TEST_ExpectTrue(testArray.GetNumber(0) == 10.0f);
 | 
					    TEST_ExpectTrue(testArray.GetNumber(0) == 10.0f);
 | 
				
			||||||
@ -490,18 +491,18 @@ protected static function SubTest_ArrayMultipleVariablesStorage()
 | 
				
			|||||||
    TEST_ExpectTrue(testArray.GetBoolean(3, false) == false);
 | 
					    TEST_ExpectTrue(testArray.GetBoolean(3, false) == false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Issue("Type of the variable is incorrectly changed.");
 | 
					    Issue("Type of the variable is incorrectly changed.");
 | 
				
			||||||
    TEST_ExpectTrue(testArray.GetType(3) == JSON_String);
 | 
					    TEST_ExpectTrue(testArray.GetTypeOf(3) == JSON_String);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
protected static function SubTest_ArrayMultipleVariablesRemoval()
 | 
					protected static function SubTest_ArrayMultipleVariablesRemoval()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    local JSONArray testArray;
 | 
					    local JArray testArray;
 | 
				
			||||||
    testArray = Prepare_Array();
 | 
					    testArray = Prepare_Array();
 | 
				
			||||||
    //  Test removing variables
 | 
					    //  Test removing variables
 | 
				
			||||||
    //  After `Prepare_Array`, our array should be:
 | 
					    //  After `Prepare_Array`, our array should be:
 | 
				
			||||||
    //  [10.0, "test string", "another string", true, 0.0, {"var": 7.0}]
 | 
					    //  [10.0, "test string", "another string", true, 0.0, {"var": 7.0}]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Context("Testing how `JSONArray` handles adding and" @
 | 
					    Context("Testing how `JArray` handles adding and" @
 | 
				
			||||||
            "removing several variables");
 | 
					            "removing several variables");
 | 
				
			||||||
    Issue("Values are incorrectly removed");
 | 
					    Issue("Values are incorrectly removed");
 | 
				
			||||||
    testArray.RemoveValue(2);
 | 
					    testArray.RemoveValue(2);
 | 
				
			||||||
@ -511,7 +512,7 @@ protected static function SubTest_ArrayMultipleVariablesRemoval()
 | 
				
			|||||||
    TEST_ExpectTrue(testArray.GetString(1) == "test string");
 | 
					    TEST_ExpectTrue(testArray.GetString(1) == "test string");
 | 
				
			||||||
    TEST_ExpectTrue(testArray.GetBoolean(2) == true);
 | 
					    TEST_ExpectTrue(testArray.GetBoolean(2) == true);
 | 
				
			||||||
    TEST_ExpectTrue(testArray.GetNumber(3) == 0.0f);
 | 
					    TEST_ExpectTrue(testArray.GetNumber(3) == 0.0f);
 | 
				
			||||||
    TEST_ExpectTrue(testArray.GetType(4) == JSON_Object);
 | 
					    TEST_ExpectTrue(testArray.GetTypeOf(4) == JSON_Object);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Issue("First element incorrectly removed");
 | 
					    Issue("First element incorrectly removed");
 | 
				
			||||||
    testArray.RemoveValue(0);
 | 
					    testArray.RemoveValue(0);
 | 
				
			||||||
@ -519,7 +520,7 @@ protected static function SubTest_ArrayMultipleVariablesRemoval()
 | 
				
			|||||||
    TEST_ExpectTrue(testArray.GetString(0) == "test string");
 | 
					    TEST_ExpectTrue(testArray.GetString(0) == "test string");
 | 
				
			||||||
    TEST_ExpectTrue(testArray.GetBoolean(1) == true);
 | 
					    TEST_ExpectTrue(testArray.GetBoolean(1) == true);
 | 
				
			||||||
    TEST_ExpectTrue(testArray.GetNumber(2) == 0.0f);
 | 
					    TEST_ExpectTrue(testArray.GetNumber(2) == 0.0f);
 | 
				
			||||||
    TEST_ExpectTrue(testArray.GetType(3) == JSON_Object);
 | 
					    TEST_ExpectTrue(testArray.GetTypeOf(3) == JSON_Object);
 | 
				
			||||||
    TEST_ExpectTrue(testArray.GetObject(3).GetNumber("var") == 7.0);
 | 
					    TEST_ExpectTrue(testArray.GetObject(3).GetNumber("var") == 7.0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Issue("Last element incorrectly removed");
 | 
					    Issue("Last element incorrectly removed");
 | 
				
			||||||
@ -535,19 +536,19 @@ protected static function SubTest_ArrayMultipleVariablesRemoval()
 | 
				
			|||||||
    testArray.RemoveValue(0);
 | 
					    testArray.RemoveValue(0);
 | 
				
			||||||
    testArray.RemoveValue(0);
 | 
					    testArray.RemoveValue(0);
 | 
				
			||||||
    TEST_ExpectTrue(testArray.Getlength() == 0);
 | 
					    TEST_ExpectTrue(testArray.Getlength() == 0);
 | 
				
			||||||
    TEST_ExpectTrue(testArray.GetType(0) == JSON_Undefined);
 | 
					    TEST_ExpectTrue(testArray.GetTypeOf(0) == JSON_Undefined);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
protected static function SubTest_ArrayRemovingMultipleVariablesAtOnce()
 | 
					protected static function SubTest_ArrayRemovingMultipleVariablesAtOnce()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    local JSONArray testArray;
 | 
					    local JArray testArray;
 | 
				
			||||||
    testArray = new class'JSONArray';
 | 
					    testArray = _().json.newArray();
 | 
				
			||||||
    testArray.AddNumber(10.0f)
 | 
					    testArray.AddNumber(10.0f)
 | 
				
			||||||
        .AddString("test string")
 | 
					        .AddString("test string")
 | 
				
			||||||
        .AddString("another string")
 | 
					        .AddString("another string")
 | 
				
			||||||
        .AddNumber(7.0);
 | 
					        .AddNumber(7.0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Context("Testing how `JSONArray`' handles removing" @
 | 
					    Context("Testing how `JArray`' handles removing" @
 | 
				
			||||||
            "multiple elements at once");
 | 
					            "multiple elements at once");
 | 
				
			||||||
    Issue("Multiple values are incorrectly removed");
 | 
					    Issue("Multiple values are incorrectly removed");
 | 
				
			||||||
    testArray.RemoveValue(1, 2);
 | 
					    testArray.RemoveValue(1, 2);
 | 
				
			||||||
@ -577,31 +578,31 @@ protected static function SubTest_ArrayRemovingMultipleVariablesAtOnce()
 | 
				
			|||||||
    Issue("Array empties incorrectly");
 | 
					    Issue("Array empties incorrectly");
 | 
				
			||||||
    testArray.RemoveValue(0, testArray.GetLength());
 | 
					    testArray.RemoveValue(0, testArray.GetLength());
 | 
				
			||||||
    TEST_ExpectTrue(testArray.GetLength() == 0);
 | 
					    TEST_ExpectTrue(testArray.GetLength() == 0);
 | 
				
			||||||
    TEST_ExpectTrue(testArray.GetType(0) == JSON_Undefined);
 | 
					    TEST_ExpectTrue(testArray.GetTypeOf(0) == JSON_Undefined);
 | 
				
			||||||
    TEST_ExpectTrue(testArray.GetType(1) == JSON_Undefined);
 | 
					    TEST_ExpectTrue(testArray.GetTypeOf(1) == JSON_Undefined);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
protected static function SubTest_ArrayExpansions()
 | 
					protected static function SubTest_ArrayExpansions()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    local JSONArray testArray;
 | 
					    local JArray testArray;
 | 
				
			||||||
    testArray = new class'JSONArray';
 | 
					    testArray = _().json.newArray();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Context("Testing how `JSONArray`' handles expansions/shrinking " @
 | 
					    Context("Testing how `JArray`' handles expansions/shrinking " @
 | 
				
			||||||
            "via `SetLength()`");
 | 
					            "via `SetLength()`");
 | 
				
			||||||
    Issue("`SetLength()` doesn't properly expand empty array");
 | 
					    Issue("`SetLength()` doesn't properly expand empty array");
 | 
				
			||||||
    testArray.SetLength(2);
 | 
					    testArray.SetLength(2);
 | 
				
			||||||
    TEST_ExpectTrue(testArray.GetLength() == 2);
 | 
					    TEST_ExpectTrue(testArray.GetLength() == 2);
 | 
				
			||||||
    TEST_ExpectTrue(testArray.GetType(0) == JSON_Null);
 | 
					    TEST_ExpectTrue(testArray.GetTypeOf(0) == JSON_Null);
 | 
				
			||||||
    TEST_ExpectTrue(testArray.GetType(1) == JSON_Null);
 | 
					    TEST_ExpectTrue(testArray.GetTypeOf(1) == JSON_Null);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Issue("`SetLength()` doesn't properly expand non-empty array");
 | 
					    Issue("`SetLength()` doesn't properly expand non-empty array");
 | 
				
			||||||
    testArray.AddNumber(1);
 | 
					    testArray.AddNumber(1);
 | 
				
			||||||
    testArray.SetLength(4);
 | 
					    testArray.SetLength(4);
 | 
				
			||||||
    TEST_ExpectTrue(testArray.GetLength() == 4);
 | 
					    TEST_ExpectTrue(testArray.GetLength() == 4);
 | 
				
			||||||
    TEST_ExpectTrue(testArray.GetType(0) == JSON_Null);
 | 
					    TEST_ExpectTrue(testArray.GetTypeOf(0) == JSON_Null);
 | 
				
			||||||
    TEST_ExpectTrue(testArray.GetType(1) == JSON_Null);
 | 
					    TEST_ExpectTrue(testArray.GetTypeOf(1) == JSON_Null);
 | 
				
			||||||
    TEST_ExpectTrue(testArray.GetType(2) == JSON_Number);
 | 
					    TEST_ExpectTrue(testArray.GetTypeOf(2) == JSON_Number);
 | 
				
			||||||
    TEST_ExpectTrue(testArray.GetType(3) == JSON_Null);
 | 
					    TEST_ExpectTrue(testArray.GetTypeOf(3) == JSON_Null);
 | 
				
			||||||
    TEST_ExpectTrue(testArray.GetNumber(2) == 1);
 | 
					    TEST_ExpectTrue(testArray.GetNumber(2) == 1);
 | 
				
			||||||
    SubSubTest_ArraySetNumberExpansions();
 | 
					    SubSubTest_ArraySetNumberExpansions();
 | 
				
			||||||
    SubSubTest_ArraySetStringExpansions();
 | 
					    SubSubTest_ArraySetStringExpansions();
 | 
				
			||||||
@ -610,10 +611,10 @@ protected static function SubTest_ArrayExpansions()
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
protected static function SubSubTest_ArraySetNumberExpansions()
 | 
					protected static function SubSubTest_ArraySetNumberExpansions()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    local JSONArray testArray;
 | 
					    local JArray testArray;
 | 
				
			||||||
    testArray = new class'JSONArray';
 | 
					    testArray = _().json.newArray();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Context("Testing how `JSONArray`' handles expansions via" @
 | 
					    Context("Testing how `JArray`' handles expansions via" @
 | 
				
			||||||
            "`SetNumber()` function");
 | 
					            "`SetNumber()` function");
 | 
				
			||||||
    Issue("Setters don't create correct first element");
 | 
					    Issue("Setters don't create correct first element");
 | 
				
			||||||
    testArray.SetNumber(0, 1);
 | 
					    testArray.SetNumber(0, 1);
 | 
				
			||||||
@ -622,30 +623,30 @@ protected static function SubSubTest_ArraySetNumberExpansions()
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    Issue(  "`SetNumber()` doesn't properly define array when setting" @
 | 
					    Issue(  "`SetNumber()` doesn't properly define array when setting" @
 | 
				
			||||||
            "value out-of-bounds");
 | 
					            "value out-of-bounds");
 | 
				
			||||||
    testArray = new class'JSONArray';
 | 
					    testArray = _().json.newArray();
 | 
				
			||||||
    testArray.AddNumber(1);
 | 
					    testArray.AddNumber(1);
 | 
				
			||||||
    testArray.SetNumber(4, 2);
 | 
					    testArray.SetNumber(4, 2);
 | 
				
			||||||
    TEST_ExpectTrue(testArray.GetLength() == 5);
 | 
					    TEST_ExpectTrue(testArray.GetLength() == 5);
 | 
				
			||||||
    TEST_ExpectTrue(testArray.GetNumber(0) == 1);
 | 
					    TEST_ExpectTrue(testArray.GetNumber(0) == 1);
 | 
				
			||||||
    TEST_ExpectTrue(testArray.GetType(1) == JSON_Null);
 | 
					    TEST_ExpectTrue(testArray.GetTypeOf(1) == JSON_Null);
 | 
				
			||||||
    TEST_ExpectTrue(testArray.GetType(2) == JSON_Null);
 | 
					    TEST_ExpectTrue(testArray.GetTypeOf(2) == JSON_Null);
 | 
				
			||||||
    TEST_ExpectTrue(testArray.GetType(3) == JSON_Null);
 | 
					    TEST_ExpectTrue(testArray.GetTypeOf(3) == JSON_Null);
 | 
				
			||||||
    TEST_ExpectTrue(testArray.GetNumber(4) == 2);
 | 
					    TEST_ExpectTrue(testArray.GetNumber(4) == 2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Issue("`SetNumber()` expands array even when it told not to");
 | 
					    Issue("`SetNumber()` expands array even when it told not to");
 | 
				
			||||||
    testArray.SetNumber(6, 7, true);
 | 
					    testArray.SetNumber(6, 7, true);
 | 
				
			||||||
    TEST_ExpectTrue(testArray.GetLength() == 5);
 | 
					    TEST_ExpectTrue(testArray.GetLength() == 5);
 | 
				
			||||||
    TEST_ExpectTrue(testArray.GetNumber(6) == 0);
 | 
					    TEST_ExpectTrue(testArray.GetNumber(6) == 0);
 | 
				
			||||||
    TEST_ExpectTrue(testArray.GetType(5) == JSON_Undefined);
 | 
					    TEST_ExpectTrue(testArray.GetTypeOf(5) == JSON_Undefined);
 | 
				
			||||||
    TEST_ExpectTrue(testArray.GetType(6) == JSON_Undefined);
 | 
					    TEST_ExpectTrue(testArray.GetTypeOf(6) == JSON_Undefined);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
protected static function SubSubTest_ArraySetStringExpansions()
 | 
					protected static function SubSubTest_ArraySetStringExpansions()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    local JSONArray testArray;
 | 
					    local JArray testArray;
 | 
				
			||||||
    testArray = new class'JSONArray';
 | 
					    testArray = _().json.newArray();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Context("Testing how `JSONArray`' handles expansions via" @
 | 
					    Context("Testing how `JArray`' handles expansions via" @
 | 
				
			||||||
            "`SetString()` function");
 | 
					            "`SetString()` function");
 | 
				
			||||||
    Issue("Setters don't create correct first element");
 | 
					    Issue("Setters don't create correct first element");
 | 
				
			||||||
    testArray.SetString(0, "str");
 | 
					    testArray.SetString(0, "str");
 | 
				
			||||||
@ -654,30 +655,30 @@ protected static function SubSubTest_ArraySetStringExpansions()
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    Issue(  "`SetString()` doesn't properly define array when setting" @
 | 
					    Issue(  "`SetString()` doesn't properly define array when setting" @
 | 
				
			||||||
            "value out-of-bounds");
 | 
					            "value out-of-bounds");
 | 
				
			||||||
    testArray = new class'JSONArray';
 | 
					    testArray = _().json.newArray();
 | 
				
			||||||
    testArray.AddString("str");
 | 
					    testArray.AddString("str");
 | 
				
			||||||
    testArray.SetString(4, "str2");
 | 
					    testArray.SetString(4, "str2");
 | 
				
			||||||
    TEST_ExpectTrue(testArray.GetLength() == 5);
 | 
					    TEST_ExpectTrue(testArray.GetLength() == 5);
 | 
				
			||||||
    TEST_ExpectTrue(testArray.GetString(0) == "str");
 | 
					    TEST_ExpectTrue(testArray.GetString(0) == "str");
 | 
				
			||||||
    TEST_ExpectTrue(testArray.GetType(1) == JSON_Null);
 | 
					    TEST_ExpectTrue(testArray.GetTypeOf(1) == JSON_Null);
 | 
				
			||||||
    TEST_ExpectTrue(testArray.GetType(2) == JSON_Null);
 | 
					    TEST_ExpectTrue(testArray.GetTypeOf(2) == JSON_Null);
 | 
				
			||||||
    TEST_ExpectTrue(testArray.GetType(3) == JSON_Null);
 | 
					    TEST_ExpectTrue(testArray.GetTypeOf(3) == JSON_Null);
 | 
				
			||||||
    TEST_ExpectTrue(testArray.GetString(4) == "str2");
 | 
					    TEST_ExpectTrue(testArray.GetString(4) == "str2");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Issue("`SetString()` expands array even when it told not to");
 | 
					    Issue("`SetString()` expands array even when it told not to");
 | 
				
			||||||
    testArray.SetString(6, "new string", true);
 | 
					    testArray.SetString(6, "new string", true);
 | 
				
			||||||
    TEST_ExpectTrue(testArray.GetLength() == 5);
 | 
					    TEST_ExpectTrue(testArray.GetLength() == 5);
 | 
				
			||||||
    TEST_ExpectTrue(testArray.GetString(6) == "");
 | 
					    TEST_ExpectTrue(testArray.GetString(6) == "");
 | 
				
			||||||
    TEST_ExpectTrue(testArray.GetType(5) == JSON_Undefined);
 | 
					    TEST_ExpectTrue(testArray.GetTypeOf(5) == JSON_Undefined);
 | 
				
			||||||
    TEST_ExpectTrue(testArray.GetType(6) == JSON_Undefined);
 | 
					    TEST_ExpectTrue(testArray.GetTypeOf(6) == JSON_Undefined);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
protected static function SubSubTest_ArraySetBooleanExpansions()
 | 
					protected static function SubSubTest_ArraySetBooleanExpansions()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    local JSONArray testArray;
 | 
					    local JArray testArray;
 | 
				
			||||||
    testArray = new class'JSONArray';
 | 
					    testArray = _().json.newArray();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Context("Testing how `JSONArray`' handles expansions via" @
 | 
					    Context("Testing how `JArray`' handles expansions via" @
 | 
				
			||||||
            "`SetBoolean()` function");
 | 
					            "`SetBoolean()` function");
 | 
				
			||||||
    Issue("Setters don't create correct first element");
 | 
					    Issue("Setters don't create correct first element");
 | 
				
			||||||
    testArray.SetBoolean(0, false);
 | 
					    testArray.SetBoolean(0, false);
 | 
				
			||||||
@ -686,22 +687,22 @@ protected static function SubSubTest_ArraySetBooleanExpansions()
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    Issue(  "`SetBoolean()` doesn't properly define array when setting" @
 | 
					    Issue(  "`SetBoolean()` doesn't properly define array when setting" @
 | 
				
			||||||
            "value out-of-bounds");
 | 
					            "value out-of-bounds");
 | 
				
			||||||
    testArray = new class'JSONArray';
 | 
					    testArray = _().json.newArray();
 | 
				
			||||||
    testArray.AddBoolean(true);
 | 
					    testArray.AddBoolean(true);
 | 
				
			||||||
    testArray.SetBoolean(4, true);
 | 
					    testArray.SetBoolean(4, true);
 | 
				
			||||||
    TEST_ExpectTrue(testArray.GetLength() == 5);
 | 
					    TEST_ExpectTrue(testArray.GetLength() == 5);
 | 
				
			||||||
    TEST_ExpectTrue(testArray.GetBoolean(0) == true);
 | 
					    TEST_ExpectTrue(testArray.GetBoolean(0) == true);
 | 
				
			||||||
    TEST_ExpectTrue(testArray.GetType(1) == JSON_Null);
 | 
					    TEST_ExpectTrue(testArray.GetTypeOf(1) == JSON_Null);
 | 
				
			||||||
    TEST_ExpectTrue(testArray.GetType(2) == JSON_Null);
 | 
					    TEST_ExpectTrue(testArray.GetTypeOf(2) == JSON_Null);
 | 
				
			||||||
    TEST_ExpectTrue(testArray.GetType(3) == JSON_Null);
 | 
					    TEST_ExpectTrue(testArray.GetTypeOf(3) == JSON_Null);
 | 
				
			||||||
    TEST_ExpectTrue(testArray.GetBoolean(4) == true);
 | 
					    TEST_ExpectTrue(testArray.GetBoolean(4) == true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Issue("`SetBoolean()` expands array even when it told not to");
 | 
					    Issue("`SetBoolean()` expands array even when it told not to");
 | 
				
			||||||
    testArray.SetBoolean(6, true, true);
 | 
					    testArray.SetBoolean(6, true, true);
 | 
				
			||||||
    TEST_ExpectTrue(testArray.GetLength() == 5);
 | 
					    TEST_ExpectTrue(testArray.GetLength() == 5);
 | 
				
			||||||
    TEST_ExpectTrue(testArray.GetBoolean(6) == false);
 | 
					    TEST_ExpectTrue(testArray.GetBoolean(6) == false);
 | 
				
			||||||
    TEST_ExpectTrue(testArray.GetType(5) == JSON_Undefined);
 | 
					    TEST_ExpectTrue(testArray.GetTypeOf(5) == JSON_Undefined);
 | 
				
			||||||
    TEST_ExpectTrue(testArray.GetType(6) == JSON_Undefined);
 | 
					    TEST_ExpectTrue(testArray.GetTypeOf(6) == JSON_Undefined);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
defaultproperties
 | 
					defaultproperties
 | 
				
			||||||
 | 
				
			|||||||
@ -22,8 +22,11 @@
 | 
				
			|||||||
class Global extends Singleton;
 | 
					class Global extends Singleton;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var public Acedia   acedia;
 | 
					var public Acedia   acedia;
 | 
				
			||||||
 | 
					var public JSONAPI  json;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
protected function OnCreated()
 | 
					protected function OnCreated()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    acedia  = class'Acedia'.static.GetInstance();
 | 
					    acedia  = class'Acedia'.static.GetInstance();
 | 
				
			||||||
 | 
					    Spawn(class'JSONAPI');
 | 
				
			||||||
 | 
					    json    = JSONAPI(class'JSONAPI'.static.GetInstance());
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
		Reference in New Issue
	
	Block a user