iot_water_monitor_v2

Dependencies:   easy-connect-v16 Watchdog FP MQTTPacket RecordType-v-16 watersenor_and_temp_code

Committer:
DuyLionTran
Date:
Tue Apr 03 17:03:01 2018 +0000
Revision:
57:898fcb6692cd
Parent:
43:dcde0e66874a
;   * version 2.9.8  	03-04-2018  Minor changes. Time frame updated to IBM Watson every 60s

Who changed what in which revision?

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