1764 lines
49 KiB
SourcePawn
1764 lines
49 KiB
SourcePawn
#if defined _jansson_included_
|
|
#endinput
|
|
#endif
|
|
#define _jansson_included_
|
|
|
|
/**
|
|
* --- Type
|
|
*
|
|
* The JSON specification (RFC 4627) defines the following data types:
|
|
* object, array, string, number, boolean, and null.
|
|
* JSON types are used dynamically; arrays and objects can hold any
|
|
* other data type, including themselves. For this reason, Jansson's
|
|
* type system is also dynamic in nature. There's one Handle type to
|
|
* represent all JSON values, and the referenced structure knows the
|
|
* type of the JSON value it holds.
|
|
*
|
|
*/
|
|
enum JSONType {
|
|
JSONType_Object,
|
|
JSONType_Array,
|
|
JSONType_String,
|
|
JSONType_Integer,
|
|
JSONType_Float,
|
|
JSONType_True,
|
|
JSONType_False,
|
|
JSONType_Null
|
|
};
|
|
|
|
/**
|
|
* Return the type of the JSON value.
|
|
*
|
|
* @param hObj Handle to the JSON value
|
|
*
|
|
* @return JSONType of the value.
|
|
*/
|
|
native JSONType json_typeof(JSONValue hObj);
|
|
|
|
/**
|
|
* The type of a JSON value is queried and tested using these macros
|
|
*
|
|
* @param %1 Handle to the JSON value
|
|
*
|
|
* @return True if the value has the correct type.
|
|
*/
|
|
#define json_is_object(%1) ( json_typeof(%1) == JSONType_Object )
|
|
#define json_is_array(%1) ( json_typeof(%1) == JSONType_Array )
|
|
#define json_is_string(%1) ( json_typeof(%1) == JSONType_String )
|
|
#define json_is_integer(%1) ( json_typeof(%1) == JSONType_Integer )
|
|
#define json_is_real(%1) ( json_typeof(%1) == JSONType_Float )
|
|
#define json_is_true(%1) ( json_typeof(%1) == JSONType_True )
|
|
#define json_is_false(%1) ( json_typeof(%1) == JSONType_False )
|
|
#define json_is_null(%1) ( json_typeof(%1) == JSONType_Null )
|
|
#define json_is_number(%1) ( json_typeof(%1) == JSONType_Integer || json_typeof(%1) == JSONType_Float )
|
|
#define json_is_boolean(%1) ( json_typeof(%1) == JSONType_True || json_typeof(%1) == JSONType_False )
|
|
|
|
/**
|
|
* Saves json_type as a String in output
|
|
*
|
|
* @param input json_type value to convert to string
|
|
* @param output Buffer to store the json_type value
|
|
* @param maxlength Maximum length of string buffer.
|
|
*
|
|
* @return False if the type does not exist.
|
|
*/
|
|
stock bool Stringify_json_type(JSONType input, char[] output, int maxlength) {
|
|
switch(input) {
|
|
case JSONType_Object: strcopy(output, maxlength, "Object");
|
|
case JSONType_Array: strcopy(output, maxlength, "Array");
|
|
case JSONType_String: strcopy(output, maxlength, "String");
|
|
case JSONType_Integer: strcopy(output, maxlength, "Integer");
|
|
case JSONType_Float: strcopy(output, maxlength, "Float");
|
|
case JSONType_True: strcopy(output, maxlength, "True");
|
|
case JSONType_False: strcopy(output, maxlength, "False");
|
|
case JSONType_Null: strcopy(output, maxlength, "Null");
|
|
default: return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* --- Equality
|
|
*
|
|
* - Two integer or real values are equal if their contained numeric
|
|
* values are equal. An integer value is never equal to a real value,
|
|
* though.
|
|
* - Two strings are equal if their contained UTF-8 strings are equal,
|
|
* byte by byte. Unicode comparison algorithms are not implemented.
|
|
* - Two arrays are equal if they have the same number of elements and
|
|
* each element in the first array is equal to the corresponding
|
|
* element in the second array.
|
|
* - Two objects are equal if they have exactly the same keys and the
|
|
* value for each key in the first object is equal to the value of
|
|
* the corresponding key in the second object.
|
|
* - Two true, false or null values have no "contents", so they are
|
|
* equal if their types are equal.
|
|
*
|
|
*/
|
|
|
|
/**
|
|
* Test whether two JSON values are equal.
|
|
*
|
|
* @param hObj Handle to the first JSON node
|
|
* @param hOther Handle to the second JSON node
|
|
*
|
|
* @return Returns false if they are inequal or one
|
|
* or both of the pointers are NULL.
|
|
*/
|
|
native bool json_equal(JSONValue hObj, JSONValue hOther);
|
|
|
|
|
|
|
|
|
|
/**
|
|
* --- Copying
|
|
*
|
|
* Jansson supports two kinds of copying: shallow and deep. There is
|
|
* a difference between these methods only for arrays and objects.
|
|
*
|
|
* Shallow copying only copies the first level value (array or object)
|
|
* and uses the same child values in the copied value.
|
|
*
|
|
* Deep copying makes a fresh copy of the child values, too. Moreover,
|
|
* all the child values are deep copied in a recursive fashion.
|
|
*
|
|
*/
|
|
|
|
/**
|
|
* Get a shallow copy of the passed object
|
|
*
|
|
* @param hObj Handle to JSON object to be copied
|
|
*
|
|
* @return Returns a shallow copy of the object,
|
|
* or INVALID_HANDLE on error.
|
|
*/
|
|
native JSONValue json_copy(JSONValue hObj);
|
|
|
|
/**
|
|
* Get a deep copy of the passed object
|
|
*
|
|
* @param hObj Handle to JSON object to be copied
|
|
*
|
|
* @return Returns a deep copy of the object,
|
|
* or INVALID_HANDLE on error.
|
|
*/
|
|
native JSONValue json_deep_copy(JSONValue hObj);
|
|
|
|
|
|
|
|
|
|
/**
|
|
* --- Objects
|
|
*
|
|
* A JSON object is a dictionary of key-value pairs, where the
|
|
* key is a Unicode string and the value is any JSON value.
|
|
*
|
|
*/
|
|
|
|
/**
|
|
* Returns a handle to a new JSON object, or INVALID_HANDLE on error.
|
|
* Initially, the object is empty.
|
|
*
|
|
* @return Handle to a new JSON object.
|
|
*/
|
|
native JSONObject json_object();
|
|
|
|
/**
|
|
* Returns the number of elements in hObj
|
|
*
|
|
* @param hObj Handle to JSON object
|
|
*
|
|
* @return Number of elements in hObj,
|
|
* or 0 if hObj is not a JSON object.
|
|
*/
|
|
native int json_object_size(JSONObject hObj);
|
|
|
|
/**
|
|
* Get a value corresponding to sKey from hObj
|
|
*
|
|
* @param hObj Handle to JSON object to get a value from
|
|
* @param sKey Key to retrieve
|
|
*
|
|
* @return Handle to a the JSON object or
|
|
* INVALID_HANDLE on error.
|
|
*/
|
|
native JSONValue json_object_get(JSONObject hObj, const char[] sKey);
|
|
|
|
/**
|
|
* Set the value of sKey to hValue in hObj.
|
|
* If there already is a value for key, it is replaced by the new value.
|
|
*
|
|
* @param hObj Handle to JSON object to set a value on
|
|
* @param sKey Key to store in the object
|
|
* Must be a valid null terminated UTF-8 encoded
|
|
* Unicode string.
|
|
* @param hValue Value to store in the object
|
|
*
|
|
* @return True on success.
|
|
*/
|
|
native bool json_object_set(JSONObject hObj, const char[] sKey, JSONValue hValue);
|
|
|
|
/**
|
|
* Set the value of sKey to hValue in hObj.
|
|
* If there already is a value for key, it is replaced by the new value.
|
|
* This function automatically closes the Handle to the value object.
|
|
*
|
|
* @param hObj Handle to JSON object to set a value on
|
|
* @param sKey Key to store in the object
|
|
* Must be a valid null terminated UTF-8 encoded
|
|
* Unicode string.
|
|
* @param hValue Value to store in the object
|
|
*
|
|
* @return True on success.
|
|
*/
|
|
native bool json_object_set_new(JSONObject hObj, const char[] sKey, JSONValue hValue);
|
|
|
|
/**
|
|
* Delete sKey from hObj if it exists.
|
|
*
|
|
* @param hObj Handle to JSON object to delete a key from
|
|
* @param sKey Key to delete
|
|
*
|
|
* @return True on success.
|
|
*/
|
|
native bool json_object_del(JSONObject hObj, const char[] sKey);
|
|
|
|
/**
|
|
* Remove all elements from hObj.
|
|
*
|
|
* @param hObj Handle to JSON object to remove all
|
|
* elements from.
|
|
*
|
|
* @return True on success.
|
|
*/
|
|
native bool json_object_clear(JSONObject hObj);
|
|
|
|
/**
|
|
* Update hObj with the key-value pairs from hOther, overwriting
|
|
* existing keys.
|
|
*
|
|
* @param hObj Handle to JSON object to update
|
|
* @param hOther Handle to JSON object to get update
|
|
* keys/values from.
|
|
*
|
|
* @return True on success.
|
|
*/
|
|
native bool json_object_update(JSONObject hObj, JSONObject hOther);
|
|
|
|
/**
|
|
* Like json_object_update(), but only the values of existing keys
|
|
* are updated. No new keys are created.
|
|
*
|
|
* @param hObj Handle to JSON object to update
|
|
* @param hOther Handle to JSON object to get update
|
|
* keys/values from.
|
|
*
|
|
* @return True on success.
|
|
*/
|
|
native bool json_object_update_existing(JSONObject hObj, JSONObject hOther);
|
|
|
|
/**
|
|
* Like json_object_update(), but only new keys are created.
|
|
* The value of any existing key is not changed.
|
|
*
|
|
* @param hObj Handle to JSON object to update
|
|
* @param hOther Handle to JSON object to get update
|
|
* keys/values from.
|
|
*
|
|
* @return True on success.
|
|
*/
|
|
native bool json_object_update_missing(JSONObject hObj, JSONObject hOther);
|
|
|
|
|
|
|
|
|
|
/**
|
|
* Object iteration
|
|
*
|
|
* Example code:
|
|
* - We assume hObj is a Handle to a valid JSON object.
|
|
*
|
|
*
|
|
* new Handle:hIterator = json_object_iter(hObj);
|
|
* while(hIterator != INVALID_HANDLE)
|
|
* {
|
|
* new String:sKey[128];
|
|
* json_object_iter_key(hIterator, sKey, sizeof(sKey));
|
|
*
|
|
* new Handle:hValue = json_object_iter_value(hIterator);
|
|
*
|
|
* // Do something with sKey and hValue
|
|
*
|
|
* delete hValue;
|
|
*
|
|
* hIterator = json_object_iter_next(hObj, hIterator);
|
|
* }
|
|
*
|
|
*/
|
|
|
|
/**
|
|
* Returns a handle to an iterator which can be used to iterate over
|
|
* all key-value pairs in hObj.
|
|
* If you are not iterating to the end of hObj make sure to close the
|
|
* handle to the iterator manually.
|
|
*
|
|
* @param hObj Handle to JSON object to get an iterator
|
|
* for.
|
|
*
|
|
* @return Handle to JSON object iterator,
|
|
* or INVALID_HANDLE on error.
|
|
*/
|
|
native JSONObjectIterator json_object_iter(JSONObject hObj);
|
|
|
|
/**
|
|
* Like json_object_iter(), but returns an iterator to the key-value
|
|
* pair in object whose key is equal to key.
|
|
* Iterating forward to the end of object only yields all key-value
|
|
* pairs of the object if key happens to be the first key in the
|
|
* underlying hash table.
|
|
*
|
|
* @param hObj Handle to JSON object to get an iterator
|
|
* for.
|
|
* @param sKey Start key for the iterator
|
|
*
|
|
* @return Handle to JSON object iterator,
|
|
* or INVALID_HANDLE on error.
|
|
*/
|
|
native JSONObjectIterator json_object_iter_at(JSONObject hObj, const char[] sKey);
|
|
|
|
/**
|
|
* Returns an iterator pointing to the next key-value pair in object.
|
|
* This automatically closes the Handle to the iterator hIter.
|
|
*
|
|
* @param hObj Handle to JSON object.
|
|
* @param hIter Handle to JSON object iterator.
|
|
*
|
|
* @return Handle to JSON object iterator,
|
|
* or INVALID_HANDLE on error, or if the
|
|
* whole object has been iterated through.
|
|
*/
|
|
native JSONObjectIterator json_object_iter_next(JSONObject hObj, JSONObjectIterator hIter);
|
|
|
|
/**
|
|
* Extracts the associated key of hIter as a null terminated UTF-8
|
|
* encoded string in the passed buffer.
|
|
*
|
|
* @param hIter Handle to the JSON String object
|
|
* @param sKeyBuffer Buffer to store the value of the String.
|
|
* @param maxlength Maximum length of string buffer.
|
|
* @error Invalid JSON Object Iterator.
|
|
* @return Length of the returned string or -1 on error.
|
|
*/
|
|
native int json_object_iter_key(JSONObjectIterator hIter, char[] sKeyBuffer, int maxlength);
|
|
|
|
/**
|
|
* Returns a handle to the value hIter is pointing at.
|
|
*
|
|
* @param hIter Handle to JSON object iterator.
|
|
*
|
|
* @return Handle to value or INVALID_HANDLE on error.
|
|
*/
|
|
native JSONValue json_object_iter_value(JSONObjectIterator hIter);
|
|
|
|
/**
|
|
* Set the value of the key-value pair in hObj, that is pointed to
|
|
* by hIter, to hValue.
|
|
*
|
|
* @param hObj Handle to JSON object.
|
|
* @param hIter Handle to JSON object iterator.
|
|
* @param hValue Handle to JSON value.
|
|
*
|
|
* @return True on success.
|
|
*/
|
|
native bool json_object_iter_set(JSONObject hObj, JSONObjectIterator hIter, JSONValue hValue);
|
|
|
|
/**
|
|
* Set the value of the key-value pair in hObj, that is pointed to
|
|
* by hIter, to hValue.
|
|
* This function automatically closes the Handle to the value object.
|
|
*
|
|
* @param hObj Handle to JSON object.
|
|
* @param hIter Handle to JSON object iterator.
|
|
* @param hValue Handle to JSON value.
|
|
*
|
|
* @return True on success.
|
|
*/
|
|
native bool json_object_iter_set_new(JSONObject hObj, JSONObjectIterator hIter, JSONValue hValue);
|
|
|
|
|
|
|
|
|
|
/**
|
|
* Arrays
|
|
*
|
|
* A JSON array is an ordered collection of other JSON values.
|
|
*
|
|
*/
|
|
|
|
/**
|
|
* Returns a handle to a new JSON array, or INVALID_HANDLE on error.
|
|
*
|
|
* @return Handle to the new JSON array
|
|
*/
|
|
native JSONArray json_array();
|
|
|
|
/**
|
|
* Returns the number of elements in hArray
|
|
*
|
|
* @param hObj Handle to JSON array
|
|
*
|
|
* @return Number of elements in hArray,
|
|
* or 0 if hObj is not a JSON array.
|
|
*/
|
|
native int json_array_size(JSONArray hArray);
|
|
|
|
/**
|
|
* Returns the element in hArray at position iIndex.
|
|
*
|
|
* @param hArray Handle to JSON array to get a value from
|
|
* @param iIndex Position to retrieve
|
|
*
|
|
* @return Handle to a the JSON object or
|
|
* INVALID_HANDLE on error.
|
|
*/
|
|
native JSONValue json_array_get(JSONArray hArray, int iIndex);
|
|
|
|
/**
|
|
* Replaces the element in array at position iIndex with hValue.
|
|
* The valid range for iIndex is from 0 to the return value of
|
|
* json_array_size() minus 1.
|
|
*
|
|
* @param hArray Handle to JSON array
|
|
* @param iIndex Position to replace
|
|
* @param hValue Value to store in the array
|
|
*
|
|
* @return True on success.
|
|
*/
|
|
native bool json_array_set(JSONArray hArray, int iIndex, JSONValue hValue);
|
|
|
|
/**
|
|
* Replaces the element in array at position iIndex with hValue.
|
|
* The valid range for iIndex is from 0 to the return value of
|
|
* json_array_size() minus 1.
|
|
* This function automatically closes the Handle to the value object.
|
|
*
|
|
* @param hArray Handle to JSON array
|
|
* @param iIndex Position to replace
|
|
* @param hValue Value to store in the array
|
|
*
|
|
* @return True on success.
|
|
*/
|
|
native bool json_array_set_new(JSONArray hArray, int iIndex, JSONValue hValue);
|
|
|
|
/**
|
|
* Appends value to the end of array, growing the size of array by 1.
|
|
*
|
|
* @param hArray Handle to JSON array
|
|
* @param hValue Value to append to the array
|
|
*
|
|
* @return True on success.
|
|
*/
|
|
native bool json_array_append(JSONArray hArray, JSONValue hValue);
|
|
|
|
/**
|
|
* Appends value to the end of array, growing the size of array by 1.
|
|
* This function automatically closes the Handle to the value object.
|
|
*
|
|
* @param hArray Handle to JSON array
|
|
* @param hValue Value to append to the array
|
|
*
|
|
* @return True on success.
|
|
*/
|
|
native bool json_array_append_new(JSONArray hArray, JSONValue hValue);
|
|
|
|
/**
|
|
* Inserts value to hArray at position iIndex, shifting the elements at
|
|
* iIndex and after it one position towards the end of the array.
|
|
*
|
|
* @param hArray Handle to JSON array
|
|
* @param iIndex Position to insert at
|
|
* @param hValue Value to store in the array
|
|
*
|
|
* @return True on success.
|
|
*/
|
|
native bool json_array_insert(JSONArray hArray, int iIndex, JSONValue hValue);
|
|
|
|
/**
|
|
* Inserts value to hArray at position iIndex, shifting the elements at
|
|
* iIndex and after it one position towards the end of the array.
|
|
* This function automatically closes the Handle to the value object.
|
|
*
|
|
* @param hArray Handle to JSON array
|
|
* @param iIndex Position to insert at
|
|
* @param hValue Value to store in the array
|
|
*
|
|
* @return True on success.
|
|
*/
|
|
native bool json_array_insert_new(JSONArray hArray, int iIndex, JSONValue hValue);
|
|
|
|
/**
|
|
* Removes the element in hArray at position iIndex, shifting the
|
|
* elements after iIndex one position towards the start of the array.
|
|
*
|
|
* @param hArray Handle to JSON array
|
|
* @param iIndex Position to insert at
|
|
*
|
|
* @return True on success.
|
|
*/
|
|
native bool json_array_remove(JSONArray hArray, int iIndex);
|
|
|
|
/**
|
|
* Removes all elements from hArray.
|
|
*
|
|
* @param hArray Handle to JSON array
|
|
*
|
|
* @return True on success.
|
|
*/
|
|
native bool json_array_clear(JSONArray hArray);
|
|
|
|
/**
|
|
* Appends all elements in hOther to the end of hArray.
|
|
*
|
|
* @param hArray Handle to JSON array to be extended
|
|
* @param hOther Handle to JSON array, source to copy from
|
|
*
|
|
* @return True on success.
|
|
*/
|
|
native bool json_array_extend(JSONArray hArray, JSONArray hOther);
|
|
|
|
|
|
|
|
|
|
/**
|
|
* Booleans & NULL
|
|
*
|
|
*/
|
|
|
|
/**
|
|
* Returns a handle to a new JSON Boolean with value true,
|
|
* or INVALID_HANDLE on error.
|
|
*
|
|
* @return Handle to the new Boolean object
|
|
*/
|
|
native JSONValue json_true();
|
|
|
|
/**
|
|
* Returns a handle to a new JSON Boolean with value false,
|
|
* or INVALID_HANDLE on error.
|
|
*
|
|
* @return Handle to the new Boolean object
|
|
*/
|
|
native JSONValue json_false();
|
|
|
|
/**
|
|
* Returns a handle to a new JSON Boolean with the value passed
|
|
* in bState or INVALID_HANDLE on error.
|
|
*
|
|
* @param bState Value for the new Boolean object
|
|
* @return Handle to the new Boolean object
|
|
*/
|
|
native JSONValue json_boolean(bool bState);
|
|
|
|
/**
|
|
* Returns a handle to a new JSON NULL or INVALID_HANDLE on error.
|
|
*
|
|
* @return Handle to the new NULL object
|
|
*/
|
|
native JSONValue json_null();
|
|
|
|
|
|
|
|
|
|
/**
|
|
* Strings
|
|
*
|
|
* Jansson uses UTF-8 as the character encoding. All JSON strings must
|
|
* be valid UTF-8 (or ASCII, as it's a subset of UTF-8). Normal null
|
|
* terminated C strings are used, so JSON strings may not contain
|
|
* embedded null characters.
|
|
*
|
|
*/
|
|
|
|
/**
|
|
* Returns a handle to a new JSON string, or INVALID_HANDLE on error.
|
|
*
|
|
* @param sValue Value for the new String object
|
|
* Must be a valid UTF-8 encoded Unicode string.
|
|
* @return Handle to the new String object
|
|
*/
|
|
native JSONString json_string(const char[] sValue);
|
|
|
|
/**
|
|
* Saves the associated value of hString as a null terminated UTF-8
|
|
* encoded string in the passed buffer.
|
|
*
|
|
* @param hString Handle to the JSON String object
|
|
* @param sValueBuffer Buffer to store the value of the String.
|
|
* @param maxlength Maximum length of string buffer.
|
|
* @error Invalid JSON String Object.
|
|
* @return Length of the returned string or -1 on error.
|
|
*/
|
|
native int json_string_value(JSONString hString, char[] sValueBuffer, int maxlength);
|
|
|
|
/**
|
|
* Sets the associated value of JSON String object to value.
|
|
*
|
|
* @param hString Handle to the JSON String object
|
|
* @param sValue Value to set the object to.
|
|
* Must be a valid UTF-8 encoded Unicode string.
|
|
* @error Invalid JSON String Object.
|
|
* @return True on success.
|
|
*/
|
|
native bool json_string_set(JSONString hString, const char[] sValue);
|
|
|
|
|
|
|
|
|
|
/**
|
|
* Numbers
|
|
*
|
|
* The JSON specification only contains one numeric type, 'number'.
|
|
* The C (and Pawn) programming language has distinct types for integer
|
|
* and floating-point numbers, so for practical reasons Jansson also has
|
|
* distinct types for the two. They are called 'integer' and 'real',
|
|
* respectively. (Whereas 'real' is a 'Float' for Pawn).
|
|
* Therefore a number is represented by either a value of the type
|
|
* JSONType_Integer or of the type JSONType_Float.
|
|
*
|
|
*/
|
|
|
|
/**
|
|
* Returns a handle to a new JSON integer, or INVALID_HANDLE on error.
|
|
*
|
|
* @param iValue Value for the new Integer object
|
|
* @return Handle to the new Integer object
|
|
*/
|
|
native JSONInteger json_integer(int iValue);
|
|
|
|
/**
|
|
* Returns the associated value of a JSON Integer Object.
|
|
*
|
|
* @param hInteger Handle to the JSON Integer object
|
|
* @error Invalid JSON Integer Object.
|
|
* @return Value of the hInteger,
|
|
* or 0 if hInteger is not a JSON integer.
|
|
*/
|
|
native int json_integer_value(JSONInteger hInteger);
|
|
|
|
/**
|
|
* Sets the associated value of JSON Integer to value.
|
|
*
|
|
* @param hInteger Handle to the JSON Integer object
|
|
* @param iValue Value to set the object to.
|
|
* @error Invalid JSON Integer Object.
|
|
* @return True on success.
|
|
*/
|
|
native bool json_integer_set(JSONInteger hInteger, int iValue);
|
|
|
|
|
|
|
|
|
|
/**
|
|
* Returns a handle to a new JSON real, or INVALID_HANDLE on error.
|
|
*
|
|
* @param fValue Value for the new Real object
|
|
* @return Handle to the new String object
|
|
*/
|
|
native JSONFloat json_real(float fValue);
|
|
|
|
/**
|
|
* Returns the associated value of a JSON Real.
|
|
*
|
|
* @param hReal Handle to the JSON Real object
|
|
* @error Invalid JSON Real Object.
|
|
* @return Float value of hReal,
|
|
* or 0.0 if hReal is not a JSON Real.
|
|
*/
|
|
native float json_real_value(JSONFloat hReal);
|
|
|
|
/**
|
|
* Sets the associated value of JSON Real to fValue.
|
|
*
|
|
* @param hReal Handle to the JSON Integer object
|
|
* @param fValue Value to set the object to.
|
|
* @error Invalid JSON Real handle.
|
|
* @return True on success.
|
|
*/
|
|
native bool json_real_set(JSONFloat hReal, float value);
|
|
|
|
/**
|
|
* Returns the associated value of a JSON integer or a
|
|
* JSON Real, cast to Float regardless of the actual type.
|
|
*
|
|
* @param hNumber Handle to the JSON Number
|
|
* @error Not a JSON Real or JSON Integer
|
|
* @return Float value of hNumber,
|
|
* or 0.0 on error.
|
|
*/
|
|
native float json_number_value(JSONNumber hNumber);
|
|
|
|
|
|
|
|
|
|
/**
|
|
* Decoding
|
|
*
|
|
* This sections describes the functions that can be used to decode JSON text
|
|
* to the Jansson representation of JSON data. The JSON specification requires
|
|
* that a JSON text is either a serialized array or object, and this
|
|
* requirement is also enforced with the following functions. In other words,
|
|
* the top level value in the JSON text being decoded must be either array or
|
|
* object.
|
|
*
|
|
*/
|
|
|
|
/**
|
|
* Decodes the JSON string sJSON and returns the array or object it contains.
|
|
* Errors while decoding can be found in the sourcemod error log.
|
|
*
|
|
* @param sJSON String containing valid JSON
|
|
|
|
* @return Handle to JSON object or array.
|
|
* or INVALID_HANDLE on error.
|
|
*/
|
|
native JSONValue json_load(const char[] sJSON);
|
|
|
|
/**
|
|
* Decodes the JSON string sJSON and returns the array or object it contains.
|
|
* This function provides additional error feedback and does not log errors
|
|
* to the sourcemod error log.
|
|
*
|
|
* @param sJSON String containing valid JSON
|
|
* @param sErrorText This buffer will be filled with the error
|
|
* message.
|
|
* @param maxlen Size of the buffer
|
|
* @param iLine This int will contain the line of the error
|
|
* @param iColumn This int will contain the column of the error
|
|
*
|
|
* @return Handle to JSON object or array.
|
|
* or INVALID_HANDLE on error.
|
|
*/
|
|
native JSONValue json_load_ex(const char[] sJSON, char[] sErrorText, int maxlen, int &iLine, int &iColumn);
|
|
|
|
/**
|
|
* Decodes the JSON text in file sFilePath and returns the array or object
|
|
* it contains.
|
|
* Errors while decoding can be found in the sourcemod error log.
|
|
*
|
|
* @param sFilePath Path to a file containing pure JSON
|
|
*
|
|
* @return Handle to JSON object or array.
|
|
* or INVALID_HANDLE on error.
|
|
*/
|
|
native JSONValue json_load_file(const char sFilePath[PLATFORM_MAX_PATH]);
|
|
|
|
/**
|
|
* Decodes the JSON text in file sFilePath and returns the array or object
|
|
* it contains.
|
|
* This function provides additional error feedback and does not log errors
|
|
* to the sourcemod error log.
|
|
*
|
|
* @param sFilePath Path to a file containing pure JSON
|
|
* @param sErrorText This buffer will be filled with the error
|
|
* message.
|
|
* @param maxlen Size of the buffer
|
|
* @param iLine This int will contain the line of the error
|
|
* @param iColumn This int will contain the column of the error
|
|
*
|
|
* @return Handle to JSON object or array.
|
|
* or INVALID_HANDLE on error.
|
|
*/
|
|
native JSONValue json_load_file_ex(const char sFilePath[PLATFORM_MAX_PATH], char[] sErrorText, int maxlen, int &iLine, int &iColumn);
|
|
|
|
|
|
|
|
/**
|
|
* Encoding
|
|
*
|
|
* This sections describes the functions that can be used to encode values
|
|
* to JSON. By default, only objects and arrays can be encoded directly,
|
|
* since they are the only valid root values of a JSON text.
|
|
*
|
|
*/
|
|
|
|
/**
|
|
* Saves the JSON representation of hObject in sJSON.
|
|
*
|
|
* @param hObject String containing valid JSON
|
|
* @param sJSON Buffer to store the created JSON string.
|
|
* @param maxlength Maximum length of string buffer.
|
|
* @param iIndentWidth Indenting with iIndentWidth spaces.
|
|
* The valid range for this is between 0 and 31 (inclusive),
|
|
* other values result in an undefined output. If this is set
|
|
* to 0, no newlines are inserted between array and object items.
|
|
* @param bEnsureAscii If this is set, the output is guaranteed
|
|
* to consist only of ASCII characters. This is achieved
|
|
* by escaping all Unicode characters outside the ASCII range.
|
|
* @param bSortKeys If this flag is used, all the objects in output are sorted
|
|
* by key. This is useful e.g. if two JSON texts are diffed
|
|
* or visually compared.
|
|
* @param bPreserveOrder If this flag is used, object keys in the output are sorted
|
|
* into the same order in which they were first inserted to
|
|
* the object. For example, decoding a JSON text and then
|
|
* encoding with this flag preserves the order of object keys.
|
|
* @return Length of the returned string or -1 on error.
|
|
*/
|
|
native int json_dump(JSONValue hObject, char[] sJSON, int maxlength, int iIndentWidth = 4, bool bEnsureAscii = false, bool bSortKeys = false, bool bPreserveOrder = false);
|
|
|
|
/**
|
|
* Write the JSON representation of hObject to the file sFilePath.
|
|
* If sFilePath already exists, it is overwritten.
|
|
*
|
|
* @param hObject String containing valid JSON
|
|
* @param sFilePath Buffer to store the created JSON string.
|
|
* @param iIndentWidth Indenting with iIndentWidth spaces.
|
|
* The valid range for this is between 0 and 31 (inclusive),
|
|
* other values result in an undefined output. If this is set
|
|
* to 0, no newlines are inserted between array and object items.
|
|
* @param bEnsureAscii If this is set, the output is guaranteed
|
|
* to consist only of ASCII characters. This is achieved
|
|
* by escaping all Unicode characters outside the ASCII range.
|
|
* @param bSortKeys If this flag is used, all the objects in output are sorted
|
|
* by key. This is useful e.g. if two JSON texts are diffed
|
|
* or visually compared.
|
|
* @param bPreserveOrder If this flag is used, object keys in the output are sorted
|
|
* into the same order in which they were first inserted to
|
|
* the object. For example, decoding a JSON text and then
|
|
* encoding with this flag preserves the order of object keys.
|
|
* @return Length of the returned string or -1 on error.
|
|
*/
|
|
native bool json_dump_file(JSONValue hObject, const char[] sFilePath, int iIndentWidth = 4, bool bEnsureAscii = false, bool bSortKeys = false, bool bPreserveOrder = false);
|
|
|
|
|
|
|
|
|
|
/**
|
|
* MethodMaps
|
|
*
|
|
* Again: EXPERIMENTAL!
|
|
*
|
|
*/
|
|
|
|
|
|
enum JSONObjectUpdateType {
|
|
Update_All = 0,
|
|
Update_Existing,
|
|
Update_Missing
|
|
};
|
|
|
|
/**
|
|
* Base methodmap for all of smjansson's handles
|
|
*/
|
|
methodmap JSONValue < Handle {
|
|
property JSONType Type {
|
|
public get() {
|
|
return json_typeof(this);
|
|
}
|
|
}
|
|
|
|
property bool IsObject {
|
|
public get() {
|
|
return (this.Type == JSONType_Object);
|
|
}
|
|
}
|
|
|
|
property bool IsArray {
|
|
public get() {
|
|
return (this.Type == JSONType_Array);
|
|
}
|
|
}
|
|
|
|
property bool IsString {
|
|
public get() {
|
|
return (this.Type == JSONType_String);
|
|
}
|
|
}
|
|
|
|
property bool IsInteger {
|
|
public get() {
|
|
return (this.Type == JSONType_Integer);
|
|
}
|
|
}
|
|
|
|
property bool IsFloat {
|
|
public get() {
|
|
return (this.Type == JSONType_Float);
|
|
}
|
|
}
|
|
|
|
property bool IsTrue {
|
|
public get() {
|
|
return (this.Type == JSONType_True);
|
|
}
|
|
}
|
|
|
|
property bool IsFalse {
|
|
public get() {
|
|
return (this.Type == JSONType_False);
|
|
}
|
|
}
|
|
|
|
property bool IsNull {
|
|
public get() {
|
|
return (this.Type == JSONType_Null);
|
|
}
|
|
}
|
|
|
|
property bool IsNumber {
|
|
public get() {
|
|
return (this.Type == JSONType_Integer || this.Type == JSONType_Float);
|
|
}
|
|
}
|
|
|
|
property bool IsBoolean {
|
|
public get() {
|
|
return (this.Type == JSONType_True || this.Type == JSONType_False);
|
|
}
|
|
}
|
|
|
|
property any Value {
|
|
// not implemented
|
|
}
|
|
|
|
public bool Equals(JSONValue other) {
|
|
return json_equal(this, other);
|
|
}
|
|
|
|
public JSONValue Copy(bool deep = false) {
|
|
if (deep) {
|
|
return view_as<JSONValue>(json_deep_copy(this));
|
|
} else {
|
|
return view_as<JSONValue>(json_copy(this));
|
|
}
|
|
}
|
|
|
|
public void TypeToString(char[] buffer, int maxlength) {
|
|
if (!Stringify_json_type(view_as<JSONType>(this.Type), buffer, maxlength)) {
|
|
ThrowError("Attempting to get type of a non-SMJansson handle");
|
|
}
|
|
}
|
|
}
|
|
|
|
methodmap JSONBoolean < JSONValue {
|
|
public JSONBoolean(bool value) {
|
|
return view_as<JSONBoolean>(json_boolean(value));
|
|
}
|
|
|
|
property bool Value {
|
|
public get() {
|
|
if (this.Type == JSONType_True) {
|
|
return true;
|
|
} else if (this.Type == JSONType_False) {
|
|
return false;
|
|
}
|
|
ThrowError("Not a JSONBoolean value");
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
|
|
methodmap JSONNull < JSONValue {
|
|
public JSONNull() {
|
|
return view_as<JSONNull>(json_null());
|
|
}
|
|
}
|
|
|
|
methodmap JSONString < JSONValue {
|
|
public JSONString(const char[] value) {
|
|
return view_as<JSONString>(json_string(value));
|
|
}
|
|
|
|
public static JSONString Format(int bufferSize = 4096, const char[] format, any ...) {
|
|
char[] buffer = new char[bufferSize];
|
|
VFormat(buffer, bufferSize, format, 3);
|
|
return new JSONString(buffer);
|
|
}
|
|
|
|
public int GetString(char[] buffer, int length) {
|
|
return json_string_value(this, buffer, length);
|
|
}
|
|
|
|
public bool SetString(char[] value) {
|
|
return json_string_set(this, value);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Base map inherited by JSONInteger and JSONFloat to get the value of either, cast to float.
|
|
*/
|
|
methodmap JSONNumber < JSONValue {
|
|
public float FloatValue() {
|
|
return json_number_value(this);
|
|
}
|
|
}
|
|
|
|
methodmap JSONInteger < JSONNumber {
|
|
public JSONInteger(int value) {
|
|
return view_as<JSONInteger>(json_integer(value));
|
|
}
|
|
|
|
property int Value {
|
|
public get() {
|
|
return json_integer_value(this);
|
|
}
|
|
public set(int value) {
|
|
json_integer_set(this, value);
|
|
}
|
|
}
|
|
}
|
|
|
|
methodmap JSONFloat < JSONNumber {
|
|
public JSONFloat(float value) {
|
|
return view_as<JSONFloat>(json_real(value));
|
|
}
|
|
|
|
property float Value {
|
|
public get() {
|
|
return json_real_value(this);
|
|
}
|
|
public set(float value) {
|
|
json_real_set(this, value);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Provides a few functions for valid root nodes (JSONArray and JSONObject)
|
|
*/
|
|
methodmap JSONRootNode < JSONValue {
|
|
/**
|
|
* Dumps the contents of the given root node to a string.
|
|
*
|
|
* @return Number of characters written
|
|
*/
|
|
public int ToString(char[] buffer, int maxlength, int indentWidth = 4,
|
|
bool asciiOnly = false, bool sortKeys = false, bool preserveOrder = false) {
|
|
return json_dump(this, buffer, maxlength, indentWidth, asciiOnly, sortKeys,
|
|
preserveOrder);
|
|
}
|
|
|
|
/**
|
|
* @return True on success
|
|
*/
|
|
public bool ToFile(const char[] filePath, int indentWidth = 4, bool asciiOnly = false,
|
|
bool sortKeys = false, bool preserveOrder = false) {
|
|
return json_dump_file(this, filePath, indentWidth, asciiOnly, sortKeys, preserveOrder);
|
|
}
|
|
|
|
public static JSONRootNode FromFile(const char[] filePath) {
|
|
char path[PLATFORM_MAX_PATH];
|
|
strcopy(path, sizeof(path), filePath);
|
|
return view_as<JSONRootNode>(json_load_file(path));
|
|
}
|
|
|
|
public static JSONRootNode Pack(const char[] packString, ArrayList params) {
|
|
return JSONValue_ByPack(packString, params);
|
|
}
|
|
|
|
public void DumpToServer() {
|
|
char sMsg[4096];
|
|
this.ToString(sMsg, sizeof(sMsg));
|
|
|
|
PrintToServer(sMsg);
|
|
}
|
|
}
|
|
|
|
methodmap JSONArray < JSONRootNode {
|
|
public JSONArray() {
|
|
return view_as<JSONArray>(json_array());
|
|
}
|
|
|
|
property int Length {
|
|
public get() {
|
|
if (this.Type != JSONType_Array) {
|
|
ThrowError("Handle is not an array");
|
|
}
|
|
return json_array_size(this);
|
|
}
|
|
}
|
|
|
|
public JSONValue Get(int index) {
|
|
return view_as<JSONValue>(json_array_get(this, index));
|
|
}
|
|
|
|
public bool Set(int index, JSONValue value, bool autoClose = true) {
|
|
if (autoClose) {
|
|
return json_array_set_new(this, index, value);
|
|
}
|
|
return json_array_set(this, index, value);
|
|
}
|
|
|
|
public bool Append(JSONValue value, bool autoClose = true) {
|
|
if (autoClose) {
|
|
return json_array_append_new(this, value);
|
|
}
|
|
return json_array_append(this, value);
|
|
}
|
|
|
|
public bool Insert(int index, JSONValue value, bool autoClose = true) {
|
|
if (autoClose) {
|
|
return json_array_insert_new(this, index, value);
|
|
}
|
|
return json_array_insert(this, index, value);
|
|
}
|
|
|
|
public bool Remove(int index) {
|
|
return json_array_remove(this, index);
|
|
}
|
|
|
|
public bool Clear() {
|
|
return json_array_clear(this);
|
|
}
|
|
|
|
public bool Extend(JSONArray other) {
|
|
return json_array_extend(this, other);
|
|
}
|
|
|
|
/**
|
|
* Utility functions
|
|
*/
|
|
|
|
/* Booleans */
|
|
|
|
public bool GetBool(int index, bool defValue = false) {
|
|
JSONValue value = this.Get(index);
|
|
if(!value)
|
|
return defValue;
|
|
|
|
JSONType type = value.Type;
|
|
delete value;
|
|
|
|
switch (type) {
|
|
case JSONType_True: { return true; }
|
|
case JSONType_False: { return false; }
|
|
}
|
|
return defValue;
|
|
}
|
|
|
|
public bool SetBool(int index, bool value) {
|
|
return this.Set(index, new JSONBoolean(value));
|
|
}
|
|
|
|
public bool AppendBool(bool value) {
|
|
return this.Append(new JSONBoolean(value));
|
|
}
|
|
|
|
public bool InsertBool(int index, bool value) {
|
|
return this.Insert(index, new JSONBoolean(value));
|
|
}
|
|
|
|
/* Floats */
|
|
|
|
public float GetFloat(int index, float defValue = 0.0) {
|
|
JSONValue value = this.Get(index);
|
|
if(!value)
|
|
return defValue;
|
|
|
|
float result = (json_is_number(value) ?
|
|
(view_as<JSONNumber>(value)).FloatValue() : defValue);
|
|
delete value;
|
|
|
|
return result;
|
|
}
|
|
|
|
public bool SetFloat(int index, float value) {
|
|
return this.Set(index, new JSONFloat(value));
|
|
}
|
|
|
|
public bool AppendFloat(float value) {
|
|
return this.Append(new JSONFloat(value));
|
|
}
|
|
|
|
public bool InsertFloat(int index, float value) {
|
|
return this.Insert(index, new JSONFloat(value));
|
|
}
|
|
|
|
/* Integers */
|
|
|
|
public int GetInt(int index, int defValue = 0) {
|
|
JSONValue value = this.Get(index);
|
|
if(!value)
|
|
return defValue;
|
|
|
|
int result = value.Type == JSONType_Integer ? (view_as<JSONInteger>(value)).Value : 0;
|
|
delete value;
|
|
|
|
return result;
|
|
}
|
|
|
|
public bool SetInt(int index, int value) {
|
|
return this.Set(index, new JSONInteger(value));
|
|
}
|
|
|
|
public bool AppendInt(int value) {
|
|
return this.Append(new JSONInteger(value));
|
|
}
|
|
|
|
public bool InsertInt(int index, int value) {
|
|
return this.Insert(index, new JSONInteger(value));
|
|
}
|
|
|
|
/* Strings */
|
|
|
|
public int GetString(int index, char[] buffer, int maxlength) {
|
|
JSONValue value = this.Get(index);
|
|
if(!value)
|
|
return -1;
|
|
|
|
int result = -1;
|
|
if (value.Type == JSONType_String) {
|
|
result = (view_as<JSONString>(value)).GetString(buffer, maxlength);
|
|
}
|
|
delete value;
|
|
return result;
|
|
}
|
|
|
|
public bool SetString(int index, const char[] value) {
|
|
return this.Set(index, new JSONString(value));
|
|
}
|
|
|
|
public bool AppendString(const char[] value) {
|
|
return this.Append(new JSONString(value));
|
|
}
|
|
|
|
public bool InsertString(int index, const char[] value) {
|
|
return this.Insert(index, new JSONString(value));
|
|
}
|
|
|
|
/* Misc. functions */
|
|
|
|
public static JSONArray FromFile(const char[] filePath) {
|
|
JSONRootNode data = JSONRootNode.FromFile(filePath);
|
|
|
|
if (data.Type == JSONType_Array) {
|
|
return view_as<JSONArray>(data);
|
|
} else {
|
|
ThrowError("File loaded by JSONArray.FromFile was not an array");
|
|
delete data;
|
|
return null;
|
|
}
|
|
}
|
|
|
|
public static JSONArray Pack(const char[] packString, ArrayList params) {
|
|
int length = strlen(packString);
|
|
if (packString[0] == '[' && packString[length - 1] == ']') {
|
|
return view_as<JSONArray>(JSONRootNode.Pack(packString, params));
|
|
} else {
|
|
ThrowError("Pack string '%s' is not appropriate for creating a JSONArray",
|
|
packString);
|
|
return null;
|
|
}
|
|
}
|
|
}
|
|
|
|
methodmap JSONObject < JSONRootNode {
|
|
public JSONObject() {
|
|
return view_as<JSONObject>(json_object());
|
|
}
|
|
|
|
property int Size {
|
|
public get() {
|
|
return json_object_size(this);
|
|
}
|
|
}
|
|
|
|
public JSONValue Get(const char[] key) {
|
|
return view_as<JSONValue>(json_object_get(this, key));
|
|
}
|
|
|
|
public bool Set(const char[] key, JSONValue value, bool autoClose = true) {
|
|
if (autoClose) {
|
|
return json_object_set_new(this, key, value);
|
|
}
|
|
return json_object_set(this, key, value);
|
|
}
|
|
|
|
/**
|
|
* @return true on success
|
|
*/
|
|
public bool Remove(const char[] key) {
|
|
return json_object_del(this, key);
|
|
}
|
|
|
|
public bool Clear() {
|
|
return json_object_clear(this);
|
|
}
|
|
|
|
public bool Update(JSONObject other, JSONObjectUpdateType updateType = Update_All) {
|
|
switch (updateType) {
|
|
case Update_Existing: {
|
|
return json_object_update_existing(this, other);
|
|
}
|
|
case Update_Missing: {
|
|
return json_object_update_missing(this, other);
|
|
}
|
|
}
|
|
return json_object_update(this, other);
|
|
}
|
|
|
|
/**
|
|
* Utility functions
|
|
*/
|
|
|
|
public bool GetBool(const char[] key, bool defValue = false) {
|
|
JSONValue value = this.Get(key);
|
|
if(!value)
|
|
return defValue;
|
|
|
|
JSONType type = value.Type;
|
|
delete value;
|
|
|
|
switch (type) {
|
|
case JSONType_True: { return true; }
|
|
case JSONType_False: { return false; }
|
|
}
|
|
return defValue;
|
|
}
|
|
|
|
public bool SetBool(const char[] key, bool value) {
|
|
return this.Set(key, new JSONBoolean(value));
|
|
}
|
|
|
|
/* Floats */
|
|
|
|
public float GetFloat(const char[] key, float defValue = 0.0) {
|
|
JSONValue value = this.Get(key);
|
|
if(!value)
|
|
return defValue;
|
|
|
|
float result = (json_is_number(value) ?
|
|
(view_as<JSONNumber>(value)).FloatValue() : defValue);
|
|
delete value;
|
|
|
|
return result;
|
|
}
|
|
|
|
public bool SetFloat(const char[] key, float value) {
|
|
return this.Set(key, new JSONFloat(value));
|
|
}
|
|
|
|
/* Integers */
|
|
|
|
public int GetInt(const char[] key, int defValue = 0) {
|
|
JSONValue value = this.Get(key);
|
|
if(!value)
|
|
return defValue;
|
|
|
|
int result = value.Type == JSONType_Integer ?
|
|
(view_as<JSONInteger>(value)).Value : defValue;
|
|
delete value;
|
|
|
|
return result;
|
|
}
|
|
|
|
public bool SetInt(const char[] key, int value) {
|
|
return this.Set(key, new JSONInteger(value));
|
|
}
|
|
|
|
/* Strings */
|
|
|
|
public int GetString(const char[] key, char[] buffer, int maxlength) {
|
|
JSONValue value = this.Get(key);
|
|
if(!value)
|
|
return -1;
|
|
|
|
int result = -1;
|
|
if (value.Type == JSONType_String) {
|
|
result = (view_as<JSONString>(value)).GetString(buffer, maxlength);
|
|
}
|
|
delete value;
|
|
return result;
|
|
}
|
|
|
|
public bool SetString(const char[] key, const char[] value) {
|
|
return this.Set(key, new JSONString(value));
|
|
}
|
|
|
|
/* Misc. functions */
|
|
|
|
public static JSONObject FromFile(const char[] filePath) {
|
|
JSONRootNode data = JSONRootNode.FromFile(filePath);
|
|
|
|
if (data.Type == JSONType_Object) {
|
|
return view_as<JSONObject>(data);
|
|
} else {
|
|
ThrowError("File loaded by JSONObject.FromFile was not an object");
|
|
delete data;
|
|
return null;
|
|
}
|
|
}
|
|
|
|
public static JSONObject Pack(const char[] packString, ArrayList params) {
|
|
int length = strlen(packString);
|
|
if (packString[0] == '{' && packString[length - 1] == '}') {
|
|
return view_as<JSONObject>(JSONRootNode.Pack(packString, params));
|
|
} else {
|
|
ThrowError("Pack string '%s' is not appropriate for creating a JSONObject",
|
|
packString);
|
|
return null;
|
|
}
|
|
}
|
|
}
|
|
|
|
methodmap JSONObjectIterator < Handle {
|
|
public static JSONObjectIterator From(JSONObject obj, const char[] key = "") {
|
|
if (strlen(key) > 0) {
|
|
return view_as<JSONObjectIterator>(json_object_iter_at(obj, key));
|
|
}
|
|
return view_as<JSONObjectIterator>(json_object_iter(obj));
|
|
}
|
|
|
|
public JSONObjectIterator Next(JSONObject obj) {
|
|
return view_as<JSONObjectIterator>(json_object_iter_next(obj, this));
|
|
}
|
|
|
|
public int GetKey(char[] buffer, int maxlength) {
|
|
return json_object_iter_key(this, buffer, maxlength);
|
|
}
|
|
|
|
public JSONValue GetValue() {
|
|
return view_as<JSONValue>(json_object_iter_value(this));
|
|
}
|
|
|
|
public bool SetValue(JSONObject obj, JSONValue value, bool autoclose = true) {
|
|
if (autoclose) {
|
|
return json_object_iter_set_new(obj, this, value);
|
|
}
|
|
return json_object_iter_set(obj, this, value);
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* Some additional constructors
|
|
*
|
|
*
|
|
*/
|
|
|
|
/**
|
|
* Returns a handle to a new JSON string, or INVALID_HANDLE on error.
|
|
* Formats the string according to the SourceMod format rules.
|
|
* The result must be a valid UTF-8 encoded Unicode string.
|
|
*
|
|
* @param sFormat Formatting rules.
|
|
* @param ... Variable number of format parameters.
|
|
* @return Handle to the new String object
|
|
*/
|
|
public JSONString JSONString_ByFormat(const char[] sFormat, ...) {
|
|
char sTmp[4096];
|
|
VFormat(sTmp, sizeof(sTmp), sFormat, 2);
|
|
|
|
return new JSONString(sTmp);
|
|
}
|
|
|
|
|
|
/**
|
|
* Returns a handle to a new JSON string, or INVALID_HANDLE on error.
|
|
* This stock allows to specify the size of the temporary buffer used
|
|
* to create the string. Use this if the default of 4096 is not enough
|
|
* for your string.
|
|
* Formats the string according to the SourceMod format rules.
|
|
* The result must be a valid UTF-8 encoded Unicode string.
|
|
*
|
|
* @param tmpBufferLength Size of the temporary buffer
|
|
* @param sFormat Formatting rules.
|
|
* @param ... Variable number of format parameters.
|
|
* @return Handle to the new String object
|
|
*/
|
|
public JSONString JSONString_ByFormatEx(int tmpBufferLength, const char[] sFormat, ...) {
|
|
char[] sTmp = new char[tmpBufferLength];
|
|
VFormat(sTmp, tmpBufferLength, sFormat, 3);
|
|
|
|
return new JSONString(sTmp);
|
|
}
|
|
|
|
|
|
/**
|
|
* Pack String Rules
|
|
*
|
|
* Here's the full list of format characters:
|
|
* n Output a JSON null value. No argument is consumed.
|
|
* s Output a JSON string, consuming one argument.
|
|
* b Output a JSON bool value, consuming one argument.
|
|
* i Output a JSON integer value, consuming one argument.
|
|
* f Output a JSON real value, consuming one argument.
|
|
* r Output a JSON real value, consuming one argument.
|
|
* [] Build an array with contents from the inner format string,
|
|
* recursive value building is supported.
|
|
* No argument is consumed.
|
|
* {} Build an array with contents from the inner format string.
|
|
* The first, third, etc. format character represent a key,
|
|
* and must be s (as object keys are always strings). The
|
|
* second, fourth, etc. format character represent a value.
|
|
* Recursive value building is supported.
|
|
* No argument is consumed.
|
|
*
|
|
*/
|
|
|
|
/**
|
|
* This method can be used to create json objects/arrays directly
|
|
* without having to create the structure.
|
|
* See 'Pack String Rules' for more details.
|
|
*
|
|
* @param sPackString Pack string similiar to Format()s fmt.
|
|
* See 'Pack String Rules'.
|
|
* @param hParams ADT Array containing all keys and values
|
|
* in the order they appear in the pack string.
|
|
*
|
|
* @error Invalid pack string or pack string and
|
|
* ADT Array don't match up regarding type
|
|
* or size.
|
|
* @return Handle to JSON element.
|
|
*/
|
|
public JSONValue JSONValue_ByPack(const char[] sPackString, Handle hParams) {
|
|
int iPos = 0;
|
|
return json_pack_element_(sPackString, iPos, hParams);
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
* Internal stocks used by json_pack(). Don't use these directly!
|
|
*
|
|
*/
|
|
public JSONArray json_pack_array_(const char[] sFormat, int &iPos, Handle hParams) {
|
|
JSONArray hObj = new JSONArray();
|
|
int iStrLen = strlen(sFormat);
|
|
|
|
for(; iPos < iStrLen;) {
|
|
int this_char = sFormat[iPos];
|
|
|
|
if(this_char == 32 || this_char == 58 || this_char == 44) {
|
|
// Skip whitespace, ',' and ':'
|
|
iPos++;
|
|
continue;
|
|
}
|
|
|
|
if(this_char == 93) {
|
|
// array end
|
|
iPos++;
|
|
break;
|
|
}
|
|
|
|
// Get the next entry as value
|
|
// This automatically increments the position!
|
|
JSONValue hValue = json_pack_element_(sFormat, iPos, hParams);
|
|
|
|
// Append the value to the array.
|
|
hObj.Append(hValue);
|
|
}
|
|
|
|
return hObj;
|
|
}
|
|
|
|
public JSONObject json_pack_object_(const char[] sFormat, int &iPos, Handle hParams) {
|
|
JSONObject hObj = new JSONObject();
|
|
int iStrLen = strlen(sFormat);
|
|
|
|
for(; iPos < iStrLen;) {
|
|
int this_char = sFormat[iPos];
|
|
|
|
if(this_char == 32 || this_char == 58 || this_char == 44) {
|
|
// Skip whitespace, ',' and ':'
|
|
iPos++;
|
|
continue;
|
|
}
|
|
|
|
if(this_char == 125) {
|
|
// } --> object end
|
|
iPos++;
|
|
break;
|
|
}
|
|
|
|
if(this_char != 115) {
|
|
LogError("Object keys must be strings at %d.", iPos);
|
|
delete hObj;
|
|
return view_as<JSONObject>(INVALID_HANDLE);
|
|
}
|
|
|
|
// Get the key string for this object from
|
|
// the hParams array.
|
|
char sKey[255];
|
|
GetArrayString(hParams, 0, sKey, sizeof(sKey));
|
|
RemoveFromArray(hParams, 0);
|
|
|
|
// Advance one character in the pack string,
|
|
// because we've just read the Key string for
|
|
// this object.
|
|
iPos++;
|
|
|
|
// Get the next entry as value
|
|
// This automatically increments the position!
|
|
JSONValue hValue = json_pack_element_(sFormat, iPos, hParams);
|
|
|
|
// Insert into object
|
|
hObj.Set(sKey, hValue);
|
|
}
|
|
|
|
return hObj;
|
|
}
|
|
|
|
public JSONValue json_pack_element_(const char[] sFormat, int &iPos, Handle hParams) {
|
|
int this_char = sFormat[iPos];
|
|
while(this_char == 32 || this_char == 58 || this_char == 44) {
|
|
iPos++;
|
|
this_char = sFormat[iPos];
|
|
}
|
|
|
|
// Advance one character in the pack string
|
|
iPos++;
|
|
|
|
switch(this_char) {
|
|
case 91: {
|
|
// { --> Array
|
|
return json_pack_array_(sFormat, iPos, hParams);
|
|
}
|
|
|
|
case 123: {
|
|
// { --> Object
|
|
return json_pack_object_(sFormat, iPos, hParams);
|
|
|
|
}
|
|
|
|
case 98: {
|
|
// b --> Boolean
|
|
int iValue = GetArrayCell(hParams, 0);
|
|
RemoveFromArray(hParams, 0);
|
|
|
|
return json_boolean(view_as<bool>(iValue));
|
|
}
|
|
|
|
case 102, 114: {
|
|
// r,f --> Real (Float)
|
|
float fValue = GetArrayCell(hParams, 0);
|
|
RemoveFromArray(hParams, 0);
|
|
|
|
return json_real(fValue);
|
|
}
|
|
|
|
case 110: {
|
|
// n --> NULL
|
|
return json_null();
|
|
}
|
|
|
|
case 115: {
|
|
// s --> String
|
|
char sKey[255];
|
|
GetArrayString(hParams, 0, sKey, sizeof(sKey));
|
|
RemoveFromArray(hParams, 0);
|
|
|
|
return json_string(sKey);
|
|
}
|
|
|
|
case 105: {
|
|
// i --> Integer
|
|
int iValue = GetArrayCell(hParams, 0);
|
|
RemoveFromArray(hParams, 0);
|
|
|
|
return json_integer(iValue);
|
|
}
|
|
}
|
|
|
|
SetFailState("Invalid pack String '%s'. Type '%s' not supported at %i", sFormat, this_char, iPos);
|
|
return json_null();
|
|
}
|
|
|
|
|
|
/**
|
|
* Not yet implemented
|
|
*
|
|
* native json_object_foreach(Handle:hObj, ForEachCallback:cb);
|
|
* native Handle:json_unpack(const String:sFormat[], ...);
|
|
*
|
|
*/
|
|
|
|
|
|
/**
|
|
* Do not edit below this line!
|
|
*/
|
|
public Extension __ext_smjansson =
|
|
{
|
|
name = "SMJansson",
|
|
file = "smjansson.ext",
|
|
#if defined AUTOLOAD_EXTENSIONS
|
|
autoload = 1,
|
|
#else
|
|
autoload = 0,
|
|
#endif
|
|
#if defined REQUIRE_EXTENSIONS
|
|
required = 1,
|
|
#else
|
|
required = 0,
|
|
#endif
|
|
};
|
|
|
|
#if !defined REQUIRE_EXTENSIONS
|
|
public __ext_smjansson_SetNTVOptional()
|
|
{
|
|
MarkNativeAsOptional("json_typeof");
|
|
MarkNativeAsOptional("json_equal");
|
|
|
|
MarkNativeAsOptional("json_copy");
|
|
MarkNativeAsOptional("json_deep_copy");
|
|
|
|
MarkNativeAsOptional("json_object");
|
|
MarkNativeAsOptional("json_object_size");
|
|
MarkNativeAsOptional("json_object_get");
|
|
MarkNativeAsOptional("json_object_set");
|
|
MarkNativeAsOptional("json_object_set_new");
|
|
MarkNativeAsOptional("json_object_del");
|
|
MarkNativeAsOptional("json_object_clear");
|
|
MarkNativeAsOptional("json_object_update");
|
|
MarkNativeAsOptional("json_object_update_existing");
|
|
MarkNativeAsOptional("json_object_update_missing");
|
|
|
|
MarkNativeAsOptional("json_object_iter");
|
|
MarkNativeAsOptional("json_object_iter_at");
|
|
MarkNativeAsOptional("json_object_iter_next");
|
|
MarkNativeAsOptional("json_object_iter_key");
|
|
MarkNativeAsOptional("json_object_iter_value");
|
|
MarkNativeAsOptional("json_object_iter_set");
|
|
MarkNativeAsOptional("json_object_iter_set_new");
|
|
|
|
MarkNativeAsOptional("json_array");
|
|
MarkNativeAsOptional("json_array_size");
|
|
MarkNativeAsOptional("json_array_get");
|
|
MarkNativeAsOptional("json_array_set");
|
|
MarkNativeAsOptional("json_array_set_new");
|
|
MarkNativeAsOptional("json_array_append");
|
|
MarkNativeAsOptional("json_array_append_new");
|
|
MarkNativeAsOptional("json_array_insert");
|
|
MarkNativeAsOptional("json_array_insert_new");
|
|
MarkNativeAsOptional("json_array_remove");
|
|
MarkNativeAsOptional("json_array_clear");
|
|
MarkNativeAsOptional("json_array_extend");
|
|
|
|
MarkNativeAsOptional("json_string");
|
|
MarkNativeAsOptional("json_string_value");
|
|
MarkNativeAsOptional("json_string_set");
|
|
|
|
MarkNativeAsOptional("json_integer");
|
|
MarkNativeAsOptional("json_integer_value");
|
|
MarkNativeAsOptional("json_integer_set");
|
|
|
|
MarkNativeAsOptional("json_real");
|
|
MarkNativeAsOptional("json_real_value");
|
|
MarkNativeAsOptional("json_real_set");
|
|
MarkNativeAsOptional("json_number_value");
|
|
|
|
MarkNativeAsOptional("json_boolean");
|
|
MarkNativeAsOptional("json_true");
|
|
MarkNativeAsOptional("json_false");
|
|
MarkNativeAsOptional("json_null");
|
|
|
|
MarkNativeAsOptional("json_load");
|
|
MarkNativeAsOptional("json_load_file");
|
|
|
|
MarkNativeAsOptional("json_dump");
|
|
MarkNativeAsOptional("json_dump_file");
|
|
}
|
|
#endif
|