From 2058d1fdc6b2ee0c955e17e7c4fbfa7b9ed2d709 Mon Sep 17 00:00:00 2001 From: Joe Andolina Date: Wed, 2 Mar 2022 10:55:36 -0800 Subject: [PATCH 1/5] Adding JSON helpers --- src/JSONVar.cpp | 54 +++++++++++++++++++++++++++++++++++++++++++++++++ src/JSONVar.h | 6 ++++++ 2 files changed, 60 insertions(+) diff --git a/src/JSONVar.cpp b/src/JSONVar.cpp index 247fcc3..e933ff8 100644 --- a/src/JSONVar.cpp +++ b/src/JSONVar.cpp @@ -412,4 +412,58 @@ void JSONVar::replaceJson(struct cJSON* json) } } +//--------------------------------------------------------------------- + +bool JSONVar::hasPropertyEqualTo(const String& key, String& value) const{ + return hasPropertyEqualTo(key.c_str(), value.c_str()); +} + +//--------------------------------------------------------------------- + +bool JSONVar::hasPropertyEqualTo(const char* key, const char* value) const { + if(!hasProperty(sourceProperty)){ + return false; + } + + if(strcmp(targetValue, source[sourceProperty]) == 0){ + return true; + } + + return false; +} + +//--------------------------------------------------------------------- + +JSONVar JSONVar::getPropertyWithValue(const String& key, String& value, String child = "") const { + return getPropertyWithValue(key..c_str(), value.c_str(), child.c_str()); +} + +//--------------------------------------------------------------------- + +JSONVar JSONVar::getPropertyWithValue(const char* key, const char* value, const char* child = '') const { + if(this.hasOwnPropertyEqualTo(key, value)){ + if(source.hasOwnProperty(childName)){ + return source[childName]; + } + else { + return source; + } + } + + if(JSON.typeof_(source) == "array"){ + for (int i = 0; i < source.length(); ++i) { + if(_hasMatch(source[i], sourceProperty, targetValue)){ + if(source[i].hasOwnProperty(childName)){ + return source[i][childName]; + } + else { + return source[i]; + } + } + } + } + + return null; +} + JSONVar undefined; diff --git a/src/JSONVar.h b/src/JSONVar.h index 58a7213..e6b16b4 100644 --- a/src/JSONVar.h +++ b/src/JSONVar.h @@ -77,6 +77,12 @@ class JSONVar : public Printable { JSONVar keys() const; bool hasOwnProperty(const char* key) const; bool hasOwnProperty(const String& key) const; + + bool haPropertyEqualTo(const String& key, String& value) const; + bool hasPropertyEqualTo(const char* key, const char* value) const; + + JSONVar getPropertyWithValue(const String& key, String& value, String child = "") const; + JSONVar getPropertyWithValue(const char* key, const char* value, const char* child = '') const; static JSONVar parse(const char* s); static JSONVar parse(const String& s); From 1dac1328e6beee7aa85828a6c890301ac0d91290 Mon Sep 17 00:00:00 2001 From: Joe Andolina Date: Wed, 2 Mar 2022 11:06:08 -0800 Subject: [PATCH 2/5] More Work --- src/JSONVar.cpp | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/JSONVar.cpp b/src/JSONVar.cpp index e933ff8..e9c61ba 100644 --- a/src/JSONVar.cpp +++ b/src/JSONVar.cpp @@ -415,17 +415,17 @@ void JSONVar::replaceJson(struct cJSON* json) //--------------------------------------------------------------------- bool JSONVar::hasPropertyEqualTo(const String& key, String& value) const{ - return hasPropertyEqualTo(key.c_str(), value.c_str()); + return this.hasPropertyEqualTo(key.c_str(), value.c_str()); } //--------------------------------------------------------------------- bool JSONVar::hasPropertyEqualTo(const char* key, const char* value) const { - if(!hasProperty(sourceProperty)){ + if(!this.hasProperty(key)){ return false; } - if(strcmp(targetValue, source[sourceProperty]) == 0){ + if(strcmp(value, this[key]) == 0){ return true; } @@ -435,29 +435,29 @@ bool JSONVar::hasPropertyEqualTo(const char* key, const char* value) const { //--------------------------------------------------------------------- JSONVar JSONVar::getPropertyWithValue(const String& key, String& value, String child = "") const { - return getPropertyWithValue(key..c_str(), value.c_str(), child.c_str()); + return this.getPropertyWithValue(key..c_str(), value.c_str(), child.c_str()); } //--------------------------------------------------------------------- JSONVar JSONVar::getPropertyWithValue(const char* key, const char* value, const char* child = '') const { if(this.hasOwnPropertyEqualTo(key, value)){ - if(source.hasOwnProperty(childName)){ - return source[childName]; + if(this.hasOwnProperty(child)){ + return this[child]; } else { - return source; + return this; } } - if(JSON.typeof_(source) == "array"){ - for (int i = 0; i < source.length(); ++i) { - if(_hasMatch(source[i], sourceProperty, targetValue)){ - if(source[i].hasOwnProperty(childName)){ - return source[i][childName]; + if(JSON.typeof_(this) == "array"){ + for (int i = 0; i < this.length(); ++i) { + if(this.hasPropertyEqualTo(key, value)){ + if(this[i].hasOwnProperty(child)){ + return this[i][child]; } else { - return source[i]; + return this[i]; } } } From 1da99788176f26ed6db2a97e88a8038597b7da2b Mon Sep 17 00:00:00 2001 From: Joe Andolina Date: Thu, 3 Mar 2022 10:44:23 -0800 Subject: [PATCH 3/5] Added filtering and property comparison --- src/JSONVar.cpp | 92 ++++++++++++++++++++++++++++++------------------- src/JSONVar.h | 16 +++++---- 2 files changed, 66 insertions(+), 42 deletions(-) diff --git a/src/JSONVar.cpp b/src/JSONVar.cpp index e9c61ba..39a6fa5 100644 --- a/src/JSONVar.cpp +++ b/src/JSONVar.cpp @@ -334,7 +334,6 @@ bool JSONVar::hasOwnProperty(const char* key) const } cJSON* json = cJSON_GetObjectItemCaseSensitive(_json, key); - return (json != NULL); } @@ -414,56 +413,77 @@ void JSONVar::replaceJson(struct cJSON* json) //--------------------------------------------------------------------- -bool JSONVar::hasPropertyEqualTo(const String& key, String& value) const{ - return this.hasPropertyEqualTo(key.c_str(), value.c_str()); -} - -//--------------------------------------------------------------------- +bool JSONVar::hasPropertyEqual(const char* key, const char* value) const { + // Serial.printf("JSONVar::hasPropertyEqual - %s == %s\n", key, value); -bool JSONVar::hasPropertyEqualTo(const char* key, const char* value) const { - if(!this.hasProperty(key)){ + if (!cJSON_IsObject(_json)) { return false; } - if(strcmp(value, this[key]) == 0){ - return true; - } - - return false; -} + cJSON* json = cJSON_GetObjectItemCaseSensitive(_json, key); + // Serial.printf("JSONVar::hasPropertyEqual - Found %s\n", json->valuestring); + return json != NULL && strcmp(value, json->valuestring) == 0; +} //--------------------------------------------------------------------- -JSONVar JSONVar::getPropertyWithValue(const String& key, String& value, String child = "") const { - return this.getPropertyWithValue(key..c_str(), value.c_str(), child.c_str()); -} +bool JSONVar::hasPropertyEqual(const char* key, const JSONVar& value) const { + return this->hasPropertyEqual(key, (const char*)value); +} //--------------------------------------------------------------------- -JSONVar JSONVar::getPropertyWithValue(const char* key, const char* value, const char* child = '') const { - if(this.hasOwnPropertyEqualTo(key, value)){ - if(this.hasOwnProperty(child)){ - return this[child]; - } - else { - return this; +bool JSONVar::hasPropertyEqual(const String& key, const String& value) const { + return this->hasPropertyEqual(key.c_str(), value.c_str()); +} + +//--------------------------------------------------------------------- + +bool JSONVar::hasPropertyEqual(const String& key, const JSONVar& value) const { + return this->hasPropertyEqual(key.c_str(), (const char*)value); +} + +//--------------------------------------------------------------------- + +JSONVar JSONVar::filter(const char* key, const char* value) const { + cJSON* item; + cJSON* test; + cJSON* json = cJSON_CreateArray(); + + if(JSONVar::typeof_((*this)) != "array"){ + test = cJSON_GetObjectItemCaseSensitive(_json, key); + if(test != NULL && strcmp(value, test->valuestring) == 0){ + cJSON_AddItemToArray(json, _json); } + return JSONVar(json, _json); } - - if(JSON.typeof_(this) == "array"){ - for (int i = 0; i < this.length(); ++i) { - if(this.hasPropertyEqualTo(key, value)){ - if(this[i].hasOwnProperty(child)){ - return this[i][child]; - } - else { - return this[i]; - } - } + + for (int i = 0; i < cJSON_GetArraySize(_json); ++i) { + item = cJSON_GetArrayItem(_json, i); + if (item == NULL) { + continue; + } + + test = cJSON_GetObjectItemCaseSensitive(item, key); + + if(test != NULL && strcmp(value, test->valuestring) == 0){ + cJSON_AddItemToArray(json, item); } } - return null; + return JSONVar(json, _json); +} + +JSONVar JSONVar::filter(const char* key, const JSONVar& value) const { + return this->filter(key, (const char*)value); +} + +JSONVar JSONVar::filter(const String& key, const String& value) const { + return this->filter(key.c_str(), value.c_str()); +} + +JSONVar JSONVar::filter(const String& key, const JSONVar& value) const { + return this->filter(key.c_str(), (const char*)value); } JSONVar undefined; diff --git a/src/JSONVar.h b/src/JSONVar.h index e6b16b4..5e14588 100644 --- a/src/JSONVar.h +++ b/src/JSONVar.h @@ -71,18 +71,22 @@ class JSONVar : public Printable { JSONVar operator[](const char* key); JSONVar operator[](const String& key); JSONVar operator[](int index); - JSONVar operator[](const JSONVar& key); + JSONVar operator[](const JSONVar& key); int length() const; JSONVar keys() const; bool hasOwnProperty(const char* key) const; bool hasOwnProperty(const String& key) const; - bool haPropertyEqualTo(const String& key, String& value) const; - bool hasPropertyEqualTo(const char* key, const char* value) const; - - JSONVar getPropertyWithValue(const String& key, String& value, String child = "") const; - JSONVar getPropertyWithValue(const char* key, const char* value, const char* child = '') const; + bool hasPropertyEqual(const char* key, const char* value) const; + bool hasPropertyEqual(const char* key, const JSONVar& value) const; + bool hasPropertyEqual(const String& key, const String& value) const; + bool hasPropertyEqual(const String& key, const JSONVar& value) const; + + JSONVar filter(const char* key, const char* value) const; + JSONVar filter(const char* key, const JSONVar& value) const; + JSONVar filter(const String& key, const String& value) const; + JSONVar filter(const String& key, const JSONVar& value) const; static JSONVar parse(const char* s); static JSONVar parse(const String& s); From 7ab7c5af463d2c0e7131f79f11fc21c0a8b84695 Mon Sep 17 00:00:00 2001 From: Joe Andolina Date: Fri, 4 Mar 2022 09:44:19 -0800 Subject: [PATCH 4/5] Added cJSON_Duplicate to found items. --- src/JSONVar.cpp | 79 ++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 72 insertions(+), 7 deletions(-) diff --git a/src/JSONVar.cpp b/src/JSONVar.cpp index 39a6fa5..e799b36 100644 --- a/src/JSONVar.cpp +++ b/src/JSONVar.cpp @@ -445,32 +445,97 @@ bool JSONVar::hasPropertyEqual(const String& key, const JSONVar& value) const //--------------------------------------------------------------------- +// JSONVar JSONVar::filter(const char* key, const char* value) const { +// JSONVar item; +// cJSON* test; +// cJSON* json = cJSON_CreateArray(); + +// Serial.printf("JSONVar::filter - %s == %s\n", key, value); + +// // if(!cJSON_IsArray(_json)){ +// // // target = cJSON_CreateArray(); +// // // cJSON_AddItemToArray(target, _json); +// // return (*this); +// // } + +// // Serial.printf("JSON SIZE %d", cJSON_GetArraySize(_json)); + +// Serial.printf("This an array %d\n", (*this).length()); + +// for (int i = 0; i < (*this).length(); i++) { +// Serial.println("GettingItem"); +// item = this[(int)i]; +// Serial.println(item); +// Serial.println(item[(const char*)key]); +// Serial.println("GotItem"); + +// // Serial.println("Loop " + String(i)); +// // Serial.println(this->operator[](i));//cJSON_GetArrayItem(_json, i); + +// // if (item == NULL) { +// // Serial.println("Loop Null"); +// // continue; +// // } + +// if(item.hasPropertyEqual(key, value)){ +// Serial.println("Got Match"); +// return item; +// } +// else { +// Serial.println("NO Match"); +// } +// } + + // if(cJSON_GetArraySize(json) == 0){ + // Serial.println("Returning Null"); + // return NULL; + // } + // else if(cJSON_GetArraySize(json) == 1){ + // Serial.println("Returning Single"); + // return JSONVar(cJSON_GetArrayItem(json, 0), (*this)._json); + // } + + // // Serial.println("Returning Array"); +// return JSONVar(); +// } + JSONVar JSONVar::filter(const char* key, const char* value) const { cJSON* item; cJSON* test; cJSON* json = cJSON_CreateArray(); - if(JSONVar::typeof_((*this)) != "array"){ - test = cJSON_GetObjectItemCaseSensitive(_json, key); + Serial.printf("JSONVar::filter - %s == %s\n", key, value); + + if(!cJSON_IsArray(_json)){ + test = cJSON_GetObjectItem(_json, key); + if(test != NULL && strcmp(value, test->valuestring) == 0){ - cJSON_AddItemToArray(json, _json); + return JSONVar(cJSON_Duplicate(item,true), _json); } - return JSONVar(json, _json); } - for (int i = 0; i < cJSON_GetArraySize(_json); ++i) { + for (int i = 0; i < cJSON_GetArraySize(_json); i++) { item = cJSON_GetArrayItem(_json, i); + if (item == NULL) { continue; } - test = cJSON_GetObjectItemCaseSensitive(item, key); + test = cJSON_GetObjectItem(item, key); if(test != NULL && strcmp(value, test->valuestring) == 0){ - cJSON_AddItemToArray(json, item); + cJSON_AddItemToArray(json, cJSON_Duplicate(item,true)); } } + if(cJSON_GetArraySize(json) == 0){ + return JSONVar(NULL, NULL); + } + + if(cJSON_GetArraySize(json) == 1){ + return JSONVar(cJSON_GetArrayItem(json, 0), _json); + } + return JSONVar(json, _json); } From 607acab3f2195a9fb97b4d0986a6c06582e3c73c Mon Sep 17 00:00:00 2001 From: Joe Andolina Date: Fri, 4 Mar 2022 10:06:24 -0800 Subject: [PATCH 5/5] Updated the object filter implementation --- src/JSONVar.cpp | 63 ++----------------------------------------------- 1 file changed, 2 insertions(+), 61 deletions(-) diff --git a/src/JSONVar.cpp b/src/JSONVar.cpp index e799b36..60dc0d8 100644 --- a/src/JSONVar.cpp +++ b/src/JSONVar.cpp @@ -414,14 +414,11 @@ void JSONVar::replaceJson(struct cJSON* json) //--------------------------------------------------------------------- bool JSONVar::hasPropertyEqual(const char* key, const char* value) const { - // Serial.printf("JSONVar::hasPropertyEqual - %s == %s\n", key, value); - if (!cJSON_IsObject(_json)) { return false; } cJSON* json = cJSON_GetObjectItemCaseSensitive(_json, key); - // Serial.printf("JSONVar::hasPropertyEqual - Found %s\n", json->valuestring); return json != NULL && strcmp(value, json->valuestring) == 0; } @@ -445,72 +442,16 @@ bool JSONVar::hasPropertyEqual(const String& key, const JSONVar& value) const //--------------------------------------------------------------------- -// JSONVar JSONVar::filter(const char* key, const char* value) const { -// JSONVar item; -// cJSON* test; -// cJSON* json = cJSON_CreateArray(); - -// Serial.printf("JSONVar::filter - %s == %s\n", key, value); - -// // if(!cJSON_IsArray(_json)){ -// // // target = cJSON_CreateArray(); -// // // cJSON_AddItemToArray(target, _json); -// // return (*this); -// // } - -// // Serial.printf("JSON SIZE %d", cJSON_GetArraySize(_json)); - -// Serial.printf("This an array %d\n", (*this).length()); - -// for (int i = 0; i < (*this).length(); i++) { -// Serial.println("GettingItem"); -// item = this[(int)i]; -// Serial.println(item); -// Serial.println(item[(const char*)key]); -// Serial.println("GotItem"); - -// // Serial.println("Loop " + String(i)); -// // Serial.println(this->operator[](i));//cJSON_GetArrayItem(_json, i); - -// // if (item == NULL) { -// // Serial.println("Loop Null"); -// // continue; -// // } - -// if(item.hasPropertyEqual(key, value)){ -// Serial.println("Got Match"); -// return item; -// } -// else { -// Serial.println("NO Match"); -// } -// } - - // if(cJSON_GetArraySize(json) == 0){ - // Serial.println("Returning Null"); - // return NULL; - // } - // else if(cJSON_GetArraySize(json) == 1){ - // Serial.println("Returning Single"); - // return JSONVar(cJSON_GetArrayItem(json, 0), (*this)._json); - // } - - // // Serial.println("Returning Array"); -// return JSONVar(); -// } - JSONVar JSONVar::filter(const char* key, const char* value) const { cJSON* item; cJSON* test; cJSON* json = cJSON_CreateArray(); - Serial.printf("JSONVar::filter - %s == %s\n", key, value); - - if(!cJSON_IsArray(_json)){ + if(cJSON_IsObject(_json)){ test = cJSON_GetObjectItem(_json, key); if(test != NULL && strcmp(value, test->valuestring) == 0){ - return JSONVar(cJSON_Duplicate(item,true), _json); + return (*this); } }