json lib

Dependents:   grove_stream_jpa_sd2 grove_stream_jpa_sd2 grove_stream_jpa_sd2-2 grove_stream_jpa_sd2-3 ... more

Committer:
38domo
Date:
Mon Aug 31 17:50:53 2020 +0000
Revision:
8:43e1e35bb7ec
Parent:
7:8aa4d0e98eb0
jpa json

Who changed what in which revision?

UserRevisionLine numberNew contents of line
faheem_chaudhary 5:dd98cf00ed9b 1 /* Json.h */
faheem_chaudhary 5:dd98cf00ed9b 2 /* Original Author: Faheem Inayat
faheem_chaudhary 5:dd98cf00ed9b 3 * Created by "Night Crue" Team @ TechShop San Jose, CA
faheem_chaudhary 5:dd98cf00ed9b 4 *
faheem_chaudhary 5:dd98cf00ed9b 5 * MIT License
faheem_chaudhary 5:dd98cf00ed9b 6 *
faheem_chaudhary 5:dd98cf00ed9b 7 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
faheem_chaudhary 5:dd98cf00ed9b 8 * and associated documentation files (the "Software"), to deal in the Software without restriction,
faheem_chaudhary 5:dd98cf00ed9b 9 * including without limitation the rights to use, copy, modify, merge, publish, distribute,
faheem_chaudhary 5:dd98cf00ed9b 10 * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
faheem_chaudhary 5:dd98cf00ed9b 11 * furnished to do so, subject to the following conditions:
faheem_chaudhary 5:dd98cf00ed9b 12 *
faheem_chaudhary 5:dd98cf00ed9b 13 * The above copyright notice and this permission notice shall be included in all copies or
faheem_chaudhary 5:dd98cf00ed9b 14 * substantial portions of the Software.
faheem_chaudhary 5:dd98cf00ed9b 15 *
faheem_chaudhary 5:dd98cf00ed9b 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
faheem_chaudhary 5:dd98cf00ed9b 17 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
faheem_chaudhary 5:dd98cf00ed9b 18 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
faheem_chaudhary 5:dd98cf00ed9b 19 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
faheem_chaudhary 5:dd98cf00ed9b 20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
faheem_chaudhary 5:dd98cf00ed9b 21 */
faheem_chaudhary 5:dd98cf00ed9b 22
mercurywaters 3:fab591fca1e7 23 #ifndef __JSON_LIB_CLASS_H_
mercurywaters 3:fab591fca1e7 24 #define __JSON_LIB_CLASS_H_
mercurywaters 3:fab591fca1e7 25
mercurywaters 3:fab591fca1e7 26 #include "jsmn.h"
mercurywaters 3:fab591fca1e7 27 #include <stdlib.h>
mercurywaters 3:fab591fca1e7 28 #include <string.h>
mercurywaters 3:fab591fca1e7 29
mercurywaters 3:fab591fca1e7 30 /**
faheem_chaudhary 5:dd98cf00ed9b 31 * C++ JSON wrapper over JSMN lib (https://github.com/zserge/jsmn).
faheem_chaudhary 5:dd98cf00ed9b 32 *
faheem_chaudhary 5:dd98cf00ed9b 33 * This C++ Class is a set of common tools/procedures as a C++ wrapper over JSMN
faheem_chaudhary 5:dd98cf00ed9b 34 * JSON parser library. It is intended to provide the boiler-plate code, with
faheem_chaudhary 5:dd98cf00ed9b 35 * intentions to reduce code clutter, in more of C++ fashion.
faheem_chaudhary 5:dd98cf00ed9b 36 *
faheem_chaudhary 5:dd98cf00ed9b 37 * In contrast to original library, Json is intended to work strictly with valid
faheem_chaudhary 5:dd98cf00ed9b 38 * JSON structures. Non-standard JSON structures should result in an error.
faheem_chaudhary 5:dd98cf00ed9b 39 *
faheem_chaudhary 5:dd98cf00ed9b 40 * This class works explicitly on the indices returned by underlying JSMN
faheem_chaudhary 5:dd98cf00ed9b 41 * library. In the scope of this class, its function parameters, return types,
faheem_chaudhary 5:dd98cf00ed9b 42 * and documentation, the term 'index' will always mean the index of JSMN
faheem_chaudhary 5:dd98cf00ed9b 43 * tokens, parsed by the Json constructor, unless and until explicitly mentioned
faheem_chaudhary 5:dd98cf00ed9b 44 * otherwise.
mercurywaters 3:fab591fca1e7 45 */
faheem_chaudhary 7:8aa4d0e98eb0 46
faheem_chaudhary 7:8aa4d0e98eb0 47 /*
faheem_chaudhary 7:8aa4d0e98eb0 48 Example:
faheem_chaudhary 7:8aa4d0e98eb0 49
faheem_chaudhary 7:8aa4d0e98eb0 50 Let's say we have to parse the samle JSON:
faheem_chaudhary 7:8aa4d0e98eb0 51
faheem_chaudhary 7:8aa4d0e98eb0 52 {
faheem_chaudhary 7:8aa4d0e98eb0 53 "team": "Night Crue",
faheem_chaudhary 7:8aa4d0e98eb0 54 "company": "TechShop",
faheem_chaudhary 7:8aa4d0e98eb0 55 "city": "San Jose",
faheem_chaudhary 7:8aa4d0e98eb0 56 "state": "California",
faheem_chaudhary 7:8aa4d0e98eb0 57 "country": "USA",
faheem_chaudhary 7:8aa4d0e98eb0 58 "zip": 95113,
faheem_chaudhary 7:8aa4d0e98eb0 59 "active": true,
faheem_chaudhary 7:8aa4d0e98eb0 60 "members":
faheem_chaudhary 7:8aa4d0e98eb0 61 [
faheem_chaudhary 7:8aa4d0e98eb0 62 {
faheem_chaudhary 7:8aa4d0e98eb0 63 "firstName": "John",
faheem_chaudhary 7:8aa4d0e98eb0 64 "lastName": "Smith",
faheem_chaudhary 7:8aa4d0e98eb0 65 "active": false,
faheem_chaudhary 7:8aa4d0e98eb0 66 "hours": 18.5,
faheem_chaudhary 7:8aa4d0e98eb0 67 "age": 21
faheem_chaudhary 7:8aa4d0e98eb0 68 },
faheem_chaudhary 7:8aa4d0e98eb0 69 {
faheem_chaudhary 7:8aa4d0e98eb0 70 "firstName": "Foo",
faheem_chaudhary 7:8aa4d0e98eb0 71 "lastName": "Bar",
faheem_chaudhary 7:8aa4d0e98eb0 72 "active": true,
faheem_chaudhary 7:8aa4d0e98eb0 73 "hours": 25,
faheem_chaudhary 7:8aa4d0e98eb0 74 "age": 21
faheem_chaudhary 7:8aa4d0e98eb0 75 },
faheem_chaudhary 7:8aa4d0e98eb0 76 {
faheem_chaudhary 7:8aa4d0e98eb0 77 "firstName": "Peter",
faheem_chaudhary 7:8aa4d0e98eb0 78 "lastName": "Jones",
faheem_chaudhary 7:8aa4d0e98eb0 79 "active": false
faheem_chaudhary 7:8aa4d0e98eb0 80 }
faheem_chaudhary 7:8aa4d0e98eb0 81 ]
faheem_chaudhary 7:8aa4d0e98eb0 82 }
faheem_chaudhary 7:8aa4d0e98eb0 83
faheem_chaudhary 7:8aa4d0e98eb0 84 which without the "white spaces" will look like: {"team":"Night Crue","company":"TechShop","city":"San Jose","state":"California","country":"USA","zip":95113,"active":true,"members":[{"firstName":"John","lastName":"Smith","active":false,"hours":18.5,"age":21},{"firstName":"Foo","lastName":"Bar","active":true,"hours":25,"age":21},{"firstName":"Peter","lastName":"Jones","active":false}]}
faheem_chaudhary 7:8aa4d0e98eb0 85
faheem_chaudhary 7:8aa4d0e98eb0 86 Anyways, this class doesn't care about the formatting of JSON, however, it
faheem_chaudhary 7:8aa4d0e98eb0 87 DOES care about the validity of JSON. So here's a sample code to parse and
faheem_chaudhary 7:8aa4d0e98eb0 88 extract values from this JSON structure.
faheem_chaudhary 7:8aa4d0e98eb0 89
faheem_chaudhary 7:8aa4d0e98eb0 90 @code
faheem_chaudhary 7:8aa4d0e98eb0 91
faheem_chaudhary 7:8aa4d0e98eb0 92 void main ()
faheem_chaudhary 7:8aa4d0e98eb0 93 {
faheem_chaudhary 7:8aa4d0e98eb0 94 // Note that the JSON object is 'escaped'. One doesn't get escaped JSON
faheem_chaudhary 7:8aa4d0e98eb0 95 // directly from the webservice, if the response type is APPLICATION/JSON
faheem_chaudhary 7:8aa4d0e98eb0 96 // Just a little thing to keep in mind.
faheem_chaudhary 7:8aa4d0e98eb0 97 const char * jsonSource = "{\"team\":\"Night Crue\",\"company\":\"TechShop\",\"city\":\"San Jose\",\"state\":\"California\",\"country\":\"USA\",\"zip\":95113,\"active\":true,\"members\":[{\"firstName\":\"John\",\"lastName\":\"Smith\",\"active\":false,\"hours\":18.5,\"age\":21},{\"firstName\":\"Foo\",\"lastName\":\"Bar\",\"active\":true,\"hours\":25,\"age\":21},{\"firstName\":\"Peter\",\"lastName\":\"Jones\",\"active\":false}]}";
faheem_chaudhary 7:8aa4d0e98eb0 98
faheem_chaudhary 7:8aa4d0e98eb0 99 Json json ( jsonSource, strlen ( jsonSource ) );
faheem_chaudhary 7:8aa4d0e98eb0 100
faheem_chaudhary 7:8aa4d0e98eb0 101 if ( !json.isValidJson () )
faheem_chaudhary 7:8aa4d0e98eb0 102 {
faheem_chaudhary 7:8aa4d0e98eb0 103 logError ( "Invalid JSON: %s", jsonSource );
faheem_chaudhary 7:8aa4d0e98eb0 104 return;
faheem_chaudhary 7:8aa4d0e98eb0 105 }
faheem_chaudhary 7:8aa4d0e98eb0 106
faheem_chaudhary 7:8aa4d0e98eb0 107 if ( json.type (0) != JSMN_OBJECT )
faheem_chaudhary 7:8aa4d0e98eb0 108 {
faheem_chaudhary 7:8aa4d0e98eb0 109 logError ( "Invalid JSON. ROOT element is not Object: %s", jsonSource );
faheem_chaudhary 7:8aa4d0e98eb0 110 return;
faheem_chaudhary 7:8aa4d0e98eb0 111 }
faheem_chaudhary 7:8aa4d0e98eb0 112
faheem_chaudhary 7:8aa4d0e98eb0 113 // Let's get the value of key "city" in ROOT object, and copy into
faheem_chaudhary 7:8aa4d0e98eb0 114 // cityValue
faheem_chaudhary 7:8aa4d0e98eb0 115 char cityValue [ 32 ];
faheem_chaudhary 7:8aa4d0e98eb0 116
faheem_chaudhary 7:8aa4d0e98eb0 117 logInfo ( "Finding \"city\" Key ... " );
faheem_chaudhary 7:8aa4d0e98eb0 118 // ROOT object should have '0' tokenIndex, and -1 parentIndex
faheem_chaudhary 7:8aa4d0e98eb0 119 int cityKeyIndex = json.findKeyIndexIn ( "city", 0 );
faheem_chaudhary 7:8aa4d0e98eb0 120 if ( cityKeyIndex == -1 )
faheem_chaudhary 7:8aa4d0e98eb0 121 {
faheem_chaudhary 7:8aa4d0e98eb0 122 // Error handling part ...
faheem_chaudhary 7:8aa4d0e98eb0 123 logError ( "\"city\" does not exist ... do something!!" );
faheem_chaudhary 7:8aa4d0e98eb0 124 }
faheem_chaudhary 7:8aa4d0e98eb0 125 else
faheem_chaudhary 7:8aa4d0e98eb0 126 {
faheem_chaudhary 7:8aa4d0e98eb0 127 // Find the first child index of key-node "city"
faheem_chaudhary 7:8aa4d0e98eb0 128 int cityValueIndex = json.findChildIndexOf ( cityKeyIndex, -1 );
faheem_chaudhary 7:8aa4d0e98eb0 129 if ( cityValueIndex > 0 )
faheem_chaudhary 7:8aa4d0e98eb0 130 {
faheem_chaudhary 7:8aa4d0e98eb0 131 const char * valueStart = json.tokenAddress ( cityValueIndex );
faheem_chaudhary 7:8aa4d0e98eb0 132 int valueLength = json.tokenLength ( cityValueIndex );
faheem_chaudhary 7:8aa4d0e98eb0 133 strncpy ( cityValue, valueStart, valueLength );
faheem_chaudhary 7:8aa4d0e98eb0 134 cityValue [ valueLength ] = 0; // NULL-terminate the string
faheem_chaudhary 7:8aa4d0e98eb0 135
faheem_chaudhary 7:8aa4d0e98eb0 136 //let's print the value. It should be "San Jose"
faheem_chaudhary 7:8aa4d0e98eb0 137 logInfo ( "city: %s", cityValue );
faheem_chaudhary 7:8aa4d0e98eb0 138 }
faheem_chaudhary 7:8aa4d0e98eb0 139 }
faheem_chaudhary 7:8aa4d0e98eb0 140
faheem_chaudhary 7:8aa4d0e98eb0 141 // More on this example to come, later.
faheem_chaudhary 7:8aa4d0e98eb0 142 }
faheem_chaudhary 7:8aa4d0e98eb0 143
faheem_chaudhary 7:8aa4d0e98eb0 144 @endcode
faheem_chaudhary 7:8aa4d0e98eb0 145 */
mercurywaters 3:fab591fca1e7 146
mercurywaters 3:fab591fca1e7 147 class Json
mercurywaters 3:fab591fca1e7 148 {
mercurywaters 3:fab591fca1e7 149 private:
faheem_chaudhary 5:dd98cf00ed9b 150 const unsigned int maxTokenCount;
mercurywaters 3:fab591fca1e7 151 const char * source;
mercurywaters 3:fab591fca1e7 152 const size_t sourceLength;
mercurywaters 3:fab591fca1e7 153 jsmntok_t * tokens;
mercurywaters 3:fab591fca1e7 154 int tokenCount;
faheem_chaudhary 5:dd98cf00ed9b 155
faheem_chaudhary 5:dd98cf00ed9b 156 // Copy COntructor is intentionally kept private to enforce the caller
faheem_chaudhary 5:dd98cf00ed9b 157 // to use pointers/reference, and never pass-by-value
faheem_chaudhary 5:dd98cf00ed9b 158 Json ( const Json & );
mercurywaters 3:fab591fca1e7 159
mercurywaters 3:fab591fca1e7 160 public:
faheem_chaudhary 5:dd98cf00ed9b 161 /** The only constructor allowed.
faheem_chaudhary 5:dd98cf00ed9b 162 As JSON object will create/allocate memory for its working, in favor of
faheem_chaudhary 5:dd98cf00ed9b 163 small memory footprints, it is not allowed to be passed-by-value. So
faheem_chaudhary 5:dd98cf00ed9b 164 there is no copy- or default-constructor
faheem_chaudhary 5:dd98cf00ed9b 165
faheem_chaudhary 6:c1d2153da4ed 166 @param jsonString char string containing JSON data
faheem_chaudhary 6:c1d2153da4ed 167 @param length length of the jsonString
faheem_chaudhary 6:c1d2153da4ed 168 @param maxTokens optional maximum count of Tokens. Default is 32.
mercurywaters 3:fab591fca1e7 169 */
faheem_chaudhary 5:dd98cf00ed9b 170 Json ( const char * jsonString, size_t length, unsigned int maxTokens = 32 );
faheem_chaudhary 5:dd98cf00ed9b 171
faheem_chaudhary 5:dd98cf00ed9b 172
faheem_chaudhary 5:dd98cf00ed9b 173 /** Although there is no virtual function to this class, destructor is
faheem_chaudhary 5:dd98cf00ed9b 174 still made virtual, for just-in-case use. Destructor will delete the
faheem_chaudhary 5:dd98cf00ed9b 175 'tokens' array, created in constructor.
faheem_chaudhary 5:dd98cf00ed9b 176 */
mercurywaters 3:fab591fca1e7 177 virtual ~Json ();
mercurywaters 3:fab591fca1e7 178
faheem_chaudhary 5:dd98cf00ed9b 179
faheem_chaudhary 5:dd98cf00ed9b 180 /** findKeyIndex will find and return the token index representing the
faheem_chaudhary 5:dd98cf00ed9b 181 'Key' in underlying JSON object. It is a strictly a linear key search
faheem_chaudhary 5:dd98cf00ed9b 182 and will return the first occurrence, without the JSON node structure
faheem_chaudhary 5:dd98cf00ed9b 183 semantics. For search in a specific node, refer to #findKeyIndex
faheem_chaudhary 5:dd98cf00ed9b 184
faheem_chaudhary 5:dd98cf00ed9b 185 @param key a char string to find as a 'Key' in JSON structure.
faheem_chaudhary 5:dd98cf00ed9b 186 @param startingAt the starting token-index for 'key' search. The
faheem_chaudhary 5:dd98cf00ed9b 187 search will NOT include this index, but instead will use the
faheem_chaudhary 5:dd98cf00ed9b 188 next one as the starting point. In case, a negative value is
faheem_chaudhary 5:dd98cf00ed9b 189 passed, search will start from '0'. It's caller's
faheem_chaudhary 5:dd98cf00ed9b 190 responsibility to make sure what values they're passing.
faheem_chaudhary 5:dd98cf00ed9b 191 Default value is set to '0', as the zero-th token index in any
faheem_chaudhary 5:dd98cf00ed9b 192 valid JSON object should always be starting object brace '{'.
faheem_chaudhary 5:dd98cf00ed9b 193 So default behavior is to always find the very first occurrence
faheem_chaudhary 5:dd98cf00ed9b 194 of key as represented by 'key' parameter.
faheem_chaudhary 5:dd98cf00ed9b 195
faheem_chaudhary 5:dd98cf00ed9b 196 @return a non-zero positive integer, if a key is found in the source
faheem_chaudhary 5:dd98cf00ed9b 197 JSON. If no key is found, -1 will be returned. There should be
faheem_chaudhary 5:dd98cf00ed9b 198 no '0' value returned in any valid case.
faheem_chaudhary 5:dd98cf00ed9b 199 */
faheem_chaudhary 5:dd98cf00ed9b 200 int findKeyIndex ( const char * key, const int &startingAt = 0 ) const;
faheem_chaudhary 5:dd98cf00ed9b 201
faheem_chaudhary 5:dd98cf00ed9b 202
faheem_chaudhary 5:dd98cf00ed9b 203 /** findKeyIndexIn will find and return the token index representing the
faheem_chaudhary 5:dd98cf00ed9b 204 'Key' in underlying JSON object node. It is strictly a single-level
faheem_chaudhary 5:dd98cf00ed9b 205 key search function, and will NOT look for the key in any child JSON
faheem_chaudhary 5:dd98cf00ed9b 206 nodes (JSON Object/Array).
faheem_chaudhary 5:dd98cf00ed9b 207
faheem_chaudhary 5:dd98cf00ed9b 208 @param key a char string to find as a 'Key' in JSON structure.
faheem_chaudhary 5:dd98cf00ed9b 209 @param parentIndex the starting token-index for 'key' search. The
faheem_chaudhary 5:dd98cf00ed9b 210 search will look for the key, only under the JSON node
faheem_chaudhary 5:dd98cf00ed9b 211 represented by this parentIndex. Default value is '0', making
faheem_chaudhary 5:dd98cf00ed9b 212 the default behavior to look for only root-level keys. The
faheem_chaudhary 5:dd98cf00ed9b 213 valid value range is 0 to [parsedTokenCount()-1] both inclusive.
faheem_chaudhary 5:dd98cf00ed9b 214
faheem_chaudhary 5:dd98cf00ed9b 215 @return a non-zero positive integer, if a key is found in the source
faheem_chaudhary 5:dd98cf00ed9b 216 JSON. If no key is found, -1 will be returned. There should be
faheem_chaudhary 5:dd98cf00ed9b 217 no '0' value returned in any valid case.
faheem_chaudhary 5:dd98cf00ed9b 218 */
faheem_chaudhary 5:dd98cf00ed9b 219 int findKeyIndexIn ( const char * key, const int &parentIndex = 0 ) const;
faheem_chaudhary 5:dd98cf00ed9b 220
faheem_chaudhary 5:dd98cf00ed9b 221
faheem_chaudhary 5:dd98cf00ed9b 222 /** findChildIndexOf will find and return the token index representing
faheem_chaudhary 5:dd98cf00ed9b 223 first child a JSON node represented by parentIndex (that is either a
faheem_chaudhary 5:dd98cf00ed9b 224 Key, an Object, or an Array), and exists after the startingAt value.
faheem_chaudhary 5:dd98cf00ed9b 225 This function is particularly handy in iterating over Array Objects, or
faheem_chaudhary 5:dd98cf00ed9b 226 getting the index for JSON 'Value' of a JSON 'Key'.
faheem_chaudhary 5:dd98cf00ed9b 227
faheem_chaudhary 5:dd98cf00ed9b 228 @param parentIndex token index representing the parent node in JSON
faheem_chaudhary 5:dd98cf00ed9b 229 source. The valid value range is 0 to [parsedTokenCount()-1]
faheem_chaudhary 5:dd98cf00ed9b 230 both inclusive.
faheem_chaudhary 5:dd98cf00ed9b 231 @param startingAt describes the starting index of the nodes to search.
faheem_chaudhary 5:dd98cf00ed9b 232 In other words, if caller wants to skip some nodes, they can
faheem_chaudhary 5:dd98cf00ed9b 233 provide this value. Default value is 0, which means search for
faheem_chaudhary 5:dd98cf00ed9b 234 all nodes in the parent.
faheem_chaudhary 5:dd98cf00ed9b 235
faheem_chaudhary 5:dd98cf00ed9b 236 @return a non-zero positive integer, if the child node is found in
faheem_chaudhary 5:dd98cf00ed9b 237 source JSON. If no child is found, -1 will be returned. There
faheem_chaudhary 5:dd98cf00ed9b 238 should be no '0' value returned in any valid case.
faheem_chaudhary 5:dd98cf00ed9b 239 */
faheem_chaudhary 5:dd98cf00ed9b 240 int findChildIndexOf ( const int &parentIndex, const int &startingAt = 0 ) const;
faheem_chaudhary 5:dd98cf00ed9b 241
faheem_chaudhary 5:dd98cf00ed9b 242
faheem_chaudhary 5:dd98cf00ed9b 243 /** matches will tell if the token data (either key or value) matches
faheem_chaudhary 5:dd98cf00ed9b 244 with the value provided. This function is particularly handy in
faheem_chaudhary 5:dd98cf00ed9b 245 iterating over the keys, and finding a specific key, in an object. The
faheem_chaudhary 5:dd98cf00ed9b 246 comparison is case-sensitive. i.e. 'Apple' will NOT match with 'apple'.
faheem_chaudhary 5:dd98cf00ed9b 247
faheem_chaudhary 5:dd98cf00ed9b 248 @param tokenIndex representing the token to compare. The valid value
faheem_chaudhary 5:dd98cf00ed9b 249 range is 0 to [parsedTokenCount()-1] both inclusive.
faheem_chaudhary 5:dd98cf00ed9b 250 @param value to compare the token data with.
faheem_chaudhary 5:dd98cf00ed9b 251
faheem_chaudhary 5:dd98cf00ed9b 252 @return true if the token data matches with value. false will be
faheem_chaudhary 5:dd98cf00ed9b 253 returned either the value doesn't match OR the tokenIndex is
faheem_chaudhary 5:dd98cf00ed9b 254 not valid.
faheem_chaudhary 5:dd98cf00ed9b 255 */
mercurywaters 3:fab591fca1e7 256 bool matches ( const int & tokenIndex, const char * value ) const;
mercurywaters 3:fab591fca1e7 257
faheem_chaudhary 5:dd98cf00ed9b 258
faheem_chaudhary 5:dd98cf00ed9b 259 /** parsedTokenCount will tell how many tokens have been parsed by JSMN
faheem_chaudhary 5:dd98cf00ed9b 260 parser. It is a utility function, for token validity.
faheem_chaudhary 5:dd98cf00ed9b 261
faheem_chaudhary 5:dd98cf00ed9b 262 @return non-negative integer number of tokens parsed by JSMN library.
faheem_chaudhary 5:dd98cf00ed9b 263 Negative value may be returned in case of error, but this
faheem_chaudhary 5:dd98cf00ed9b 264 behavior is not tested, yet.
faheem_chaudhary 5:dd98cf00ed9b 265 */
faheem_chaudhary 5:dd98cf00ed9b 266 inline int parsedTokenCount () const;
faheem_chaudhary 5:dd98cf00ed9b 267
faheem_chaudhary 5:dd98cf00ed9b 268
faheem_chaudhary 5:dd98cf00ed9b 269 /** isValidJson will tell the caller if the parsed JSON was valid,
faheem_chaudhary 5:dd98cf00ed9b 270 parsed, and accepted to further work on.
faheem_chaudhary 5:dd98cf00ed9b 271
faheem_chaudhary 5:dd98cf00ed9b 272 @return true if the JSON is valid, false otherwise.
faheem_chaudhary 5:dd98cf00ed9b 273 */
mercurywaters 3:fab591fca1e7 274 inline bool isValidJson () const;
faheem_chaudhary 5:dd98cf00ed9b 275
faheem_chaudhary 5:dd98cf00ed9b 276
faheem_chaudhary 5:dd98cf00ed9b 277 /** isValidToken will tell the caller if the tokenIndex is in valid
faheem_chaudhary 5:dd98cf00ed9b 278 range. The valid value range is 0 to [parsedTokenCount()-1] both
faheem_chaudhary 5:dd98cf00ed9b 279 inclusive.
faheem_chaudhary 5:dd98cf00ed9b 280
faheem_chaudhary 5:dd98cf00ed9b 281 @param tokenIndex representing the token in the JSON source
faheem_chaudhary 5:dd98cf00ed9b 282
faheem_chaudhary 5:dd98cf00ed9b 283 @return true if the JSON is valid, false otherwise.
faheem_chaudhary 5:dd98cf00ed9b 284 */
faheem_chaudhary 5:dd98cf00ed9b 285 inline bool isValidToken ( const int tokenIndex ) const;
faheem_chaudhary 5:dd98cf00ed9b 286
faheem_chaudhary 5:dd98cf00ed9b 287
faheem_chaudhary 5:dd98cf00ed9b 288 /** type will return the JSMN type represented by the tokenIndex.
faheem_chaudhary 5:dd98cf00ed9b 289
faheem_chaudhary 5:dd98cf00ed9b 290 @param tokenIndex representing the token in the JSON source. The valid
faheem_chaudhary 5:dd98cf00ed9b 291 value range is 0 to [parsedTokenCount()-1] both inclusive.
faheem_chaudhary 5:dd98cf00ed9b 292
faheem_chaudhary 5:dd98cf00ed9b 293 @return the type represented by tokenIndex. In case of invalid
faheem_chaudhary 5:dd98cf00ed9b 294 tokenIndex, JSMN_UNDEFINED is returned.
faheem_chaudhary 5:dd98cf00ed9b 295 */
mercurywaters 3:fab591fca1e7 296 inline jsmntype_t type ( const int tokenIndex ) const;
faheem_chaudhary 5:dd98cf00ed9b 297
faheem_chaudhary 5:dd98cf00ed9b 298
faheem_chaudhary 5:dd98cf00ed9b 299 /** parent is a utility function to get the parent index of the
faheem_chaudhary 5:dd98cf00ed9b 300 tokenIndex passed.
faheem_chaudhary 5:dd98cf00ed9b 301
faheem_chaudhary 5:dd98cf00ed9b 302 @param tokenIndex representing the token in the JSON source. The valid
faheem_chaudhary 5:dd98cf00ed9b 303 value range is 0 to [parsedTokenCount()-1] both inclusive.
faheem_chaudhary 5:dd98cf00ed9b 304
faheem_chaudhary 5:dd98cf00ed9b 305 @return the parentIndex if the node has a parent, and tokenIndex is a
faheem_chaudhary 5:dd98cf00ed9b 306 valid index. In case of no parent, or invalid tokenIndex, -1
faheem_chaudhary 5:dd98cf00ed9b 307 is returned.
faheem_chaudhary 5:dd98cf00ed9b 308 */
mercurywaters 3:fab591fca1e7 309 inline int parent ( const int tokenIndex ) const;
faheem_chaudhary 5:dd98cf00ed9b 310
faheem_chaudhary 5:dd98cf00ed9b 311
faheem_chaudhary 5:dd98cf00ed9b 312 /** childCount returns the number of children sharing the same parent.
faheem_chaudhary 5:dd98cf00ed9b 313 This utility function is handy for iterating over Arrays or Objects.
faheem_chaudhary 5:dd98cf00ed9b 314
faheem_chaudhary 5:dd98cf00ed9b 315 @param tokenIndex representing the token in the JSON source. The valid
faheem_chaudhary 5:dd98cf00ed9b 316 value range is 0 to [parsedTokenCount()-1] both inclusive.
faheem_chaudhary 5:dd98cf00ed9b 317
faheem_chaudhary 5:dd98cf00ed9b 318 @return non-negative integer representing the number of children
faheem_chaudhary 5:dd98cf00ed9b 319 tokenIndex node has. 0 is a valid number, in case the node has
faheem_chaudhary 5:dd98cf00ed9b 320 no child nodes. -1 will be returned if the tokenIndex is not
faheem_chaudhary 5:dd98cf00ed9b 321 valid.
faheem_chaudhary 5:dd98cf00ed9b 322 */
mercurywaters 3:fab591fca1e7 323 inline int childCount ( const int tokenIndex ) const;
faheem_chaudhary 5:dd98cf00ed9b 324
faheem_chaudhary 5:dd98cf00ed9b 325
faheem_chaudhary 5:dd98cf00ed9b 326 /** tokenLength returns the number of characters a node takes up in JSON
faheem_chaudhary 5:dd98cf00ed9b 327 source string.
faheem_chaudhary 5:dd98cf00ed9b 328
faheem_chaudhary 5:dd98cf00ed9b 329 @param tokenIndex representing the token in the JSON source. The valid
faheem_chaudhary 5:dd98cf00ed9b 330 value range is 0 to [parsedTokenCount()-1] both inclusive.
faheem_chaudhary 5:dd98cf00ed9b 331
faheem_chaudhary 5:dd98cf00ed9b 332 @return positive integer value representing the length of the token
faheem_chaudhary 5:dd98cf00ed9b 333 sub-string in the source JSON. The 0 value is an invalid state
faheem_chaudhary 5:dd98cf00ed9b 334 and should never occur. -1 will be returned in case of invalid
faheem_chaudhary 5:dd98cf00ed9b 335 tokenIndex.
faheem_chaudhary 5:dd98cf00ed9b 336 */
mercurywaters 3:fab591fca1e7 337 inline int tokenLength ( const int tokenIndex ) const;
faheem_chaudhary 5:dd98cf00ed9b 338
faheem_chaudhary 5:dd98cf00ed9b 339
faheem_chaudhary 5:dd98cf00ed9b 340 /** tokenAddress returns the pointer that marks as the start of token
faheem_chaudhary 5:dd98cf00ed9b 341 in JSON source string. This is a utility function for character/string
faheem_chaudhary 5:dd98cf00ed9b 342 manipulation by the caller.
faheem_chaudhary 5:dd98cf00ed9b 343
faheem_chaudhary 5:dd98cf00ed9b 344 @param tokenIndex representing the token in the JSON source. The valid
faheem_chaudhary 5:dd98cf00ed9b 345 value range is 0 to [parsedTokenCount()-1] both inclusive.
faheem_chaudhary 5:dd98cf00ed9b 346
faheem_chaudhary 5:dd98cf00ed9b 347 @return a non-NULL pointer will be returned if tokenIndex is valid, -1
faheem_chaudhary 5:dd98cf00ed9b 348 otherwise.
faheem_chaudhary 5:dd98cf00ed9b 349 */
mercurywaters 3:fab591fca1e7 350 inline const char * tokenAddress ( const int tokenIndex ) const;
mercurywaters 3:fab591fca1e7 351
faheem_chaudhary 5:dd98cf00ed9b 352
faheem_chaudhary 5:dd98cf00ed9b 353 /** tokenInterValue will convert the value as int represented by the
faheem_chaudhary 5:dd98cf00ed9b 354 tokenIndex. A typical use is that caller has found the Key-index, and
faheem_chaudhary 5:dd98cf00ed9b 355 then has retrieved the Value-index (by using findChildIndexOf function)
faheem_chaudhary 5:dd98cf00ed9b 356 , and now they want to read the value of Value-index, as integer value.
faheem_chaudhary 5:dd98cf00ed9b 357
faheem_chaudhary 5:dd98cf00ed9b 358 @param tokenIndex representing the "value" in the JSON source. The
faheem_chaudhary 5:dd98cf00ed9b 359 valid value range is 0 to [parsedTokenCount()-1] both inclusive.
faheem_chaudhary 5:dd98cf00ed9b 360
faheem_chaudhary 5:dd98cf00ed9b 361 @param returnValue is a return-parameter passed by reference to hold up
faheem_chaudhary 5:dd98cf00ed9b 362 the integer value parsed by this function. If the converted
faheem_chaudhary 5:dd98cf00ed9b 363 value would be out of the range of representable values by an
faheem_chaudhary 5:dd98cf00ed9b 364 int, it causes undefined behavior. It is caller's
faheem_chaudhary 5:dd98cf00ed9b 365 responsibility to check for these cases.
faheem_chaudhary 5:dd98cf00ed9b 366
faheem_chaudhary 5:dd98cf00ed9b 367 @return 0 if the operation is successful. -1 if tokenIndex is invalid.
faheem_chaudhary 5:dd98cf00ed9b 368 */
faheem_chaudhary 5:dd98cf00ed9b 369 int tokenIntegerValue ( const int tokenIndex, int &returnValue ) const;
faheem_chaudhary 5:dd98cf00ed9b 370
faheem_chaudhary 5:dd98cf00ed9b 371
faheem_chaudhary 5:dd98cf00ed9b 372 /** tokenNumberValue will convert the value as float represented by the
faheem_chaudhary 5:dd98cf00ed9b 373 tokenIndex. A typical use is that caller has found the Key-index, and
faheem_chaudhary 5:dd98cf00ed9b 374 then has retrieved the Value-index (by using findChildIndexOf function)
faheem_chaudhary 5:dd98cf00ed9b 375 , and now they want to read the value of Value-index, as floating-point
faheem_chaudhary 5:dd98cf00ed9b 376 value.
faheem_chaudhary 5:dd98cf00ed9b 377
faheem_chaudhary 5:dd98cf00ed9b 378 @param tokenIndex representing the "value" in the JSON source. The
faheem_chaudhary 5:dd98cf00ed9b 379 valid value range is 0 to [parsedTokenCount()-1] both inclusive.
faheem_chaudhary 5:dd98cf00ed9b 380
faheem_chaudhary 5:dd98cf00ed9b 381 @param returnValue is a return-parameter passed by reference to hold up
faheem_chaudhary 5:dd98cf00ed9b 382 the floating-point value parsed by this function. If the
faheem_chaudhary 5:dd98cf00ed9b 383 converted value would be out of the range of representable
faheem_chaudhary 5:dd98cf00ed9b 384 values by a float, it causes undefined behavior. It is caller's
faheem_chaudhary 5:dd98cf00ed9b 385 responsibility to check for these cases.
mercurywaters 3:fab591fca1e7 386
faheem_chaudhary 5:dd98cf00ed9b 387 @return 0 if the operation is successful. -1 if tokenIndex is invalid.
faheem_chaudhary 5:dd98cf00ed9b 388 */
faheem_chaudhary 5:dd98cf00ed9b 389 int tokenNumberValue ( const int tokenIndex, float &returnValue ) const;
faheem_chaudhary 5:dd98cf00ed9b 390
faheem_chaudhary 5:dd98cf00ed9b 391
faheem_chaudhary 5:dd98cf00ed9b 392 /** tokenBooleanValue will convert the value as bool represented by
faheem_chaudhary 5:dd98cf00ed9b 393 the tokenIndex. A typical use is that caller has found the Key-index,
faheem_chaudhary 5:dd98cf00ed9b 394 and then has retrieved the Value-index (by using findChildIndexOf
faheem_chaudhary 5:dd98cf00ed9b 395 function), and now they want to read the value of Value-index, as
faheem_chaudhary 5:dd98cf00ed9b 396 boolean value.
faheem_chaudhary 5:dd98cf00ed9b 397
faheem_chaudhary 5:dd98cf00ed9b 398 @param tokenIndex representing the "value" in the JSON source. The
faheem_chaudhary 5:dd98cf00ed9b 399 valid value range is 0 to [parsedTokenCount()-1] both inclusive.
faheem_chaudhary 5:dd98cf00ed9b 400
faheem_chaudhary 5:dd98cf00ed9b 401 @param returnValue is a return-parameter passed by reference to hold up
faheem_chaudhary 5:dd98cf00ed9b 402 the bool value parsed by this function.
mercurywaters 3:fab591fca1e7 403
faheem_chaudhary 5:dd98cf00ed9b 404 @return 0 if the operation is successful. -1 if tokenIndex is invalid.
faheem_chaudhary 5:dd98cf00ed9b 405 */
faheem_chaudhary 5:dd98cf00ed9b 406 int tokenBooleanValue ( const int tokenIndex, bool &returnValue ) const;
faheem_chaudhary 5:dd98cf00ed9b 407
faheem_chaudhary 5:dd98cf00ed9b 408
faheem_chaudhary 5:dd98cf00ed9b 409 /** unescape is a utility function to unescape a JSON string. This
faheem_chaudhary 5:dd98cf00ed9b 410 function does not change any state of Json object, and is a pure
faheem_chaudhary 5:dd98cf00ed9b 411 static utility function. This function is in-pace unescaping, and WILL
faheem_chaudhary 5:dd98cf00ed9b 412 modify the source parameter.
faheem_chaudhary 5:dd98cf00ed9b 413
faheem_chaudhary 5:dd98cf00ed9b 414 @param jsonString representing an escaped JSON string. This parameter
faheem_chaudhary 5:dd98cf00ed9b 415 is also the return parameter as well. All modifications will be
faheem_chaudhary 5:dd98cf00ed9b 416 reflected in this parameter.
faheem_chaudhary 5:dd98cf00ed9b 417
faheem_chaudhary 5:dd98cf00ed9b 418 @return pointer to unescaped JSON string. This is exactly the same
faheem_chaudhary 5:dd98cf00ed9b 419 pointer as jsonString parameter.
faheem_chaudhary 5:dd98cf00ed9b 420 */
faheem_chaudhary 4:ae34010d87e5 421 static char * unescape ( char * jsonString );
mercurywaters 3:fab591fca1e7 422 };
mercurywaters 3:fab591fca1e7 423
faheem_chaudhary 5:dd98cf00ed9b 424 inline int Json::parsedTokenCount () const
faheem_chaudhary 5:dd98cf00ed9b 425 {
faheem_chaudhary 5:dd98cf00ed9b 426 return tokenCount;
faheem_chaudhary 5:dd98cf00ed9b 427 }
faheem_chaudhary 5:dd98cf00ed9b 428
mercurywaters 3:fab591fca1e7 429 inline bool Json::isValidJson () const
mercurywaters 3:fab591fca1e7 430 {
mercurywaters 3:fab591fca1e7 431 return ( tokenCount >= 1 );
mercurywaters 3:fab591fca1e7 432 }
mercurywaters 3:fab591fca1e7 433
faheem_chaudhary 5:dd98cf00ed9b 434 inline bool Json::isValidToken ( const int tokenIndex ) const
faheem_chaudhary 5:dd98cf00ed9b 435 {
faheem_chaudhary 5:dd98cf00ed9b 436 return ( tokenIndex >= 0 && tokenIndex < tokenCount );
faheem_chaudhary 5:dd98cf00ed9b 437 }
faheem_chaudhary 5:dd98cf00ed9b 438
mercurywaters 3:fab591fca1e7 439 inline jsmntype_t Json::type ( const int tokenIndex ) const
mercurywaters 3:fab591fca1e7 440 {
faheem_chaudhary 5:dd98cf00ed9b 441 jsmntype_t retVal = JSMN_UNDEFINED;
faheem_chaudhary 5:dd98cf00ed9b 442
faheem_chaudhary 5:dd98cf00ed9b 443 if ( isValidToken ( tokenIndex ) )
faheem_chaudhary 5:dd98cf00ed9b 444 {
faheem_chaudhary 5:dd98cf00ed9b 445 retVal = tokens [ tokenIndex ].type;
faheem_chaudhary 5:dd98cf00ed9b 446 }
faheem_chaudhary 5:dd98cf00ed9b 447
faheem_chaudhary 5:dd98cf00ed9b 448 return retVal;
mercurywaters 3:fab591fca1e7 449 }
mercurywaters 3:fab591fca1e7 450
mercurywaters 3:fab591fca1e7 451 inline int Json::parent ( const int tokenIndex ) const
mercurywaters 3:fab591fca1e7 452 {
faheem_chaudhary 5:dd98cf00ed9b 453 int retVal = -1;
faheem_chaudhary 5:dd98cf00ed9b 454
faheem_chaudhary 5:dd98cf00ed9b 455 if ( isValidToken ( tokenIndex ) )
faheem_chaudhary 5:dd98cf00ed9b 456 {
faheem_chaudhary 5:dd98cf00ed9b 457 retVal = tokens [ tokenIndex ].parent;
faheem_chaudhary 5:dd98cf00ed9b 458 }
faheem_chaudhary 5:dd98cf00ed9b 459
faheem_chaudhary 5:dd98cf00ed9b 460 return retVal;
mercurywaters 3:fab591fca1e7 461 }
mercurywaters 3:fab591fca1e7 462
mercurywaters 3:fab591fca1e7 463 inline int Json::childCount ( const int tokenIndex ) const
mercurywaters 3:fab591fca1e7 464 {
faheem_chaudhary 5:dd98cf00ed9b 465 int retVal = -1;
faheem_chaudhary 5:dd98cf00ed9b 466
faheem_chaudhary 5:dd98cf00ed9b 467 if ( isValidToken ( tokenIndex ) )
faheem_chaudhary 5:dd98cf00ed9b 468 {
faheem_chaudhary 5:dd98cf00ed9b 469 retVal = tokens [ tokenIndex ].childCount;
faheem_chaudhary 5:dd98cf00ed9b 470 }
faheem_chaudhary 5:dd98cf00ed9b 471
faheem_chaudhary 5:dd98cf00ed9b 472 return retVal;
mercurywaters 3:fab591fca1e7 473 }
mercurywaters 3:fab591fca1e7 474
mercurywaters 3:fab591fca1e7 475 inline int Json::tokenLength ( const int tokenIndex ) const
mercurywaters 3:fab591fca1e7 476 {
faheem_chaudhary 5:dd98cf00ed9b 477 int retVal = -1;
faheem_chaudhary 5:dd98cf00ed9b 478
faheem_chaudhary 5:dd98cf00ed9b 479 if ( isValidToken ( tokenIndex ) )
faheem_chaudhary 5:dd98cf00ed9b 480 {
faheem_chaudhary 5:dd98cf00ed9b 481 retVal = tokens [ tokenIndex ].end - tokens [ tokenIndex ].start;
faheem_chaudhary 5:dd98cf00ed9b 482 }
faheem_chaudhary 5:dd98cf00ed9b 483
faheem_chaudhary 5:dd98cf00ed9b 484 return retVal;
mercurywaters 3:fab591fca1e7 485 }
mercurywaters 3:fab591fca1e7 486
mercurywaters 3:fab591fca1e7 487 inline const char * Json::tokenAddress ( const int tokenIndex ) const
mercurywaters 3:fab591fca1e7 488 {
faheem_chaudhary 5:dd98cf00ed9b 489 char * retVal = NULL;
mercurywaters 3:fab591fca1e7 490
faheem_chaudhary 5:dd98cf00ed9b 491 if ( isValidToken ( tokenIndex ) )
faheem_chaudhary 4:ae34010d87e5 492 {
faheem_chaudhary 5:dd98cf00ed9b 493 retVal = (char *) source + tokens [ tokenIndex ].start;
faheem_chaudhary 4:ae34010d87e5 494 }
faheem_chaudhary 5:dd98cf00ed9b 495
faheem_chaudhary 5:dd98cf00ed9b 496 return retVal;
faheem_chaudhary 4:ae34010d87e5 497 }
faheem_chaudhary 4:ae34010d87e5 498
mercurywaters 3:fab591fca1e7 499 #endif
mercurywaters 3:fab591fca1e7 500
38domo 8:43e1e35bb7ec 501