iot_water_monitor_v2
Dependencies: easy-connect-v16 Watchdog FP MQTTPacket RecordType-v-16 watersenor_and_temp_code
JSON/Json.h@57:898fcb6692cd, 2018-04-03 (annotated)
- 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?
User | Revision | Line number | New 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 |