summaryrefslogtreecommitdiffstats
path: root/library/cpp/json/writer/json_value.cpp
diff options
context:
space:
mode:
authorilnurkh <[email protected]>2025-09-21 17:27:52 +0300
committerilnurkh <[email protected]>2025-09-21 17:45:29 +0300
commitb8d4d45acc8974872dc28167f0b07d886b7bfe15 (patch)
tree5c04866ad5faefd4f4b582f5e55435ebc457ccc0 /library/cpp/json/writer/json_value.cpp
parentca3f87b02dc3b458e8f33f532eaaca1b9afcbe54 (diff)
implement appending `[]` and reverse-lookup `[-1]` in json *ByValue methods
commit_hash:27ed69b5a37eb0d58449fb062147aaeb67ec51ba
Diffstat (limited to 'library/cpp/json/writer/json_value.cpp')
-rw-r--r--library/cpp/json/writer/json_value.cpp21
1 files changed, 19 insertions, 2 deletions
diff --git a/library/cpp/json/writer/json_value.cpp b/library/cpp/json/writer/json_value.cpp
index 344a2cd1648..e71e9ce8199 100644
--- a/library/cpp/json/writer/json_value.cpp
+++ b/library/cpp/json/writer/json_value.cpp
@@ -825,7 +825,7 @@ namespace NJson {
template <class TPtr, class T>
TPtr* CreateOrNullptr(const TPtr* p, T key, std::false_type /*create*/) noexcept {
const TPtr* const next = &(*p)[key];
- return next->IsDefined() ? const_cast<TPtr*>(next) : nullptr;
+ return next->GetType() != JSON_UNDEFINED ? const_cast<TPtr*>(next) : nullptr;
}
template <bool Create, class TJsonPtr>
@@ -836,10 +836,27 @@ namespace NJson {
constexpr std::integral_constant<bool, Create> create_tag{};
while (!path.empty()) {
- size_t index = 0;
+ i64 index = 0;
const TStringBuf step = path.NextTok(delimiter);
if (step.size() > 2 && *step.begin() == '[' && step.back() == ']' && TryFromString(step.substr(1, step.size() - 2), index)) {
+ if (index < 0) {
+ if constexpr (Create) {
+ currentJson->SetType(JSON_ARRAY);
+ TJsonArray::TArray& dst = currentJson->GetArraySafe();
+ while (i64(dst.size()) < -index) {
+ dst.push_front({JSON_NULL});
+ }
+ }
+ index = i64(currentJson->GetArray().size()) - (-index);
+ }
+ if (index < 0) {
+ return nullptr;
+ }
currentJson = CreateOrNullptr(currentJson, index, create_tag);
+ } else if (Create && step == "[]") {
+ if constexpr (Create) {
+ currentJson = &currentJson->AppendValue({});
+ }
} else {
currentJson = CreateOrNullptr(currentJson, step, create_tag);
}