JSON library based on JSMN lib

Dependents:   ATT_WNCInterface_Info WNCInterface_HTTP_example NerfUS-Coord Mbed_Prototype_copy_4_INNO_day_15_6_2017 ... more

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers Json.cpp Source File

Json.cpp

00001 /* Json.cpp */
00002 /* Original Author: Faheem Inayat
00003  * Created by "Night Crue" Team @ TechShop San Jose, CA
00004  *
00005  * MIT License
00006  *
00007  * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
00008  * and associated documentation files (the "Software"), to deal in the Software without restriction,
00009  * including without limitation the rights to use, copy, modify, merge, publish, distribute,
00010  * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
00011  * furnished to do so, subject to the following conditions:
00012  *
00013  * The above copyright notice and this permission notice shall be included in all copies or
00014  * substantial portions of the Software.
00015  *
00016  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
00017  * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
00018  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
00019  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
00020  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00021  */
00022 
00023 #include "Json.h"
00024 
00025 Json::Json ( const char * jsonString, size_t length, unsigned int maxTokens )
00026         : maxTokenCount ( maxTokens ), source ( jsonString ), sourceLength ( length )
00027 {
00028     jsmn_parser parser;
00029     tokens = new jsmntok_t [ maxTokenCount ];
00030 
00031     jsmn_init ( &parser );
00032     tokenCount = jsmn_parse ( &parser, jsonString, length, tokens, maxTokenCount );
00033 }
00034 
00035 Json::Json ( const Json & )
00036         : maxTokenCount ( 0 ), source ( NULL ), sourceLength ( 0 )
00037 {
00038     tokenCount = 0;
00039     tokens = NULL;
00040 }
00041 
00042 Json::~Json ()
00043 {
00044     delete [] tokens;
00045 }
00046 
00047 int Json::findKeyIndex ( const char * key, const int &startingAt ) const
00048 {
00049     int retVal = -1;
00050 
00051     int i = startingAt + 1;
00052     if ( i < 0 ) {
00053         i = 0;
00054     }
00055     
00056     for ( ; i < tokenCount; i++ )
00057     {
00058         jsmntok_t t = tokens [ i ];
00059 
00060         if ( t.type == JSMN_KEY )
00061         {
00062             size_t keyLength = (size_t) ( t.end - t.start );
00063             if ( ( strlen ( key ) == keyLength ) && ( strncmp ( source + t.start, key, keyLength ) == 0 ) )
00064             {
00065                 retVal = i;
00066                 break;
00067             }
00068         }
00069     }
00070 
00071     return retVal;
00072 }
00073 
00074 int Json::findKeyIndexIn ( const char * key, const int &parentIndex ) const
00075 {
00076     int retVal = -1;
00077 
00078     if ( isValidToken ( parentIndex ) )
00079     {
00080         for ( int i = parentIndex + 1; i < tokenCount; i++ )
00081         {
00082             jsmntok_t t = tokens [ i ];
00083 
00084             if ( t.end >= tokens [ parentIndex ].end )
00085             {
00086                 break;
00087             }
00088 
00089             if ( ( t.type == JSMN_KEY ) && ( t.parent == parentIndex ) )
00090             {
00091                 size_t keyLength = (size_t) ( t.end - t.start );
00092                 if ( ( strlen ( key ) == keyLength ) && ( strncmp ( source + t.start, key, keyLength ) == 0 ) )
00093                 {
00094                     retVal = i;
00095                     break;
00096                 }
00097             }
00098         }
00099     }
00100 
00101     return retVal;
00102 }
00103 
00104 int Json::findChildIndexOf ( const int &parentIndex, const int &startingAt ) const
00105 {
00106     int retVal = -1;
00107 
00108     if ( isValidToken ( parentIndex ) )
00109     {
00110 
00111         jsmntype_t type = tokens [ parentIndex ].type;
00112         if ( ( type == JSMN_KEY ) || ( type == JSMN_OBJECT ) || ( type == JSMN_ARRAY ) )
00113         {
00114             int i = startingAt + 1;
00115             if ( startingAt < 0 )
00116             {
00117                 i = 0;
00118             }
00119 
00120             for ( i += parentIndex; i < tokenCount; i++ )
00121             {
00122                 if ( tokens [ i ].parent == parentIndex )
00123                 {
00124                     retVal = i;
00125                     break;
00126                 }
00127             }
00128         }
00129     }
00130 
00131     return retVal;
00132 }
00133 
00134 bool Json::matches ( const int & tokenIndex, const char * value ) const
00135 {
00136     bool retVal = false;
00137     
00138     if ( isValidToken ( tokenIndex ) )
00139     {
00140         jsmntok_t token = tokens [ tokenIndex ];
00141         retVal = ( strncmp ( source + token.start, value, ( token.end - token.start ) ) == 0 );
00142     }
00143     
00144     return retVal;
00145 }
00146 
00147 int Json::tokenIntegerValue ( const int tokenIndex, int &returnValue ) const
00148 {
00149     int retVal = -1;
00150     
00151     if ( type ( tokenIndex ) == JSMN_PRIMITIVE )
00152     {
00153         int len = tokenLength ( tokenIndex );
00154         char * tok = new char [ len + 1 ];
00155         strncpy ( tok, tokenAddress ( tokenIndex ), len );
00156         tok [ len ] = 0;
00157         returnValue = atoi ( tok );
00158         delete [] tok;
00159         retVal = 0;
00160     }
00161     return retVal;
00162 }
00163 
00164 int Json::tokenNumberValue ( const int tokenIndex, float &returnValue ) const
00165 {
00166     int retVal = -1;
00167     
00168     if ( type ( tokenIndex ) == JSMN_PRIMITIVE )
00169     {
00170         int len = tokenLength ( tokenIndex );
00171         char * tok = new char [ len + 1 ];
00172         strncpy ( tok, tokenAddress ( tokenIndex ), len );
00173         tok [ len ] = 0;
00174         returnValue = atof ( tok );
00175         delete [] tok;
00176         retVal = 0;
00177     }
00178     
00179     return retVal;
00180 }
00181 
00182 int Json::tokenBooleanValue ( const int tokenIndex, bool &returnValue ) const
00183 {
00184     int retVal = -1;
00185     
00186     if ( type ( tokenIndex ) == JSMN_PRIMITIVE )
00187     {
00188         returnValue = matches ( tokenIndex, "true" );
00189         retVal = 0;
00190     }
00191 
00192     return retVal;
00193 }
00194 
00195 char * Json::unescape ( char * jsonString )
00196 {
00197     if ( jsonString != NULL )
00198     {
00199         int stringIndex = 0;
00200         int indentLevel = 0;
00201         int quoteCount = 0;
00202         for ( int i = 0; jsonString [ i ] != 0; i ++ )
00203         {
00204             switch ( jsonString [ i ] )
00205             {
00206                 case '{':
00207                     indentLevel ++;
00208                     break;
00209                 
00210                 case '}':
00211                     indentLevel --;
00212                     if ( indentLevel == 0 ) {
00213                         // Just close and return the first valid JSON object.  No need to handle complex cases.
00214                         jsonString [ stringIndex ++ ] = '}';
00215                         jsonString [ stringIndex ] = 0;
00216                         return jsonString;
00217                     }
00218                     break;
00219                     
00220                 case '\\':
00221                     i ++;
00222                     break;
00223                     
00224                 case '"':
00225                     quoteCount ++;
00226                     break;
00227             }
00228             
00229             if ( indentLevel > 0 )
00230             {
00231                 if ( quoteCount == 0 ) {
00232                     return jsonString; //No need to unescape.  JsonString needs to be already escaped
00233                 }
00234                 jsonString [ stringIndex ++ ] = jsonString [ i ];
00235             }
00236         }
00237         jsonString [ stringIndex ] = 0;
00238     }
00239     
00240     return jsonString;
00241 }