forked from bblanchon/ArduinoJson
Added class JsonToken
This commit is contained in:
@ -7,8 +7,31 @@
|
||||
#include "JsonHashTable.h"
|
||||
|
||||
using namespace ArduinoJson::Parser;
|
||||
using namespace ArduinoJson::Internal;
|
||||
|
||||
DEPRECATED JsonHashTable JsonArray::getHashTable(int index)
|
||||
{
|
||||
return (JsonHashTable) (*this)[index];
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the token for the value at the specified index
|
||||
*/
|
||||
JsonValue JsonArray::operator[](int index)
|
||||
{
|
||||
// sanity check
|
||||
if (index < 0 || !token.isArray() || index >= token.size())
|
||||
return JsonValue::null();
|
||||
|
||||
// skip first token, it's the whole object
|
||||
JsonToken currentToken = token + 1;
|
||||
|
||||
// skip all tokens before the specified index
|
||||
for (int i = 0; i < index; i++)
|
||||
{
|
||||
// move forward: current + nested tokens
|
||||
currentToken += 1 + currentToken.nestedTokenCount();
|
||||
}
|
||||
|
||||
return JsonValue(json, currentToken);
|
||||
}
|
@ -7,6 +7,7 @@
|
||||
|
||||
#include "JsonValue.h"
|
||||
#include "JsonArrayIterator.h"
|
||||
#include "JsonToken.h"
|
||||
|
||||
namespace ArduinoJson
|
||||
{
|
||||
@ -15,40 +16,41 @@ namespace ArduinoJson
|
||||
class JsonHashTable;
|
||||
|
||||
class JsonArray
|
||||
{
|
||||
{
|
||||
public:
|
||||
|
||||
JsonArray() {}
|
||||
JsonArray()
|
||||
: token(0)
|
||||
{
|
||||
|
||||
JsonArray(JsonValue& value)
|
||||
: value(value)
|
||||
}
|
||||
|
||||
JsonArray(char* json, Internal::JsonToken token)
|
||||
: json(json), token(token)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bool success()
|
||||
{
|
||||
return value.success();
|
||||
return token.isArray();
|
||||
}
|
||||
|
||||
int size()
|
||||
{
|
||||
return value.size();
|
||||
return success() ? token.size() : 0;
|
||||
}
|
||||
|
||||
JsonValue operator[](int index)
|
||||
{
|
||||
return value[index];
|
||||
}
|
||||
JsonValue operator[](int index);
|
||||
|
||||
JsonArrayIterator begin()
|
||||
{
|
||||
return JsonArrayIterator(value);
|
||||
return JsonArrayIterator(json, token);
|
||||
}
|
||||
|
||||
JsonArrayIterator end()
|
||||
{
|
||||
return JsonArrayIterator();
|
||||
return JsonArrayIterator(json, token + token.nestedTokenCount());
|
||||
}
|
||||
|
||||
DEPRECATED int getLength()
|
||||
@ -83,9 +85,15 @@ namespace ArduinoJson
|
||||
return (char*) (*this)[index];
|
||||
}
|
||||
|
||||
static JsonArray null()
|
||||
{
|
||||
return JsonArray();
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
JsonValue value;
|
||||
char* json;
|
||||
Internal::JsonToken token;
|
||||
};
|
||||
}
|
||||
}
|
@ -6,6 +6,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "JsonValue.h"
|
||||
#include "JsonToken.h"
|
||||
|
||||
namespace ArduinoJson
|
||||
{
|
||||
@ -21,33 +22,34 @@ namespace ArduinoJson
|
||||
|
||||
JsonArrayIterator operator++()
|
||||
{
|
||||
tokens++;
|
||||
return *this;
|
||||
JsonArrayIterator prev = *this;
|
||||
token += 1;
|
||||
return prev;
|
||||
}
|
||||
|
||||
JsonValue operator*()
|
||||
{
|
||||
return JsonValue(json, tokens);
|
||||
return JsonValue(json, token);
|
||||
}
|
||||
|
||||
bool operator !=(const JsonArrayIterator& other)
|
||||
{
|
||||
return tokens != other.tokens || json != other.json;
|
||||
return token != other.token || json != other.json;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
char* json;
|
||||
jsmntok_t* tokens;
|
||||
Internal::JsonToken token;
|
||||
|
||||
JsonArrayIterator()
|
||||
: json(0), tokens(0)
|
||||
: json(0), token(0)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
JsonArrayIterator(JsonValue& value)
|
||||
: json(value.json), tokens(value.tokens)
|
||||
JsonArrayIterator(char* json, Internal::JsonToken& token)
|
||||
: json(json), token(token)
|
||||
{
|
||||
|
||||
}
|
||||
|
@ -3,13 +3,51 @@
|
||||
* Benoit Blanchon 2014 - MIT License
|
||||
*/
|
||||
|
||||
#include <string.h> // for strcmp()
|
||||
#include "JsonHashTable.h"
|
||||
#include "JsonArray.h"
|
||||
#include "JsonValue.h"
|
||||
|
||||
using namespace ArduinoJson::Parser;
|
||||
using namespace ArduinoJson::Internal;
|
||||
|
||||
DEPRECATED JsonArray JsonHashTable::getArray(const char* key)
|
||||
{
|
||||
return (JsonArray) (*this)[key];
|
||||
return (*this)[key];
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the token for the value associated with the specified key
|
||||
*/
|
||||
JsonValue JsonHashTable::getValue(const char* desiredKey)
|
||||
{
|
||||
// sanity check
|
||||
if (desiredKey == 0 || !token.isObject())
|
||||
return JsonValue::null();
|
||||
|
||||
// skip first token, it's the whole object
|
||||
JsonToken runningToken = token + 1;
|
||||
|
||||
// scan each keys
|
||||
for (int i = 0; i < token.size() / 2; i++)
|
||||
{
|
||||
// get 'key' token string
|
||||
char* key = runningToken.getText(json);
|
||||
|
||||
// move to the 'value' token
|
||||
runningToken += 1;
|
||||
|
||||
// compare with desired name
|
||||
if (strcmp(desiredKey, key) == 0)
|
||||
{
|
||||
// return the value token that follows the key token
|
||||
return JsonValue(json, runningToken);
|
||||
}
|
||||
|
||||
// skip nested tokens
|
||||
runningToken += 1 + runningToken.nestedTokenCount();
|
||||
}
|
||||
|
||||
// nothing found, return NULL
|
||||
return JsonValue::null();
|
||||
}
|
@ -19,59 +19,70 @@ namespace ArduinoJson
|
||||
|
||||
public:
|
||||
|
||||
JsonHashTable() {}
|
||||
JsonHashTable()
|
||||
: token(Internal::JsonToken::null())
|
||||
{
|
||||
}
|
||||
|
||||
bool success()
|
||||
{
|
||||
return value.success();
|
||||
return token.isObject();
|
||||
}
|
||||
|
||||
JsonValue operator[](const char* key)
|
||||
{
|
||||
return value[key];
|
||||
return getValue(key);
|
||||
}
|
||||
|
||||
bool containsKey(const char* key)
|
||||
{
|
||||
return value[key];
|
||||
return getValue(key).success();
|
||||
}
|
||||
|
||||
DEPRECATED JsonArray getArray(const char* key);
|
||||
|
||||
DEPRECATED bool getBool(const char* key)
|
||||
{
|
||||
return value[key];
|
||||
return getValue(key);
|
||||
}
|
||||
|
||||
DEPRECATED double getDouble(const char* key)
|
||||
{
|
||||
return value[key];
|
||||
return getValue(key);
|
||||
}
|
||||
|
||||
DEPRECATED JsonHashTable getHashTable(const char* key)
|
||||
{
|
||||
return value[key];
|
||||
return getValue(key);
|
||||
}
|
||||
|
||||
DEPRECATED long getLong(const char* key)
|
||||
{
|
||||
return value[key];
|
||||
return getValue(key);
|
||||
}
|
||||
|
||||
DEPRECATED char* getString(const char* key)
|
||||
{
|
||||
return value[key];
|
||||
return getValue(key);
|
||||
}
|
||||
|
||||
static JsonHashTable null()
|
||||
{
|
||||
return JsonHashTable();
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
JsonHashTable(JsonValue& value)
|
||||
: value(value)
|
||||
JsonHashTable(char* json, Internal::JsonToken token)
|
||||
: json(json), token(token)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
JsonValue value;
|
||||
char* json;
|
||||
Internal::JsonToken token;
|
||||
|
||||
JsonValue getValue(const char* key);
|
||||
};
|
||||
}
|
||||
}
|
@ -4,8 +4,10 @@
|
||||
*/
|
||||
|
||||
#include "JsonParserBase.h"
|
||||
#include "JsonToken.h"
|
||||
|
||||
using namespace ArduinoJson::Parser;
|
||||
using namespace ArduinoJson::Internal;
|
||||
|
||||
JsonValue JsonParserBase::parse(char* json)
|
||||
{
|
||||
@ -13,7 +15,7 @@ JsonValue JsonParserBase::parse(char* json)
|
||||
jsmn_init(&parser);
|
||||
|
||||
if (JSMN_SUCCESS != jsmn_parse(&parser, json, tokens, maxTokens))
|
||||
return JsonValue();
|
||||
return JsonValue::null();
|
||||
|
||||
return JsonValue(json, tokens);
|
||||
return JsonValue(json, JsonToken(tokens));
|
||||
}
|
||||
|
21
JsonParser/JsonToken.cpp
Normal file
21
JsonParser/JsonToken.cpp
Normal file
@ -0,0 +1,21 @@
|
||||
|
||||
#include "JsonToken.h"
|
||||
|
||||
using namespace ArduinoJson::Internal;
|
||||
|
||||
int JsonToken::nestedTokenCount() const
|
||||
{
|
||||
jsmntok_t* t = token;
|
||||
int yetToVisit = t->size;
|
||||
int count = 0;
|
||||
|
||||
while (yetToVisit)
|
||||
{
|
||||
count++;
|
||||
t++;
|
||||
yetToVisit--;
|
||||
yetToVisit += t->size;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
87
JsonParser/JsonToken.h
Normal file
87
JsonParser/JsonToken.h
Normal file
@ -0,0 +1,87 @@
|
||||
/*
|
||||
* Arduino JSON library
|
||||
* Benoit Blanchon 2014 - MIT License
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "jsmn.h"
|
||||
|
||||
namespace ArduinoJson
|
||||
{
|
||||
namespace Internal
|
||||
{
|
||||
class JsonToken
|
||||
{
|
||||
public:
|
||||
|
||||
JsonToken(jsmntok_t* token)
|
||||
:token(token)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
char* getText(char* json)
|
||||
{
|
||||
json[token->end] = 0;
|
||||
return json + token->start;
|
||||
}
|
||||
|
||||
JsonToken operator+ (int n)
|
||||
{
|
||||
return JsonToken(token + n);
|
||||
}
|
||||
|
||||
void operator+= (int n)
|
||||
{
|
||||
token += n;
|
||||
}
|
||||
|
||||
bool operator!= (const JsonToken& other)
|
||||
{
|
||||
return token != other.token;
|
||||
}
|
||||
|
||||
int size()
|
||||
{
|
||||
return token->size;
|
||||
}
|
||||
|
||||
bool isValid()
|
||||
{
|
||||
return token != 0;
|
||||
}
|
||||
|
||||
bool isObject()
|
||||
{
|
||||
return token != 0 && token->type == JSMN_OBJECT;
|
||||
}
|
||||
|
||||
bool isArray()
|
||||
{
|
||||
return token != 0 && token->type == JSMN_ARRAY;
|
||||
}
|
||||
|
||||
bool isPrimitive()
|
||||
{
|
||||
return token != 0 && token->type == JSMN_PRIMITIVE;
|
||||
}
|
||||
|
||||
bool isString()
|
||||
{
|
||||
return token != 0 && token->type == JSMN_STRING;
|
||||
}
|
||||
|
||||
static JsonToken null()
|
||||
{
|
||||
return JsonToken(0);
|
||||
}
|
||||
|
||||
int nestedTokenCount() const;
|
||||
|
||||
private:
|
||||
jsmntok_t* token;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -4,141 +4,57 @@
|
||||
*/
|
||||
|
||||
#include <stdlib.h> // for strtol, strtod
|
||||
#include <string.h> // for strcmp()
|
||||
#include "JsonArray.h"
|
||||
#include "JsonHashTable.h"
|
||||
#include "JsonValue.h"
|
||||
|
||||
using namespace ArduinoJson::Parser;
|
||||
using namespace ArduinoJson::Internal;
|
||||
|
||||
JsonValue::operator bool()
|
||||
{
|
||||
if (tokens == 0 || tokens->type != JSMN_PRIMITIVE) return 0;
|
||||
if (!token.isPrimitive()) return 0;
|
||||
|
||||
char *text = token.getText(json);
|
||||
|
||||
// "true"
|
||||
if (json[tokens->start] == 't') return true;
|
||||
if (text[0] == 't') return true;
|
||||
|
||||
// "false"
|
||||
if (json[tokens->start] == 'f') return false;
|
||||
if (text[0] == 'f') return false;
|
||||
|
||||
// "null"
|
||||
if (json[tokens->start] == 'n') return false;
|
||||
if (text[0] == 'n') return false;
|
||||
|
||||
// number
|
||||
return strtol(json + tokens->start, 0, 0) != 0;
|
||||
return strtol(text, 0, 0) != 0;
|
||||
}
|
||||
|
||||
JsonValue::operator double()
|
||||
{
|
||||
if (tokens == 0 || tokens->type != JSMN_PRIMITIVE) return 0;
|
||||
|
||||
return strtod(json + tokens->start, 0);
|
||||
return token.isPrimitive() ? strtod(token.getText(json), 0) : 0;
|
||||
}
|
||||
|
||||
JsonValue::operator long()
|
||||
{
|
||||
if (tokens == 0 || tokens->type != JSMN_PRIMITIVE) return 0;
|
||||
|
||||
return strtol(json + tokens->start, 0, 0);
|
||||
return token.isPrimitive() ? strtol(token.getText(json), 0, 0) : 0;
|
||||
}
|
||||
|
||||
JsonValue::operator char*()
|
||||
{
|
||||
if (tokens == 0 || tokens->type != JSMN_PRIMITIVE && tokens->type != JSMN_STRING)
|
||||
return 0;
|
||||
|
||||
// add null terminator to the string
|
||||
json[tokens->end] = 0;
|
||||
|
||||
return json + tokens->start;
|
||||
return token.isString() || token.isPrimitive() ? token.getText(json) : 0;
|
||||
}
|
||||
|
||||
JsonValue::operator JsonArray()
|
||||
{
|
||||
return tokens != 0 && tokens->type == JSMN_ARRAY
|
||||
? JsonArray(*this)
|
||||
: JsonArray();
|
||||
return token.isArray()
|
||||
? JsonArray(json, token)
|
||||
: JsonArray::null();
|
||||
}
|
||||
|
||||
JsonValue::operator JsonHashTable()
|
||||
{
|
||||
return tokens != 0 && tokens->type == JSMN_OBJECT
|
||||
? JsonHashTable(*this)
|
||||
: JsonHashTable();
|
||||
}
|
||||
|
||||
int JsonValue::size()
|
||||
{
|
||||
return tokens != 0 && tokens->type == JSMN_ARRAY ? tokens->size : 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the token for the value associated with the specified key
|
||||
*/
|
||||
JsonValue JsonValue::operator [](const char* desiredKey)
|
||||
{
|
||||
// sanity check
|
||||
if (json == 0 || desiredKey == 0 || tokens->type != JSMN_OBJECT)
|
||||
return JsonValue();
|
||||
|
||||
// skip first token, it's the whole object
|
||||
jsmntok_t* currentToken = tokens + 1;
|
||||
|
||||
// scan each keys
|
||||
for (int i = 0; i < tokens[0].size / 2; i++)
|
||||
{
|
||||
// get key token string
|
||||
char* key = JsonValue(json, currentToken);
|
||||
|
||||
// compare with desired name
|
||||
if (strcmp(desiredKey, key) == 0)
|
||||
{
|
||||
// return the value token that follows the key token
|
||||
return JsonValue(json, currentToken + 1);
|
||||
}
|
||||
|
||||
// move forward: key + value + nested tokens
|
||||
currentToken += 2 + getNestedTokenCount(currentToken + 1);
|
||||
}
|
||||
|
||||
// nothing found, return NULL
|
||||
return JsonValue();
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the token for the value at the specified index
|
||||
*/
|
||||
JsonValue JsonValue::operator[](int index)
|
||||
{
|
||||
// sanity check
|
||||
if (index < 0 || index >= size())
|
||||
return JsonValue();
|
||||
|
||||
// skip first token, it's the whole object
|
||||
jsmntok_t* currentToken = tokens + 1;
|
||||
|
||||
// skip all tokens before the specified index
|
||||
for (int i = 0; i < index; i++)
|
||||
{
|
||||
// move forward: current + nested tokens
|
||||
currentToken += 1 + getNestedTokenCount(currentToken);
|
||||
}
|
||||
|
||||
return JsonValue(json, currentToken);
|
||||
}
|
||||
|
||||
int JsonValue::getNestedTokenCount(jsmntok_t* token)
|
||||
{
|
||||
int tokensToVisit = token->size;
|
||||
int count = 0;
|
||||
|
||||
while (tokensToVisit)
|
||||
{
|
||||
count++;
|
||||
token++;
|
||||
tokensToVisit--;
|
||||
tokensToVisit += token->size;
|
||||
}
|
||||
|
||||
return count;
|
||||
return token.isObject()
|
||||
? JsonHashTable(json, token)
|
||||
: JsonHashTable::null();
|
||||
}
|
@ -5,7 +5,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "jsmn.h"
|
||||
#include "JsonToken.h"
|
||||
|
||||
#ifndef ARDUINO_JSON_NO_DEPRECATED_WARNING
|
||||
#ifdef __GNUC__
|
||||
@ -26,44 +26,37 @@ namespace ArduinoJson
|
||||
|
||||
class JsonValue
|
||||
{
|
||||
friend class JsonArrayIterator;
|
||||
|
||||
public:
|
||||
JsonValue()
|
||||
: json(0), tokens(0)
|
||||
{
|
||||
|
||||
}
|
||||
public:
|
||||
|
||||
JsonValue(char* json, jsmntok_t* tokens)
|
||||
: json(json), tokens(tokens)
|
||||
JsonValue(char* json, Internal::JsonToken token)
|
||||
: json(json), token(token)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bool success()
|
||||
{
|
||||
return json != 0 && tokens != 0;
|
||||
}
|
||||
|
||||
return token.isValid();
|
||||
}
|
||||
|
||||
operator bool();
|
||||
operator double();
|
||||
operator long();
|
||||
operator char*();
|
||||
operator JsonArray();
|
||||
operator JsonHashTable();
|
||||
JsonValue operator[](int index);
|
||||
JsonValue operator[](const char*key);
|
||||
|
||||
JsonValue operator[](const char*);
|
||||
JsonValue operator[](int);
|
||||
|
||||
int size();
|
||||
static JsonValue null()
|
||||
{
|
||||
return JsonValue(0, Internal::JsonToken(0));
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
char* json;
|
||||
jsmntok_t* tokens;
|
||||
|
||||
static int getNestedTokenCount(jsmntok_t* token);
|
||||
Internal::JsonToken token;
|
||||
};
|
||||
}
|
||||
}
|
@ -11,7 +11,7 @@ namespace JsonParserTests
|
||||
{
|
||||
public:
|
||||
|
||||
TEST_METHOD(TestMethod1)
|
||||
TEST_METHOD(SimpleIteraton)
|
||||
{
|
||||
char json [] = "[1,2,3]";
|
||||
JsonParser<4> parser;
|
||||
|
@ -89,6 +89,7 @@
|
||||
<ClCompile Include="..\JsonParser\JsonArray.cpp" />
|
||||
<ClCompile Include="..\JsonParser\JsonHashTable.cpp" />
|
||||
<ClCompile Include="..\JsonParser\JsonParserBase.cpp" />
|
||||
<ClCompile Include="..\JsonParser\JsonToken.cpp" />
|
||||
<ClCompile Include="..\JsonParser\JsonValue.cpp" />
|
||||
<ClCompile Include="JsonArrayIteratorTests.cpp" />
|
||||
<ClCompile Include="JsonArrayTests.cpp" />
|
||||
@ -102,6 +103,7 @@
|
||||
<ClInclude Include="..\JsonParser\JsonHashTable.h" />
|
||||
<ClInclude Include="..\JsonParser\JsonParser.h" />
|
||||
<ClInclude Include="..\JsonParser\JsonParserBase.h" />
|
||||
<ClInclude Include="..\JsonParser\JsonToken.h" />
|
||||
<ClInclude Include="..\JsonParser\JsonValue.h" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
|
@ -42,6 +42,9 @@
|
||||
<ClCompile Include="JsonArrayIteratorTests.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\JsonParser\JsonToken.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\JsonParser\jsmn.h">
|
||||
@ -65,5 +68,8 @@
|
||||
<ClInclude Include="..\JsonParser\JsonArrayIterator.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\JsonParser\JsonToken.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
Reference in New Issue
Block a user