From fb0fc0a30a2ea4c617523046d7e05b4163c0bdab Mon Sep 17 00:00:00 2001 From: Bogdan Date: Sun, 21 Aug 2022 15:22:55 +0200 Subject: [PATCH] switch from internal jReadWrite to external --- CMakeLists.txt | 4 +- extlibs/jRead.c | 784 ----------------------------------------------- extlibs/jRead.h | 128 -------- extlibs/jWrite.c | 561 --------------------------------- extlibs/jWrite.h | 217 ------------- 5 files changed, 1 insertion(+), 1693 deletions(-) delete mode 100644 extlibs/jRead.c delete mode 100644 extlibs/jRead.h delete mode 100644 extlibs/jWrite.c delete mode 100644 extlibs/jWrite.h diff --git a/CMakeLists.txt b/CMakeLists.txt index ef814a5..b833856 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,13 +13,10 @@ idf_component_register( "src/MQTT.c" "src/MQTTSysHandler.c" "src/OTA.c" - "extlibs/jRead.c" - "extlibs/jWrite.c" INCLUDE_DIRS "." "include" "src" - "extlibs" REQUIRES nvs_flash libespfs @@ -30,4 +27,5 @@ idf_component_register( esp_modem esp_https_ota app_update + jReadWrite ) \ No newline at end of file diff --git a/extlibs/jRead.c b/extlibs/jRead.c deleted file mode 100644 index 9e73e22..0000000 --- a/extlibs/jRead.c +++ /dev/null @@ -1,784 +0,0 @@ -// jRead.cpp -// Version 1v6 -// -// jRead - an in-place JSON element reader -// ======================================= -// -// Instead of parsing JSON into some structure, this maintains the input JSON as unaltered text -// and allows queries to be made on it directly. -// -// e.g. with the simple JSON: -// { -// "astring":"This is a string", -// "anumber":42, -// "myarray":[ "one", 2, {"description":"element 3"}, null ], -// "yesno":true, -// "HowMany":"1234", -// "foo":null -// } -// -// calling: -// jRead( json, "{'myarray'[0", &jElem ); -// -// would return: -// jElem.dataType= JREAD_STRING; -// jElem.elements= 1 -// jElem.bytelen= 3 -// jElem.pValue -> "one" -// -// or you could call the helper functions: -// jRead_string( json, "{'astring'", destString, MAXLEN ); -// jRead_int( json, "{'anumber'", &myint ); -// jRead_string( json, "{'myarray'[3", destString, MAXLEN ); -// etc. -// -// Note that the helper functions do type coersion and always return a value -// (on error an empty string is returned or value of zero etc.) -// -// The query string simply defines the route to the required data item -// as an arbitary list of object or array specifiers: -// object element= "{'keyname'" -// array element= "[INDEX" -// -// The jRead() function fills a jReadElement structure to describe the located element -// this can be used to locate any element, not just terminal values -// e.g. -// jRead( json, "{'myarray'", &jElem ); -// -// in this case jElem would contain: -// jElem.dataType= JSON_ARRAY -// jElem.elements= 4 -// jElem.bytelen= 46 -// jElem.pValue -> [ "one", 2, {"descripton":"element 3"}, null ] ... -// -// allowing jRead to be called again on the array: -// e.g. -// jRead( jElem.pValue, "[3", &jElem ); // get 4th element - the null value -// -// .oO! see main.c runExamples() for a whole bunch of examples !Oo. -// ------------------------------------------------------- -// -// Note that jRead never modifies the source JSON and does not allocate any memory. -// i.e. elements are returned as pointer and length into the source text. -// -// Functions -// ========= -// Main JSON reader: -// int jRead( char * JsonSource, char *query, jReadElement &pResult ); -// -// Extended function using query parameters for indexing: -// int jRead( char * JsonSource, char *query, jReadElement &pResult, int *queryParams ); -// -// Function to step thru JSON arrays instead of indexing: -// char *jReadArrayStep( char *pJsonArray, struct jReadElement *pResult ); -// -// Optional Helper functions: -// long jRead_long( char *pJson, char *pQuery ); -// int jRead_int( char *pJson, char *pQuery ); -// double jRead_double( char *pJson, char *pQuery ); -// int jRead_string( char *pJson, char *pQuery, char *pDest, int destlen ); -// -// Optional String output Functions -// char * jReadTypeToString( int dataType ); // string describes dataType -// char * jReadErrorToString( int error ); // string descibes error code -// -// *NEW* in 1v2 -// - "{NUMBER" returns the "key" value at that index within an object -// - jReadParam() adds queryParams which can be used as indexes into arrays (or into -// objects to return key values) by specifying '*' in the query string -// e.g. jReadParam( pJson, "[*", &result, &index ) -// *NEW in 1v4 -// - fixed a couple of error return values -// - added #define JREAD_DOUBLE_QUOTE_IN_QUERY -// *NEW* in 1v5 (11mar2015) -// - fixed null ptr if '[*' used when null param passed -// *NEW* in 1v6 (24sep2016) -// - fixed handling of empty arrays and objects -// -// TonyWilk, 24sep2016 -// mail at tonywilk . co .uk -// -// License: "Free as in You Owe Me a Beer" -// - actually, since some people really worry about licenses, you are free to apply -// whatever licence you want. -// -// Note: jRead_atol() and jRead_atof() are modified from original routines -// fast_atol() and fast_atof() 09-May-2009 Tom Van Baak (tvb) www.LeapSecond.com -// -// You may want to replace the use of jRead_atol() and jRead_atof() in helper functions -// of your own. Especially note that my atof does not handle exponents. -// -// -#include -#include - - -// By default we use single quote in query strings so it's a lot easier -// to type in code i.e. "{'key'" instead of "{\"key\"" -// -#ifdef JREAD_DOUBLE_QUOTE_IN_QUERY -#define QUERY_QUOTE '\"' -#else -#define QUERY_QUOTE '\'' -#endif - -//------------------------------------------------------ -// Internal Functions - -char * jReadSkipWhitespace( char *sp ); -char * jReadFindTok( char *sp, int *tokType ); -char * jReadGetString( char *pJson, struct jReadElement *pElem, char quote ); -int jReadTextLen( char *pJson ); -int jReadStrcmp( struct jReadElement *j1, struct jReadElement *j2 ); -char * jReadCountObject( char *pJson, struct jReadElement *pResult, int keyIndex ); -char * jReadCountArray( char *pJson, struct jReadElement *pResult ); -char * jRead_atoi( char *p, unsigned int *result ); -char * jRead_atol( char *p, long *result ); -char * jRead_atof( char *p, double *result); - -//======================================================= - -char *jReadSkipWhitespace( char *sp ) -{ - while( (*sp != '\0') && (*sp <= ' ') ) - sp++; - return sp; -}; - - -// Find start of a token -// - returns pointer to start of next token or element -// returns type via tokType -// -char *jReadFindTok( char *sp, int *tokType ) -{ - char c; - sp= jReadSkipWhitespace(sp); - c= *sp; - if( c == '\0' ) *tokType= JREAD_EOL; - else if((c == '"') || (c == QUERY_QUOTE))*tokType= JREAD_STRING; - else if((c >= '0') && (c <= '9')) *tokType= JREAD_NUMBER; - else if( c == '-') *tokType= JREAD_NUMBER; - else if( c == '{') *tokType= JREAD_OBJECT; - else if( c == '[') *tokType= JREAD_ARRAY; - else if( c == '}') *tokType= JREAD_EOBJECT; - else if( c == ']') *tokType= JREAD_EARRAY; - else if((c == 't') || (c == 'f')) *tokType= JREAD_BOOL; - else if( c == 'n') *tokType= JREAD_NULL; - else if( c == ':') *tokType= JREAD_COLON; - else if( c == ',') *tokType= JREAD_COMMA; - else if( c == '*') *tokType= JREAD_QPARAM; - else *tokType= JREAD_ERROR; - return sp; -}; - -// jReadGetString -// - assumes next element is "string" which may include "\" sequences -// - returns pointer to -------------^ -// - pElem contains result ( JREAD_STRING, length, pointer to string) -// - pass quote = '"' for Json, quote = '\'' for query scanning -// -// returns: pointer into pJson after the string (char after the " terminator) -// pElem contains pointer and length of string (or dataType=JREAD_ERROR) -// -char * jReadGetString( char *pJson, struct jReadElement *pElem, char quote ) -{ - short skipch; - pElem->dataType= JREAD_ERROR; - pElem->elements= 1; - pElem->bytelen= 0; - pJson= jReadSkipWhitespace( pJson ); - if( *pJson == quote ) - { - pJson++; - pElem->pValue= pJson; // -> start of actual string - pElem->bytelen=0; - skipch= 0; - while( *pJson != '\0' ) - { - if( skipch ) - skipch= 0; - else if( *pJson == '\\' ) // "\" sequence - skipch= 1; - else if( *pJson == quote ) - { - pElem->dataType= JREAD_STRING; - pJson++; - break; - } - pElem->bytelen++; - pJson++; - }; - }; - return pJson; -}; - -// jReadTextLen -// - used to identify length of element text -// - returns no. of chars from pJson upto a terminator -// - terminators: ' ' , } ] -// -int jReadTextLen( char *pJson ) -{ - int len= 0; - while( (*pJson > ' ' ) && // any ctrl char incl '\0' - (*pJson != ',' ) && - (*pJson != '}' ) && - (*pJson != ']' ) ) - { - len++; - pJson++; - } - return len; -} - -// compare two json elements -// returns: 0 if they are identical strings, else 1 -// -int jReadStrcmp( struct jReadElement *j1, struct jReadElement *j2 ) -{ - int i; - if( (j1->dataType != JREAD_STRING) || - (j2->dataType != JREAD_STRING) || - (j1->bytelen != j2->bytelen ) ) - return 1; - - for( i=0; i< j1->bytelen; i++ ) - if( ((char *)(j1->pValue))[i] != ((char *)(j2->pValue))[i] ) - return 1; - return 0; -} - -// read unsigned int from string -char * jRead_atoi( char *p, unsigned int *result ) -{ - unsigned int x = 0; - while (*p >= '0' && *p <= '9') { - x = (x*10) + (*p - '0'); - ++p; - } - *result= x; - return p; -} - -// read long int from string -// -char * jRead_atol( char *p, long *result ) -{ - long x = 0; - int neg = 0; - if (*p == '-') { - neg = 1; - ++p; - } - while (*p >= '0' && *p <= '9') { - x = (x*10) + (*p - '0'); - ++p; - } - if (neg) { - x = -x; - } - *result= x; - return p; -} - - -#define valid_digit(c) ((c) >= '0' && (c) <= '9') - -// read double from string -// *CAUTION* does not handle exponents -// -// -char * jRead_atof( char *p, double *result) -{ - double sign, value; - - // Get sign, if any. - sign = 1.0; - if (*p == '-') { - sign = -1.0; - p += 1; - - } else if (*p == '+') { - p += 1; - } - - // Get digits before decimal point or exponent, if any. - for (value = 0.0; valid_digit(*p); p += 1) { - value = value * 10.0 + (*p - '0'); - } - - // Get digits after decimal point, if any. - if (*p == '.') { - double pow10 = 10.0; - p += 1; - while (valid_digit(*p)) { - value += (*p - '0') / pow10; - pow10 *= 10.0; - p += 1; - } - } - *result= sign * value; - return p; -} - -// read element into destination buffer and add '\0' terminator -// - always copies element irrespective of dataType (unless it's an error) -// - destBuffer is always '\0'-terminated (even on zero lenght returns) -// - returns pointer to destBuffer -// -char *jRead_strcpy( char *destBuffer, int destLength, struct jReadElement *pElement ) -{ - int i; - int len= pElement->bytelen; - char *pdest= destBuffer; - char *psrc= (char *)pElement->pValue; - if( pElement->error == 0 ) - { - if( len >= destLength ) - len= destLength; - for( i=0; i "{... " -// - used to skip unwanted values which are objects -// - keyIndex normally passed as -1 unless we're looking for the nth "key" value -// in which case keyIndex is the index of the key we want -// -char * jReadCountObject( char *pJson, struct jReadElement *pResult, int keyIndex ) -{ - struct jReadElement jElement; - int jTok; - char *sp; - pResult->dataType= JREAD_OBJECT; - pResult->error= 0; - pResult->elements= 0; - pResult->pValue= pJson; - sp= jReadFindTok( pJson+1, &jTok ); // check for empty object - if( jTok == JREAD_EOBJECT ) - { - pJson= sp+1; - }else - { - while( 1 ) - { - pJson= jReadGetString( ++pJson, &jElement, '\"' ); - if( jElement.dataType != JREAD_STRING ) - { - pResult->error= 3; // Expected "key" - break; - } - if( pResult->elements == keyIndex ) // if passed keyIndex - { - *pResult= jElement; // we return "key" at this index - pResult->dataType= JREAD_KEY; - return pJson; - } - pJson= jReadFindTok( pJson, &jTok ); - if( jTok != JREAD_COLON ) - { - pResult->error= 4; // Expected ":" - break; - } - pJson= jRead( ++pJson, "", &jElement ); - if( pResult->error ) - break; - pJson= jReadFindTok( pJson, &jTok ); - pResult->elements++; - if( jTok == JREAD_EOBJECT ) - { - pJson++; - break; - } - if( jTok != JREAD_COMMA ) - { - pResult->error= 6; // Expected "," in object - break; - } - } - } - if( keyIndex >= 0 ) - { - // we wanted a "key" value - that we didn't find - pResult->dataType= JREAD_ERROR; - pResult->error= 11; // Object key not found (bad index) - }else{ - pResult->bytelen= pJson - (char *)pResult->pValue; - } - return pJson; -} - - - -// jReadCountArray -// - used when query ends at an array, we want to return the array length -// - on entry pJson -> "[... " -// - used to skip unwanted values which are arrays -// -char * jReadCountArray( char *pJson, struct jReadElement *pResult ) -{ - struct jReadElement jElement; - int jTok; - char *sp; - pResult->dataType= JREAD_ARRAY; - pResult->error= 0; - pResult->elements= 0; - pResult->pValue= pJson; - sp= jReadFindTok( pJson+1, &jTok ); // check for empty array - if( jTok == JREAD_EARRAY ) - { - pJson= sp+1; - }else - { - while( 1 ) - { - pJson= jRead( ++pJson, "", &jElement ); // array value - if( pResult->error ) - break; - pJson= jReadFindTok( pJson, &jTok ); // , or ] - pResult->elements++; - if( jTok == JREAD_EARRAY ) - { - pJson++; - break; - } - if( jTok != JREAD_COMMA ) - { - pResult->error= 9; // Expected "," in array - break; - } - } - } - pResult->bytelen= pJson - (char *)pResult->pValue; - return pJson; -} - -// jReadArrayStep() -// - reads one value from an array -// - assumes pJsonArray points at the start of an array or array element -// -char *jReadArrayStep( char *pJsonArray, struct jReadElement *pResult ) -{ - int jTok; - - pJsonArray= jReadFindTok( pJsonArray, &jTok ); - switch( jTok ) - { - case JREAD_ARRAY: // start of array - case JREAD_COMMA: // element separator - return jRead( ++pJsonArray, "", pResult ); - - case JREAD_EARRAY: // end of array - pResult->error= 13; // End of array found - break; - default: // some other error - pResult->error= 9; // expected comma in array - break; - } - pResult->dataType= JREAD_ERROR; - return pJsonArray; -} - - -// jRead -// - reads a complete JSON -// - matches pQuery against pJson, results in pResult -// returns: pointer into pJson -// -// Note: is recursive -// -char * jRead( char *pJson, char *pQuery, struct jReadElement *pResult ) -{ - return jReadParam( pJson, pQuery, pResult, NULL ); -} - -char * jReadParam( char *pJson, char *pQuery, struct jReadElement *pResult, int *queryParams ) -{ - int qTok, jTok, bytelen; - unsigned int index, count; - struct jReadElement qElement, jElement; - - pJson= jReadFindTok( pJson, &jTok ); - pQuery= jReadFindTok( pQuery, &qTok ); - - pResult->dataType= jTok; - pResult->bytelen= pResult->elements= pResult->error= 0; - pResult->pValue= pJson; - - if( (qTok != JREAD_EOL) && (qTok != jTok) ) - { - pResult->error= 1; // JSON does not match Query - return pJson; - } - - switch( jTok ) - { - case JREAD_ERROR: // general error, eof etc. - pResult->error= 2; // Error reading JSON value - break; - - case JREAD_OBJECT: // "{" - if( qTok == JREAD_EOL ) - return jReadCountObject( pJson, pResult, -1 ); // return length of object - - pQuery= jReadFindTok( ++pQuery, &qTok ); // "('key'...", "{NUMBER", "{*" or EOL - if( qTok != JREAD_STRING ) - { - index= 0; - switch( qTok ) - { - case JREAD_NUMBER: - pQuery= jRead_atoi( (char *)pQuery, &index ); // index value - break; - case JREAD_QPARAM: - pQuery++; - index= (queryParams != NULL) ? *queryParams++ : 0; // substitute parameter - break; - default: - pResult->error= 12; // Bad Object key - return pJson; - } - return jReadCountObject( pJson, pResult, index ); - } - - pQuery= jReadGetString( pQuery, &qElement, QUERY_QUOTE ); // qElement = query 'key' - // - // read : , ... } - // loop 'til key matched - // - while( 1 ) - { - pJson= jReadGetString( ++pJson, &jElement, '\"' ); - if( jElement.dataType != JREAD_STRING ) - { - pResult->error= 3; // Expected "key" - break; - } - pJson= jReadFindTok( pJson, &jTok ); - if( jTok != JREAD_COLON ) - { - pResult->error= 4; // Expected ":" - break; - } - // compare object keys - if( jReadStrcmp( &qElement, &jElement ) == 0 ) - { - // found object key - return jReadParam( ++pJson, pQuery, pResult, queryParams ); - } - // no key match... skip this value - pJson= jRead( ++pJson, "", pResult ); - pJson= jReadFindTok( pJson, &jTok ); - if( jTok == JREAD_EOBJECT ) - { - pResult->error= 5; // Object key not found - break; - } - if( jTok != JREAD_COMMA ) - { - pResult->error= 6; // Expected "," in object - break; - } - } - break; - case JREAD_ARRAY: // "[NUMBER" or "[*" - // - // read index, skip values 'til index - // - if( qTok == JREAD_EOL ) - return jReadCountArray( pJson, pResult ); // return length of object - - index= 0; - pQuery= jReadFindTok( ++pQuery, &qTok ); // "[NUMBER" or "[*" - if( qTok == JREAD_NUMBER ) - { - pQuery= jRead_atoi( pQuery, &index ); // get array index - }else if( qTok == JREAD_QPARAM ) - { - pQuery++; - index= (queryParams != NULL) ? *queryParams++ : 0; // substitute parameter - } - - count=0; - while( 1 ) - { - if( count == index ) - return jReadParam( ++pJson, pQuery, pResult, queryParams ); // return value at index - // not this index... skip this value - pJson= jRead( ++pJson, "", &jElement ); - if( pResult->error ) - break; - count++; - pJson= jReadFindTok( pJson, &jTok ); // , or ] - if( jTok == JREAD_EARRAY ) - { - pResult->error= 10; // Array element not found (bad index) - break; - } - if( jTok != JREAD_COMMA ) - { - pResult->error= 9; // Expected "," in array - break; - } - } - break; - case JREAD_STRING: // "string" - pJson= jReadGetString( pJson, pResult, '\"' ); - break; - case JREAD_NUMBER: // number (may be -ve) int or float - case JREAD_BOOL: // true or false - case JREAD_NULL: // null - bytelen= jReadTextLen( pJson ); - pResult->dataType= jTok; - pResult->bytelen= bytelen; - pResult->pValue= pJson; - pResult->elements= 1; - pJson += bytelen; - break; - default: - pResult->error= 8; // unexpected character (in pResult->dataType) - } - // We get here on a 'terminal value' - // - make sure the query string is empty also - pQuery= jReadFindTok( pQuery, &qTok ); - if( !pResult->error && (qTok != JREAD_EOL) ) - pResult->error= 7; // terminal value found before end of query - if( pResult->error ) - { - pResult->dataType= JREAD_ERROR; - pResult->elements= pResult->bytelen= 0; - pResult->pValue= pJson; // return pointer into JSON at error point - } - return pJson; -} - - -//-------------------------------------------------------------------- -// Optional helper functions -// - simple routines to extract values from JSON -// - does coercion of types where possible -// - always returns a value (e.g. 0 or "" on error) -// -// Note: by default, pass NULL for queryParams -// unless you are using '*' in the query for indexing -// - -// jRead_long -// - reads signed long value from JSON -// - returns number from NUMBER or STRING elements (if possible) -// returns 1 or 0 from BOOL elements -// otherwise returns 0 -// -long jRead_long( char *pJson, char *pQuery, int *queryParams ) -{ - struct jReadElement elem; - long result; - jReadParam( pJson, pQuery, &elem, queryParams ); - if( (elem.dataType == JREAD_ERROR) || (elem.dataType == JREAD_NULL)) - return 0; - if( elem.dataType == JREAD_BOOL ) - return *((char *)elem.pValue)=='t' ? 1 : 0; - - jRead_atol( (char *)elem.pValue, &result ); - return result; -} - -int jRead_int( char *pJson, char *pQuery, int *queryParams ) -{ - return (int)jRead_long( pJson, pQuery, queryParams ); -} - -// jRead_double -// - returns double from JSON -// - returns number from NUMBER or STRING elements -// otherwise returns 0.0 -// -double jRead_double( char *pJson, char *pQuery, int *queryParams ) -{ - struct jReadElement elem; - double result; - jReadParam( pJson, pQuery, &elem, queryParams ); - if( elem.dataType == JREAD_ERROR ) - return 0.0; - jRead_atof( (char *)elem.pValue, &result ); - return result; -} - -// jRead_string -// Copy string to pDest and '\0'-terminate it (upto destlen total bytes) -// returns: character length of string (excluding '\0' terminator) -// -// Note: any element can be returned as a string -// -int jRead_string( char *pJson, char *pQuery, char *pDest, int destlen, int *queryParams ) -{ - struct jReadElement elem; - int i; - - *pDest= '\0'; - jReadParam( pJson, pQuery, &elem, queryParams ); - if( elem.dataType == JREAD_ERROR ) - return 0; - - for( i=0; (i=0 ) && (error <= 14)) - return jReadErrorStrings[ error ]; - return "Unknown error"; -}; - -// end of jRead.c diff --git a/extlibs/jRead.h b/extlibs/jRead.h deleted file mode 100644 index 7ccaa05..0000000 --- a/extlibs/jRead.h +++ /dev/null @@ -1,128 +0,0 @@ -// jRead.h -// -// see jRead.c for more information -// - -// uncomment this if you really want to use double quotes in query strings instead of ' -//#define JREAD_DOUBLE_QUOTE_IN_QUERY - -// -// return dataTypes: -#define JREAD_ERROR 0 // general error, eof etc. -#define JREAD_OBJECT 1 // "{" -#define JREAD_ARRAY 2 // "[" -#define JREAD_STRING 3 // "string" -#define JREAD_NUMBER 4 // number (may be -ve) int or float -#define JREAD_BOOL 5 // true or false -#define JREAD_NULL 6 // null -#define JREAD_KEY 7 // object "key" -// internal values: -#define JREAD_COLON 8 // ":" -#define JREAD_EOL 9 // end of input string (ptr at '\0') -#define JREAD_COMMA 10 // "," -#define JREAD_EOBJECT 11 // "}" -#define JREAD_EARRAY 12 // "]" -#define JREAD_QPARAM 13 // "*" query string parameter - -//------------------------------------------------------ -// jReadElement -// - structure to return JSON elements -// - error=0 for valid returns -// -// *NOTES* -// the returned pValue pointer points into the passed JSON -// string returns are not '\0' terminated. -// bytelen specifies the length of the returned data pointed to by pValue -// -struct jReadElement{ - int dataType; // one of JREAD_... - int elements; // number of elements (e.g. elements in array or object) - int bytelen; // byte length of element (e.g. length of string, array text "[ ... ]" etc.) - void * pValue; // pointer to value string in JSON text - int error; // error value if dataType == JREAD_ERROR -}; - -//------------------------------------------------------ -// The JSON reader function -// -// - reads a '\0'-terminated JSON text string from pJson -// - traverses the JSON according to the pQuery string -// - returns the result value in pResult -// -// returns: pointer into pJson after the queried value -// -// e.g. -// With JSON like: "{ ..., "key":"value", ... }" -// -// jRead( pJson, "{'key'", &result ); -// returns with: -// result.dataType= JREAD_STRING, result.pValue->'value', result.bytelen=5 -// -char * jRead( char *pJson, char *pQuery, struct jReadElement *pResult ); - -// version of jRead which allows one or more queryParam integers to be substituted -// for array or object indexes marked by a '*' in the query -// -// e.g. jReadParam( pJson, "[*", &resultElement, &arrayIndex ); -// -// *!* CAUTION *!* -// You can supply an array of integers which are indexed for each '*' in pQuery -// however, horrid things will happen if you don't supply enough parameters -// -char * jReadParam( char *pJson, char *pQuery, struct jReadElement *pResult, int *queryParams ); - -// Array Stepping function -// - assumes pJsonArray is JSON source of an array "[ ... ]" -// - returns next element of the array in pResult -// - returns pointer to end of element, to be passed to next call of jReadArrayStep() -// - if end of array is encountered, pResult->error = 13 "End of array found" -// -// e.g. -// With JSON like: "{ ... "arrayInObject":[ elem1,elem2,... ], ... }" -// -// pJson= jRead( pJson, "{'arrayInObject'", &theArray ); -// if( theArray.dataType == JREAD_ARRAY ) -// { -// char *pArray= (char *)theArray.pValue; -// jReadElement arrayElement; -// int index; -// for( index=0; index < theArray.elements; index++ ) -// { -// pArray= jReadArrayStep( pArray, &arrayElement ); -// ... -// -// Note: this significantly speeds up traversing arrays. -// -char *jReadArrayStep( char *pJsonArray, struct jReadElement *pResult ); - - -#define EXPORT_OPTIONAL_FUNCTIONS -#ifdef EXPORT_OPTIONAL_FUNCTIONS - -//------------------------------------------------------ -// Optional Helper Functions -// -long jRead_long( char *pJson, char *pQuery, int *queryParams ); -int jRead_int( char *pJson, char *pQuery, int *queryParams ); -double jRead_double( char *pJson, char *pQuery, int *queryParams ); -int jRead_string( char *pJson, char *pQuery, char *pDest, int destlen, int *queryParams ); - -//------------------------------------------------------ -// Optional String output Functions -// -char *jReadTypeToString( int dataType ); // string describes dataType -char * jReadErrorToString( int error ); // string descibes error code - -//------------------------------------------------------ -// Other jRead utilities which may be useful... -// -char * jRead_atoi( char *p, unsigned int *result ); // string to unsigned int -char * jRead_atol( char *p, long *result ); // string to signed long -char * jRead_atof( char *p, double *result); // string to double (does not do exponents) -int jReadStrcmp( struct jReadElement *j1, struct jReadElement *j2 ); // compare STRING elements - -// copy element to '\0'-terminated buffer -char * jRead_strcpy( char *destBuffer, int destLength, struct jReadElement *pElement ); - -#endif -// end of jRead.h diff --git a/extlibs/jWrite.c b/extlibs/jWrite.c deleted file mode 100644 index e129c4b..0000000 --- a/extlibs/jWrite.c +++ /dev/null @@ -1,561 +0,0 @@ -// -// jWrite.c version 1v2 -// -// A *really* simple JSON writer in C -// -// see: jWrite.h for info -// -// TonyWilk, Mar 2015 -// -#define _CRT_SECURE_NO_WARNINGS // stop complaining about deprecated functions - -#include -#include -#include // memset() - -#include - -#include // definintion of uint32_t, int32_t -//typedef unsigned int uint32_t; -//typedef int int32_t; - - -// the jWrite functions take the above jWriteControl structure pointer -// to maintain state while writing a JSON string. -// -// You can opt to use a single global instance of a jWriteControl structure -// which simplifies the function parameters or to supply your own structure -// -#ifdef JW_GLOBAL_CONTROL_STRUCT -struct jWriteControl g_jWriteControl; // global control struct -#define JWC_DECL // function parameter decl is empty -#define JWC_DECL0 -#define JWC(x) g_jWriteControl.x // functions access global -#define JWC_PARAM // pointer to struct is empty -#define JWC_PARAM0 -#else -#define JWC_DECL struct jWriteControl *jwc, // function parameter is ptr to control struct -#define JWC_DECL0 struct jWriteControl *jwc // function parameter, no params -#define JWC(x) jwc->x // functions use pointer -#define JWC_PARAM jwc, // pointer to stuct -#define JWC_PARAM0 jwc // pointer to stuct, no params -#endif - -//------------------------------------------ -// Internal functions -// -void jwPutch( JWC_DECL char c ); -void jwPutstr( JWC_DECL char *str ); -void jwPutraw( JWC_DECL char *str ); -void modp_itoa10(int32_t value, char* str); -void modp_dtoa2(double value, char* str, int prec); -void jwPretty( JWC_DECL0 ); -enum jwNodeType jwPop( JWC_DECL0 ); -void jwPush( JWC_DECL enum jwNodeType nodeType ); - - -//------------------------------------------ -// jwOpen -// - open writing of JSON starting with rootType = JW_OBJECT or JW_ARRAY -// - initialise with user string buffer of length buflen -// - isPretty=JW_PRETTY adds \n and spaces to prettify output (else JW_COMPACT) -// -void jwOpen( JWC_DECL char *buffer, unsigned int buflen, - enum jwNodeType rootType, int isPretty ) -{ - memset( buffer, 0, buflen ); // zap the whole destination buffer - JWC(buffer)= buffer; - JWC(buflen)= buflen; - JWC(bufp)= buffer; - JWC(nodeStack)[0].nodeType= rootType; - JWC(nodeStack)[0].elementNo= 0; - JWC(stackpos)=0; - JWC(error)= JWRITE_OK; - JWC(callNo)= 1; - JWC(isPretty)= isPretty; - jwPutch( JWC_PARAM (rootType==JW_OBJECT) ? '{' : '[' ); -} - -//------------------------------------------ -// jwClose -// - closes the root JSON object started by jwOpen() -// - returns error code -// -int jwClose( JWC_DECL0 ) -{ - if( JWC(error) == JWRITE_OK ) - { - if( JWC(stackpos) == 0 ) - { - enum jwNodeType node= JWC(nodeStack)[0].nodeType; - if( JWC(isPretty) ) - jwPutch( JWC_PARAM '\n' ); - jwPutch( JWC_PARAM (node == JW_OBJECT) ? '}' : ']'); - }else{ - JWC(error)= JWRITE_NEST_ERROR; // nesting error, not all objects closed when jwClose() called - } - } - return JWC(error); -} - -//------------------------------------------ -// End the current array/object -// -int jwEnd( JWC_DECL0 ) -{ - if( JWC(error) == JWRITE_OK ) - { - enum jwNodeType node; - int lastElemNo= JWC(nodeStack)[JWC(stackpos)].elementNo; - node= jwPop( JWC_PARAM0 ); - if( lastElemNo > 0 ) - jwPretty( JWC_PARAM0 ); - jwPutch( JWC_PARAM (node == JW_OBJECT) ? '}' : ']'); - } - return JWC(error); -} - - -//------------------------------------------ -// jwErrorPos -// - Returns position of error: the nth call to a jWrite function -// -int jwErrorPos( JWC_DECL0 ) -{ - return JWC(callNo); -} - - -//------------------------------------------ -// Object insert functions -// -int _jwObj( JWC_DECL char *key ); - -// put raw string to object (i.e. contents of rawtext without quotes) -// -void jwObj_raw( JWC_DECL char *key, char *rawtext ) -{ - if(_jwObj( JWC_PARAM key ) == JWRITE_OK) - jwPutraw( JWC_PARAM rawtext); -} - -// put "quoted" string to object -// -void jwObj_string( JWC_DECL char *key, char *value ) -{ - if(_jwObj( JWC_PARAM key ) == JWRITE_OK) - jwPutstr( JWC_PARAM value ); -} - -void jwObj_int( JWC_DECL char *key, int value ) -{ - modp_itoa10( value, JWC(tmpbuf) ); - jwObj_raw( JWC_PARAM key, JWC(tmpbuf) ); -} - -void jwObj_double( JWC_DECL char *key, double value ) -{ - modp_dtoa2( value, JWC(tmpbuf), 6 ); - jwObj_raw( JWC_PARAM key, JWC(tmpbuf) ); -} - -void jwObj_bool( JWC_DECL char *key, int oneOrZero ) -{ - jwObj_raw( JWC_PARAM key, (oneOrZero) ? "true" : "false" ); -} - -void jwObj_null( JWC_DECL char *key ) -{ - jwObj_raw( JWC_PARAM key, "null" ); -} - -// put Object in Object -// -void jwObj_object( JWC_DECL char *key ) -{ - if(_jwObj( JWC_PARAM key ) == JWRITE_OK) - { - jwPutch( JWC_PARAM '{' ); - jwPush( JWC_PARAM JW_OBJECT ); - } -} - -// put Array in Object -// -void jwObj_array( JWC_DECL char *key ) -{ - if(_jwObj( JWC_PARAM key ) == JWRITE_OK) - { - jwPutch( JWC_PARAM '[' ); - jwPush( JWC_PARAM JW_ARRAY ); - } -} - -//------------------------------------------ -// Array insert functions -// -int _jwArr( JWC_DECL0 ); - -// put raw string to array (i.e. contents of rawtext without quotes) -// -void jwArr_raw( JWC_DECL char *rawtext ) -{ - if(_jwArr( JWC_PARAM0 ) == JWRITE_OK) - jwPutraw( JWC_PARAM rawtext); -} - -// put "quoted" string to array -// -void jwArr_string( JWC_DECL char *value ) -{ - if(_jwArr( JWC_PARAM0 ) == JWRITE_OK) - jwPutstr( JWC_PARAM value ); -} - -void jwArr_int( JWC_DECL int value ) -{ - modp_itoa10( value, JWC(tmpbuf) ); - jwArr_raw( JWC_PARAM JWC(tmpbuf) ); -} - -void jwArr_double( JWC_DECL double value ) -{ - modp_dtoa2( value, JWC(tmpbuf), 6 ); - jwArr_raw( JWC_PARAM JWC(tmpbuf) ); -} - -void jwArr_bool( JWC_DECL int oneOrZero ) -{ - jwArr_raw( JWC_PARAM (oneOrZero) ? "true" : "false" ); -} - -void jwArr_null( JWC_DECL0 ) -{ - jwArr_raw( JWC_PARAM "null" ); -} - -void jwArr_object( JWC_DECL0 ) -{ - if(_jwArr( JWC_PARAM0 ) == JWRITE_OK) - { - jwPutch( JWC_PARAM '{' ); - jwPush( JWC_PARAM JW_OBJECT ); - } -} - -void jwArr_array( JWC_DECL0 ) -{ - if(_jwArr( JWC_PARAM0 ) == JWRITE_OK) - { - jwPutch( JWC_PARAM '[' ); - jwPush( JWC_PARAM JW_ARRAY ); - } -} - - -//------------------------------------------ -// jwErrorToString -// - returns string describing error code -// -char *jwErrorToString( int err ) -{ - switch( err ) - { - case JWRITE_OK: return "OK"; - case JWRITE_BUF_FULL: return "output buffer full"; - case JWRITE_NOT_ARRAY: return "tried to write Array value into Object"; - case JWRITE_NOT_OBJECT: return "tried to write Object key/value into Array"; - case JWRITE_STACK_FULL: return "array/object nesting > JWRITE_STACK_DEPTH"; - case JWRITE_STACK_EMPTY:return "stack underflow error (too many 'end's)"; - case JWRITE_NEST_ERROR: return "nesting error, not all objects closed when jwClose() called"; - } - return "Unknown error"; -} - -//============================================================================ -// Internal functions -// -void jwPretty( JWC_DECL0 ) -{ - int i; - if( JWC(isPretty) ) - { - jwPutch( JWC_PARAM '\n' ); - for( i=0; i= JWRITE_STACK_DEPTH ) - JWC(error)= JWRITE_STACK_FULL; // array/object nesting > JWRITE_STACK_DEPTH - else - { - JWC(nodeStack[++JWC(stackpos)]).nodeType= nodeType; - JWC(nodeStack[JWC(stackpos)]).elementNo= 0; - } -} - -enum jwNodeType jwPop( JWC_DECL0 ) -{ - enum jwNodeType retval= JWC(nodeStack[JWC(stackpos)]).nodeType; - if( JWC(stackpos) == 0 ) - JWC(error)= JWRITE_STACK_EMPTY; // stack underflow error (too many 'end's) - else - JWC(stackpos)--; - return retval; -} - -void jwPutch( JWC_DECL char c ) -{ - if( (unsigned int)(JWC(bufp) - JWC(buffer)) >= JWC(buflen) ) - { - JWC(error)= JWRITE_BUF_FULL; - }else{ - *JWC(bufp)++ = c; - } -} - -// put string enclosed in quotes -// -void jwPutstr( JWC_DECL char *str ) -{ - jwPutch( JWC_PARAM '\"' ); - while( *str != '\0' ) - jwPutch( JWC_PARAM *str++ ); - jwPutch( JWC_PARAM '\"' ); -} - -// put raw string -// -void jwPutraw( JWC_DECL char *str ) -{ - while( *str != '\0' ) - jwPutch( JWC_PARAM *str++ ); -} - - -// *common Object function* -// - checks error -// - checks current node is OBJECT -// - adds comma if reqd -// - adds "key" : -// -int _jwObj( JWC_DECL char *key ) -{ - if(JWC(error) == JWRITE_OK) - { - JWC(callNo)++; - if( JWC(nodeStack)[JWC(stackpos)].nodeType != JW_OBJECT ) - JWC(error)= JWRITE_NOT_OBJECT; // tried to write Object key/value into Array - else if( JWC(nodeStack)[JWC(stackpos)].elementNo++ > 0 ) - jwPutch( JWC_PARAM ',' ); - jwPretty( JWC_PARAM0 ); - jwPutstr( JWC_PARAM key ); - jwPutch( JWC_PARAM ':' ); - if( JWC(isPretty) ) - jwPutch( JWC_PARAM ' ' ); - } - return JWC(error); -} - -// *common Array function* -// - checks error -// - checks current node is ARRAY -// - adds comma if reqd -// -int _jwArr( JWC_DECL0 ) -{ - if(JWC(error) == JWRITE_OK) - { - JWC(callNo)++; - if( JWC(nodeStack)[JWC(stackpos)].nodeType != JW_ARRAY ) - JWC(error)= JWRITE_NOT_ARRAY; // tried to write array value into Object - else if( JWC(nodeStack)[JWC(stackpos)].elementNo++ > 0 ) - jwPutch( JWC_PARAM ',' ); - jwPretty( JWC_PARAM0 ); - } - return JWC(error); -} - -//================================================================= -// -// modp value-to-string functions -// - modified for C89 -// -// We use these functions as they are a lot faster than sprintf() -// -// Origin of these routines: -/* - *
- * Copyright © 2007, Nick Galbreath -- nickg [at] modp [dot] com
- * All rights reserved.
- * http://code.google.com/p/stringencoders/
- * Released under the bsd license.
- * 
- */ - -static void strreverse(char* begin, char* end) -{ - char aux; - while (end > begin) - aux = *end, *end-- = *begin, *begin++ = aux; -} - -/** \brief convert an signed integer to char buffer - * - * \param[in] value - * \param[out] buf the output buffer. Should be 16 chars or more. - */ -void modp_itoa10(int32_t value, char* str) -{ - char* wstr=str; - // Take care of sign - unsigned int uvalue = (value < 0) ? -value : value; - // Conversion. Number is reversed. - do *wstr++ = (char)(48 + (uvalue % 10)); while(uvalue /= 10); - if (value < 0) *wstr++ = '-'; - *wstr='\0'; - - // Reverse string - strreverse(str,wstr-1); -} - -/** - * Powers of 10 - * 10^0 to 10^9 - */ -static const double pow10[] = {1, 10, 100, 1000, 10000, 100000, 1000000, - 10000000, 100000000, 1000000000}; - -/** \brief convert a floating point number to char buffer with a - * variable-precision format, and no trailing zeros - * - * This is similar to "%.[0-9]f" in the printf style, except it will - * NOT include trailing zeros after the decimal point. This type - * of format oddly does not exists with printf. - * - * If the input value is greater than 1<<31, then the output format - * will be switched exponential format. - * - * \param[in] value - * \param[out] buf The allocated output buffer. Should be 32 chars or more. - * \param[in] precision Number of digits to the right of the decimal point. - * Can only be 0-9. - */ -void modp_dtoa2(double value, char* str, int prec) -{ - /* if input is larger than thres_max, revert to exponential */ - const double thres_max = (double)(0x7FFFFFFF); - int count; - double diff = 0.0; - char* wstr = str; - int neg= 0; - int whole; - double tmp; - uint32_t frac; - - /* Hacky test for NaN - * under -fast-math this won't work, but then you also won't - * have correct nan values anyways. The alternative is - * to link with libmath (bad) or hack IEEE double bits (bad) - */ - if (! (value == value)) { - str[0] = 'n'; str[1] = 'a'; str[2] = 'n'; str[3] = '\0'; - return; - } - - if (prec < 0) { - prec = 0; - } else if (prec > 9) { - /* precision of >= 10 can lead to overflow errors */ - prec = 9; - } - - /* we'll work in positive values and deal with the - negative sign issue later */ - if (value < 0) { - neg = 1; - value = -value; - } - - - whole = (int) value; - tmp = (value - whole) * pow10[prec]; - frac = (uint32_t)(tmp); - diff = tmp - frac; - - if (diff > 0.5) { - ++frac; - /* handle rollover, e.g. case 0.99 with prec 1 is 1.0 */ - if (frac >= pow10[prec]) { - frac = 0; - ++whole; - } - } else if (diff == 0.5 && ((frac == 0) || (frac & 1))) { - /* if halfway, round up if odd, OR - if last digit is 0. That last part is strange */ - ++frac; - } - - /* for very large numbers switch back to native sprintf for exponentials. - anyone want to write code to replace this? */ - /* - normal printf behavior is to print EVERY whole number digit - which can be 100s of characters overflowing your buffers == bad - */ - if (value > thres_max) { - sprintf(str, "%e", neg ? -value : value); - return; - } - - if (prec == 0) { - diff = value - whole; - if (diff > 0.5) { - /* greater than 0.5, round up, e.g. 1.6 -> 2 */ - ++whole; - } else if (diff == 0.5 && (whole & 1)) { - /* exactly 0.5 and ODD, then round up */ - /* 1.5 -> 2, but 2.5 -> 2 */ - ++whole; - } - - //vvvvvvvvvvvvvvvvvvv Diff from modp_dto2 - } else if (frac) { - count = prec; - // now do fractional part, as an unsigned number - // we know it is not 0 but we can have leading zeros, these - // should be removed - while (!(frac % 10)) { - --count; - frac /= 10; - } - //^^^^^^^^^^^^^^^^^^^ Diff from modp_dto2 - - // now do fractional part, as an unsigned number - do { - --count; - *wstr++ = (char)(48 + (frac % 10)); - } while (frac /= 10); - // add extra 0s - while (count-- > 0) *wstr++ = '0'; - // add decimal - *wstr++ = '.'; - } - - // do whole part - // Take care of sign - // Conversion. Number is reversed. - do *wstr++ = (char)(48 + (whole % 10)); while (whole /= 10); - if (neg) { - *wstr++ = '-'; - } - *wstr='\0'; - strreverse(str, wstr-1); -} -//================================================================= - -/* end of jWrite.c */ diff --git a/extlibs/jWrite.h b/extlibs/jWrite.h deleted file mode 100644 index 308139c..0000000 --- a/extlibs/jWrite.h +++ /dev/null @@ -1,217 +0,0 @@ -// -// jWrite.h -// -// A *really* simple JSON writer in C (C89) -// - a collection of functions to generate JSON semi-automatically -// -// The idea is to simplify writing native C values into a JSON string and -// to provide some error trapping to ensure that the result is valid JSON. -// -// Example: -// jwOpen( buffer, buflen, JW_OBJECT, JW_PRETTY ); // open root node as object -// jwObj_string( "key", "value" ); -// jwObj_int( "int", 1 ); -// jwObj_array( "anArray"); -// jwArr_int( 0 ); -// jwArr_int( 1 ); -// jwArr_int( 2 ); -// jwEnd(); -// err= jwClose(); // close root object -// -// results in: -// -// { -// "key": "value", -// "int": 1, -// "anArray": [ -// 0, -// 1, -// 2 -// ] -// } -// -// Note that jWrite handles string quoting and getting commas in the right place. -// If the sequence of calls is incorrect -// e.g. -// jwOpen( buffer, buflen, JW_OBJECT, 1 ); -// jwObj_string( "key", "value" ); -// jwArr_int( 0 ); -// ... -// -// then the error code returned from jwClose() would indicate that you attempted to -// put an array element into an object (instead of a key:value pair) -// To locate the error, the supplied buffer has the JSON created upto the error point -// and a call to jwErrorPos() would return the function call at which the error occurred -// - in this case 3, the 3rd function call "jwArr_int(0)" is not correct at this point. -// -// The root JSON type can be JW_OBJECT or JW_ARRAY. -// -// For more information on each function, see the prototypes below. -// -// -// GLOBAL vs. Application-Supplied Control Structure -// ------------------------------------------------- -// jWrite requires a jWriteControl structure to save the internal state. -// For many applications it is much simpler for this to be a global variable as -// used by the above examples. -// -// To use multiple instances of jWrite, an application has to supply unique instances -// of jWriteControl structures. -// -// This feature is enabled by commenting out the definition of JW_GLOBAL_CONTROL_STRUCT -// -// All the jWrite functions then take an additional parameter: a ptr to the structure -// e.g. -// struct jWriteControl jwc; -// -// jwOpen( &jwc, buffer, buflen, JW_OBJECT, 1 ); -// jwObj_string( &jwc, "key", "value" ); -// jwObj_int( &jwc, "int", 1 ); -// jwObj_array( &jwc, "anArray"); -// jwArr_int( &jwc, 0 ); -// jwArr_int( &jwc, 1 ); -// jwArr_int( &jwc, 2 ); -// jwEnd( &jwc ); -// err= jwClose( &jwc ); -// -// - which is more flexible, but a pain to type in ! -// -// TonyWilk, Mar 2015 -// -// - -#ifndef JWRITE_H_ -#define JWRITE_H_ - - -#define JW_GLOBAL_CONTROL_STRUCT // <--- comment this out to use applic-supplied jWriteControl -#define JWRITE_STACK_DEPTH 32 // max nesting depth of objects/arrays - -#define JW_COMPACT 0 // output string control for jwOpen() -#define JW_PRETTY 1 // pretty adds \n and indentation - -enum jwNodeType{ - JW_OBJECT= 1, - JW_ARRAY -}; - -struct jwNodeStack{ - enum jwNodeType nodeType; - int elementNo; -}; - -struct jWriteControl{ - char *buffer; // pointer to application's buffer - unsigned int buflen; // length of buffer - char *bufp; // current write position in buffer - char tmpbuf[32]; // local buffer for int/double convertions - int error; // error code - int callNo; // API call on which error occurred - struct jwNodeStack nodeStack[JWRITE_STACK_DEPTH]; // stack of array/object nodes - int stackpos; - int isPretty; // 1= pretty output (inserts \n and spaces) -}; - -// Error Codes -// ----------- -#define JWRITE_OK 0 -#define JWRITE_BUF_FULL 1 // output buffer full -#define JWRITE_NOT_ARRAY 2 // tried to write Array value into Object -#define JWRITE_NOT_OBJECT 3 // tried to write Object key/value into Array -#define JWRITE_STACK_FULL 4 // array/object nesting > JWRITE_STACK_DEPTH -#define JWRITE_STACK_EMPTY 5 // stack underflow error (too many 'end's) -#define JWRITE_NEST_ERROR 6 // nesting error, not all objects closed when jwClose() called - - -// API functions -// ------------- - -// Returns '\0'-termianted string describing the error (as returned by jwClose()) -// -char *jwErrorToString( int err ); - - -#ifdef JW_GLOBAL_CONTROL_STRUCT /* USING GLOBAL g_jWriteControl */ - -// jwOpen -// - initialises jWrite with the application supplied 'buffer' of length 'buflen' -// in operation, the buffer will always contain a valid '\0'-terminated string -// - jWrite will not overrun the buffer (it returns an "output buffer full" error) -// - rootType is the base JSON type: JW_OBJECT or JW_ARRAY -// - isPretty controls 'prettifying' the output: JW_PRETTY or JW_COMPACT -void jwOpen( char *buffer, unsigned int buflen, enum jwNodeType rootType, int isPretty ); - -// jwClose -// - closes the element opened by jwOpen() -// - returns error code (0 = JWRITE_OK) -// - after an error, all following jWrite calls are skipped internally -// so the error code is for the first error detected -int jwClose( ); - -// jwErrorPos -// - if jwClose returned an error, this function returns the number of the jWrite function call -// which caused that error. -int jwErrorPos( ); - -// Object insertion functions -// - used to insert "key":"value" pairs into an object -// -void jwObj_string( char *key, char *value ); -void jwObj_int( char *key, int value ); -void jwObj_double( char *key, double value ); -void jwObj_bool( char *key, int oneOrZero ); -void jwObj_null( char *key ); -void jwObj_object( char *key ); -void jwObj_array( char *key ); - -// Array insertion functions -// - used to insert "value" elements into an array -// -void jwArr_string( char *value ); -void jwArr_int( int value ); -void jwArr_double( double value ); -void jwArr_bool( int oneOrZero ); -void jwArr_null( ); -void jwArr_object( ); -void jwArr_array( ); - -// jwEnd -// - defines the end of an Object or Array definition -int jwEnd( ); - - -// these 'raw' routines write the JSON value as the contents of rawtext -// i.e. enclosing quotes are not added -// - use if your app. supplies its own value->string functions -// -void jwObj_raw( char *key, char *rawtext ); -void jwArr_raw( char *rawtext ); - -#else /* JW_GLOBAL_CONTROL_STRUCT not defined */ -// Same API functions with app-supplied control struct option -// -void jwOpen( struct jWriteControl *jwc, char *buffer, unsigned int buflen, enum jwNodeType rootType, int isPretty ); -int jwClose( struct jWriteControl *jwc ); -int jwErrorPos( struct jWriteControl *jwc ); -void jwObj_string( struct jWriteControl *jwc, char *key, char *value ); -void jwObj_int( struct jWriteControl *jwc, char *key, int value ); -void jwObj_double( struct jWriteControl *jwc, char *key, double value ); -void jwObj_bool( struct jWriteControl *jwc, char *key, int oneOrZero ); -void jwObj_null( struct jWriteControl *jwc, char *key ); -void jwObj_object( struct jWriteControl *jwc, char *key ); -void jwObj_array( struct jWriteControl *jwc, char *key ); -void jwArr_string( struct jWriteControl *jwc, char *value ); -void jwArr_int( struct jWriteControl *jwc, int value ); -void jwArr_double( struct jWriteControl *jwc, double value ); -void jwArr_bool( struct jWriteControl *jwc, int oneOrZero ); -void jwArr_null( struct jWriteControl *jwc ); -void jwArr_object( struct jWriteControl *jwc ); -void jwArr_array( struct jWriteControl *jwc ); -int jwEnd( struct jWriteControl *jwc ); -void jwObj_raw( struct jWriteControl *jwc, char *key, char *rawtext ); -void jwArr_raw( struct jWriteControl *jwc, char *rawtext ); - -#endif /* JW_GLOBAL_CONTROL_STRUCT */ - -#endif /*JWRITE_H_ */ -/* end of jWrite.h */