-
Notifications
You must be signed in to change notification settings - Fork 196
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
New Command 2055 - Process JSON Code
- Loading branch information
Showing
5 changed files
with
215 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,159 @@ | ||
#include "Json_Helper.h" | ||
#include "external/picojson.h" | ||
#include "output.h" | ||
#include <vector> | ||
|
||
namespace Json_Helper { | ||
const std::string kInvalidOutput = "<<INVALID_OUTPUT>>"; | ||
|
||
std::vector<std::string> SplitPath(const std::string& jsonPath) { | ||
std::istringstream iss(jsonPath); | ||
std::vector<std::string> pathParts; | ||
std::string part; | ||
while (std::getline(iss, part, '.')) { | ||
pathParts.push_back(part); | ||
} | ||
return pathParts; | ||
} | ||
|
||
picojson::value* GetValuePointer(picojson::value& jsonValue, const std::vector<std::string>& pathParts, bool allowCreation) { | ||
picojson::value* currentValue = &jsonValue; | ||
|
||
for (const auto& part : pathParts) { | ||
std::string arrayName; | ||
int arrayIndex = -1; | ||
bool inArray = false; | ||
|
||
for (char c : part) { | ||
if (!inArray) { | ||
if (c == '[') { | ||
inArray = true; | ||
arrayIndex = 0; | ||
} | ||
else { | ||
arrayName += c; | ||
} | ||
} | ||
else { | ||
if (c == ']') { | ||
break; | ||
} | ||
else { | ||
arrayIndex = arrayIndex * 10 + (c - '0'); | ||
} | ||
} | ||
} | ||
|
||
if (inArray) { | ||
if (!currentValue->is<picojson::object>()) { | ||
if (allowCreation) { | ||
*currentValue = picojson::value(picojson::object()); | ||
} | ||
else { | ||
Output::Warning("JSON_ERROR - Invalid JSON type for array: {}", arrayName); | ||
return nullptr; | ||
} | ||
} | ||
|
||
auto& obj = currentValue->get<picojson::object>(); | ||
auto arrayIt = obj.find(arrayName); | ||
|
||
if (arrayIt == obj.end()) { | ||
if (allowCreation) { | ||
obj.emplace(arrayName, picojson::value(picojson::array())); | ||
arrayIt = obj.find(arrayName); | ||
} | ||
else { | ||
Output::Warning("JSON_ERROR - Array not found: {}", arrayName); | ||
return nullptr; | ||
} | ||
} | ||
|
||
auto& arr = arrayIt->second.get<picojson::array>(); | ||
|
||
if (arrayIndex >= static_cast<int>(arr.size())) { | ||
if (allowCreation) { | ||
arr.resize(arrayIndex + 1); | ||
} | ||
else { | ||
Output::Warning("JSON_ERROR - Array index out of bounds: {}", part); | ||
return nullptr; | ||
} | ||
} | ||
|
||
currentValue = &arr[arrayIndex]; | ||
} | ||
else { | ||
if (!currentValue->is<picojson::object>()) { | ||
if (allowCreation) { | ||
*currentValue = picojson::value(picojson::object()); | ||
} | ||
else { | ||
Output::Warning("JSON_ERROR - Invalid JSON type for path: {}", part); | ||
return nullptr; | ||
} | ||
} | ||
|
||
auto& obj = currentValue->get<picojson::object>(); | ||
auto objIt = obj.find(arrayName); | ||
|
||
if (objIt == obj.end()) { | ||
if (allowCreation) { | ||
obj.emplace(arrayName, picojson::value(picojson::object())); | ||
objIt = obj.find(arrayName); | ||
} | ||
else { | ||
Output::Warning("JSON_ERROR - Object key not found: {}", part); | ||
return nullptr; | ||
} | ||
} | ||
|
||
currentValue = &objIt->second; | ||
} | ||
} | ||
|
||
return currentValue; | ||
} | ||
|
||
std::string GetValue(const std::string& jsonData, const std::string& jsonPath) { | ||
picojson::value jsonValue; | ||
std::string err = picojson::parse(jsonValue, jsonData); | ||
|
||
if (!err.empty()) { | ||
Output::Warning("JSON_ERROR - JSON parsing error: {}", err); | ||
return kInvalidOutput; | ||
} | ||
|
||
auto pathParts = SplitPath(jsonPath); | ||
auto valuePtr = GetValuePointer(jsonValue, pathParts, false); | ||
|
||
if (valuePtr == nullptr || !valuePtr->is<std::string>()) { | ||
Output::Warning("JSON_ERROR - Value not found or not a string"); | ||
return kInvalidOutput; | ||
} | ||
|
||
return valuePtr->get<std::string>(); | ||
} | ||
|
||
std::string SetValue(const std::string& jsonData, const std::string& jsonPath, const std::string& value) { | ||
picojson::value jsonValue; | ||
std::string err = picojson::parse(jsonValue, jsonData); | ||
|
||
if (!err.empty()) { | ||
Output::Warning("JSON_ERROR - JSON parsing error: {}", err); | ||
return kInvalidOutput; | ||
} | ||
|
||
auto pathParts = SplitPath(jsonPath); | ||
auto valuePtr = GetValuePointer(jsonValue, pathParts, true); | ||
|
||
if (valuePtr == nullptr) { | ||
Output::Warning("JSON_ERROR - Unable to create value"); | ||
return kInvalidOutput; | ||
} | ||
|
||
*valuePtr = picojson::value(value); | ||
|
||
return picojson::value(jsonValue).serialize(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
#ifndef JSON_HELPER_H | ||
#define JSON_HELPER_H | ||
|
||
#include <string> | ||
|
||
namespace Json_Helper { | ||
std::string GetValue(const std::string& jsonData, const std::string& jsonPath); | ||
std::string SetValue(const std::string& jsonData, const std::string& jsonPath, const std::string& value); | ||
} | ||
|
||
#endif // JSON_HELPER_H |