#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 json_type { JSON_OBJECT, JSON_ARRAY, JSON_STRING, JSON_INTEGER, JSON_REAL, JSON_TRUE, JSON_FALSE, JSON_NULL } /** * Return the type of the JSON value. * * @param hObj Handle to the JSON value * * @return json_type of the value. */ native json_type json_typeof(Handle 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) == JSON_OBJECT ) #define json_is_array(%1) ( json_typeof(%1) == JSON_ARRAY ) #define json_is_string(%1) ( json_typeof(%1) == JSON_STRING ) #define json_is_integer(%1) ( json_typeof(%1) == JSON_INTEGER ) #define json_is_real(%1) ( json_typeof(%1) == JSON_REAL ) #define json_is_true(%1) ( json_typeof(%1) == JSON_TRUE ) #define json_is_false(%1) ( json_typeof(%1) == JSON_FALSE ) #define json_is_null(%1) ( json_typeof(%1) == JSON_NULL ) #define json_is_number(%1) ( json_typeof(%1) == JSON_INTEGER || json_typeof(%1) == JSON_REAL ) #define json_is_boolean(%1) ( json_typeof(%1) == JSON_TRUE || json_typeof(%1) == JSON_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(json_type input, char[] output, int maxlength) { switch(input) { case JSON_OBJECT: strcopy(output, maxlength, "Object"); case JSON_ARRAY: strcopy(output, maxlength, "Array"); case JSON_STRING: strcopy(output, maxlength, "String"); case JSON_INTEGER: strcopy(output, maxlength, "Integer"); case JSON_REAL: strcopy(output, maxlength, "Real"); case JSON_TRUE: strcopy(output, maxlength, "True"); case JSON_FALSE: strcopy(output, maxlength, "False"); case JSON_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 object * @param hOther Handle to the second JSON object * * @return Returns false if they are inequal or one * or both of the pointers are NULL. */ native bool json_equal(Handle hObj, Handle 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 Handle json_copy(Handle 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 Handle json_deep_copy(Handle 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 Handle 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(Handle 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 Handle json_object_get(Handle 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(Handle hObj, const char[] sKey, Handle 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(Handle hObj, const char[] sKey, Handle 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(Handle 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(Handle 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(Handle hObj, Handle 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(Handle hObj, Handle 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(Handle hObj, Handle 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 * * CloseHandle(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 Handle json_object_iter(Handle 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 Handle json_object_iter_at(Handle hObj, const char[] key); /** * 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 Handle json_object_iter_next(Handle hObj, Handle 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(Handle 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 Handle json_object_iter_value(Handle 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(Handle hObj, Handle hIter, Handle 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(Handle hObj, Handle hIter, Handle 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 Handle 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(Handle 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 Handle json_array_get(Handle 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(Handle hArray, int iIndex, Handle 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(Handle hArray, int iIndex, Handle 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(Handle hArray, Handle 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(Handle hArray, Handle 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(Handle hArray, int iIndex, Handle 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(Handle hArray, int iIndex, Handle 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(Handle hArray, int iIndex); /** * Removes all elements from hArray. * * @param hArray Handle to JSON array * * @return True on success. */ native bool json_array_clear(Handle 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(Handle hArray, Handle 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 Handle 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 Handle 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 Handle 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 Handle 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 Handle 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(Handle 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(Handle hString, 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 * JSON_INTEGER or of the type JSON_REAL. * */ /** * 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 Handle 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(Handle 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(Handle 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 Handle 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(Handle 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(Handle 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(Handle 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 Handle 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 Handle 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 Handle 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 Handle 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(Handle 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(Handle hObject, const char[] sFilePath, int iIndentWidth = 4, bool bEnsureAscii = false, bool bSortKeys = false, bool bPreserveOrder = false); /** * Convenience stocks * * These are some custom functions to ease the development using this * extension. * */ /** * 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 */ stock Handle json_string_format(const char[] sFormat, any ...) { char sTmp[4096]; VFormat(sTmp, sizeof(sTmp), sFormat, 2); return json_string(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 */ stock Handle json_string_format_ex(int tmpBufferLength, const char[] sFormat, any ...) { char[] sTmp = new char[tmpBufferLength]; VFormat(sTmp, tmpBufferLength, sFormat, 3); return json_string(sTmp); } /** * Returns the boolean value of the element in hArray at position iIndex. * * @param hArray Handle to JSON array to get a value from * @param iIndex Position to retrieve * * @return True if it's a boolean and TRUE, * false otherwise. */ stock bool json_array_get_bool(Handle hArray, int iIndex) { Handle hElement = json_array_get(hArray, iIndex); bool bResult = (json_is_true(hElement) ? true : false); delete hElement; return bResult; } /** * Returns the float value of the element in hArray at position iIndex. * * @param hArray Handle to JSON array to get a value from * @param iIndex Position to retrieve * * @return Float value, * or 0.0 if element is not a JSON Real. */ stock float json_array_get_float(Handle hArray, int iIndex) { Handle hElement = json_array_get(hArray, iIndex); float fResult = (json_is_number(hElement) ? json_number_value(hElement) : 0.0); delete hElement; return fResult; } /** * Returns the integer value of the element in hArray at position iIndex. * * @param hArray Handle to JSON array to get a value from * @param iIndex Position to retrieve * * @return Integer value, * or 0 if element is not a JSON Integer. */ stock int json_array_get_int(Handle hArray, int iIndex) { Handle hElement = json_array_get(hArray, iIndex); int iResult = (json_is_integer(hElement) ? json_integer_value(hElement) : 0); delete hElement; return iResult; } /** * Saves the associated value of the element in hArray at position iIndex * as a null terminated UTF-8 encoded string in the passed buffer. * * @param hArray Handle to JSON array to get a value from * @param iIndex Position to retrieve * @param sBuffer Buffer to store the value of the String. * @param maxlength Maximum length of string buffer. * * @error Element is not a JSON String. * @return Length of the returned string or -1 on error. */ stock int json_array_get_string(Handle hArray, int iIndex, char[] sBuffer, int maxlength) { Handle hElement = json_array_get(hArray, iIndex); int iResult = -1; if(json_is_string(hElement)) { iResult = json_string_value(hElement, sBuffer, maxlength); } delete hElement; return iResult; } /** * Returns the boolean value of the element in hObj at entry sKey. * * @param hObj Handle to JSON object to get a value from * @param sKey Entry to retrieve * * @return True if it's a boolean and TRUE, * false otherwise. */ stock bool json_object_get_bool(Handle hObj, const char[] sKey) { Handle hElement = json_object_get(hObj, sKey); bool bResult = json_is_true(hElement); delete hElement; return bResult; } /** * Returns the float value of the element in hObj at entry sKey. * * @param hObj Handle to JSON object to get a value from * @param sKey Position to retrieve * * @return Float value, * or 0.0 if element is not a JSON Real. */ stock float json_object_get_float(Handle hObj, const char[] sKey) { Handle hElement = json_object_get(hObj, sKey); float fResult = (json_is_number(hElement) ? json_number_value(hElement) : 0.0); delete hElement; return fResult; } /** * Returns the integer value of the element in hObj at entry sKey. * * @param hObj Handle to JSON object to get a value from * @param sKey Position to retrieve * * @return Integer value, * or 0 if element is not a JSON Integer. */ stock int json_object_get_int(Handle hObj, const char[] sKey) { Handle hElement = json_object_get(hObj, sKey); int iResult = (json_is_integer(hElement) ? json_integer_value(hElement) : 0); delete hElement; return iResult; } /** * Saves the associated value of the element in hObj at entry sKey * as a null terminated UTF-8 encoded string in the passed buffer. * * @param hObj Handle to JSON object to get a value from * @param sKey Entry to retrieve * @param sBuffer Buffer to store the value of the String. * @param maxlength Maximum length of string buffer. * * @error Element is not a JSON String. * @return Length of the returned string or -1 on error. */ stock int json_object_get_string(Handle hObj, const char[] sKey, char[] sBuffer, int maxlength) { Handle hElement = json_object_get(hObj, sKey); int iResult = -1; if(json_is_string(hElement)) { iResult = json_string_value(hElement, sBuffer, maxlength); } delete hElement; return iResult; } /** * 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. */ stock Handle json_pack(const char[] sPackString, ArrayList hParams) { int iPos = 0; return json_pack_element_(sPackString, iPos, hParams); } /** * Internal stocks used by json_pack(). Don't use these directly! * */ stock Handle json_pack_array_(const char[] sFormat, int &iPos, ArrayList hParams) { Handle hObj = json_array(); 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! Handle hValue = json_pack_element_(sFormat, iPos, hParams); // Append the value to the array. json_array_append_new(hObj, hValue); } return hObj; } stock Handle json_pack_object_(const char[] sFormat, int &iPos, ArrayList hParams) { Handle hObj = json_object(); 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); return INVALID_HANDLE; } // Get the key string for this object from // the hParams array. char sKey[255]; hParams.GetString(0, sKey, sizeof(sKey)); hParams.Erase(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! Handle hValue = json_pack_element_(sFormat, iPos, hParams); // Insert into object json_object_set_new(hObj, sKey, hValue); } return hObj; } stock Handle json_pack_element_(const char[] sFormat, int &iPos, ArrayList 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 = hParams.Get(0); hParams.Erase(0); return json_boolean(view_as(iValue)); } case 102, 114: { // r,f --> Real (Float) float iValue = hParams.Get(0); hParams.Erase(0); return json_real(iValue); } case 110: { // n --> NULL return json_null(); } case 115: { // s --> String char sKey[255]; hParams.GetString(0, sKey, sizeof(sKey)); hParams.Erase(0); return json_string(sKey); } case 105: { // i --> Integer int iValue = hParams.Get(0); hParams.Erase(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 char[] 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 void __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