Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Json.cpp
- Committer:
- Amod Amatya amodamatya@gmail.com
- Date:
- 2017-05-25
- Revision:
- 0:c1cd8e6ecdc9
File content as of revision 0:c1cd8e6ecdc9:
/* Json.cpp */
/* Original Author: Faheem Inayat
* Created by "Night Crue" Team @ TechShop San Jose, CA
*
* MIT License
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or
* substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
* BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include "Json.h"
#include <stdio.h>
// Json::Json() : maxTokenCount ( 0 ), sourceLength ( 0 )
// {
// }
// Json::Json() :maxTokenCount ( 0 ), source ( NULL ), sourceLength ( 0 )
// {
// tokenCount = 0;
// tokens = NULL;
// }
Json::Json ( const char * jsonString, size_t length, unsigned int maxTokens )
: maxTokenCount ( maxTokens ), source ( jsonString ), sourceLength ( length )
{
jsmn_parser parser;
tokens = new jsmntok_t [ maxTokenCount ];
jsmn_init ( &parser );
tokenCount = jsmn_parse ( &parser, jsonString, length, tokens, maxTokenCount );
}
Json::Json ( const Json & )
: maxTokenCount ( 0 ), source ( NULL ), sourceLength ( 0 )
{
tokenCount = 0;
tokens = NULL;
}
Json::~Json ()
{
delete [] tokens;
}
int Json::findKeyIndex ( const char * key, const int &startingAt ) const
{
int retVal = -1;
int i = startingAt + 1;
if ( i < 0 ) {
i = 0;
}
for ( ; i < tokenCount; i++ )
{
jsmntok_t t = tokens [ i ];
if ( t.type == JSMN_KEY )
{
size_t keyLength = (size_t) ( t.end - t.start );
if ( ( strlen ( key ) == keyLength ) && ( strncmp ( source + t.start, key, keyLength ) == 0 ) )
{
retVal = i;
break;
}
}
}
return retVal;
}
int Json::findKeyIndexIn ( const char * key, const int &parentIndex ) const
{
int retVal = -1;
if ( isValidToken ( parentIndex ) )
{
for ( int i = parentIndex + 1; i < tokenCount; i++ )
{
jsmntok_t t = tokens [ i ];
if ( t.end >= tokens [ parentIndex ].end )
{
break;
}
if ( ( t.type == JSMN_KEY ) && ( t.parent == parentIndex ) )
{
size_t keyLength = (size_t) ( t.end - t.start );
if ( ( strlen ( key ) == keyLength ) && ( strncmp ( source + t.start, key, keyLength ) == 0 ) )
{
retVal = i;
break;
}
}
}
}
return retVal;
}
int Json::findChildIndexOf ( const int &parentIndex, const int &startingAt ) const
{
int retVal = -1;
if ( isValidToken ( parentIndex ) )
{
jsmntype_t type = tokens [ parentIndex ].type;
if ( ( type == JSMN_KEY ) || ( type == JSMN_OBJECT ) || ( type == JSMN_ARRAY ) )
{
int i = startingAt + 1;
if ( startingAt < 0 )
{
i = 0;
}
for ( i += parentIndex; i < tokenCount; i++ )
{
if ( tokens [ i ].parent == parentIndex )
{
retVal = i;
break;
}
}
}
}
return retVal;
}
bool Json::matches ( const int & tokenIndex, const char * value ) const
{
bool retVal = false;
if ( isValidToken ( tokenIndex ) )
{
jsmntok_t token = tokens [ tokenIndex ];
retVal = ( strncmp ( source + token.start, value, ( token.end - token.start ) ) == 0 );
}
return retVal;
}
int Json::tokenIntegerValue ( const int tokenIndex, int &returnValue ) const
{
int retVal = -1;
if ( type ( tokenIndex ) == JSMN_PRIMITIVE )
{
int len = tokenLength ( tokenIndex );
char * tok = new char [ len + 1 ];
strncpy ( tok, tokenAddress ( tokenIndex ), len );
tok [ len ] = 0;
returnValue = atoi ( tok );
delete [] tok;
retVal = 0;
}
return retVal;
}
int Json::tokenNumberValue ( const int tokenIndex, float &returnValue ) const
{
int retVal = -1;
if ( type ( tokenIndex ) == JSMN_PRIMITIVE )
{
int len = tokenLength ( tokenIndex );
char * tok = new char [ len + 1 ];
strncpy ( tok, tokenAddress ( tokenIndex ), len );
tok [ len ] = 0;
returnValue = atof ( tok );
delete [] tok;
retVal = 0;
}
return retVal;
}
int Json::tokenBooleanValue ( const int tokenIndex, bool &returnValue ) const
{
int retVal = -1;
if ( type ( tokenIndex ) == JSMN_PRIMITIVE )
{
returnValue = matches ( tokenIndex, "true" );
retVal = 0;
}
return retVal;
}
char * Json::unescape ( char * jsonString )
{
if ( jsonString != NULL )
{
int stringIndex = 0;
int indentLevel = 0;
int quoteCount = 0;
for ( int i = 0; jsonString [ i ] != 0; i ++ )
{
switch ( jsonString [ i ] )
{
case '{':
indentLevel ++;
break;
case '}':
indentLevel --;
if ( indentLevel == 0 ) {
// Just close and return the first valid JSON object. No need to handle complex cases.
jsonString [ stringIndex ++ ] = '}';
jsonString [ stringIndex ] = 0;
return jsonString;
}
break;
case '\\':
i ++;
break;
case '"':
quoteCount ++;
break;
}
if ( indentLevel > 0 )
{
if ( quoteCount == 0 ) {
return jsonString; //No need to unescape. JsonString needs to be already escaped
}
jsonString [ stringIndex ++ ] = jsonString [ i ];
}
}
jsonString [ stringIndex ] = 0;
}
return jsonString;
}
const char * Json::JsonParse(const char * jsonString, const char * key)
{
Json json ( jsonString, strlen ( jsonString));
if ( !json.isValidJson () )
{
printf( "Invalid JSON: %s", jsonString );
}
if ( json.type (0) != JSMN_OBJECT )
{
printf ( "Invalid JSON. ROOT element is not Object: %s", jsonString );
}
char *info1 = new char[32];
// ROOT object should have '0' tokenIndex, and -1 parentIndex
int KeyIndex = json.findKeyIndexIn(key,0);
if (KeyIndex == -1)
{
// Error handling part ...
printf ( "Key does not exist");
}
else
{
// Find the first child index of key-node "info"
int ValueIndex = json.findChildIndexOf (KeyIndex, -1 );
if (ValueIndex > 0 )
{
const char * valueStart = json.tokenAddress (ValueIndex );
int valueLength = json.tokenLength (ValueIndex );
strncpy ( info1, valueStart, valueLength );
// info[valueLength] = 0; // NULL-terminate the string
// strcpy(info1, info);
//let's print the value. It should be "San Jose"
// printf( "info: %s", info);
}
}
return info1;
}
// plublic:
// const char* getBar() const {
// char * str = new char[_sBar.length()+1];
// strcpy(str, _sBar.c_str());
// return str;}
// In main:
// foo object;
// ///some code
// const char* bar = object.getBar();
// ///some code
// delete [] bar;