Skip to content

Commit

Permalink
Added JSONUtils::updatePointer
Browse files Browse the repository at this point in the history
  • Loading branch information
FigBug committed Nov 19, 2024
1 parent 6e20e3f commit f7d86f1
Show file tree
Hide file tree
Showing 2 changed files with 80 additions and 0 deletions.
68 changes: 68 additions & 0 deletions modules/juce_core/json/juce_JSONUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,74 @@ std::optional<var> JSONUtils::setPointer (const var& v,
return {};
}

bool JSONUtils::updatePointer (var& v, String pointer, const var& newValue)
{
if (pointer.isEmpty())
return false;

if (! pointer.startsWith ("/"))
{
// This is not a well-formed JSON pointer
jassertfalse;
return {};
}

const auto findResult = pointer.indexOfChar (1, '/');
const auto pos = findResult < 0 ? pointer.length() : findResult;
const String head (pointer.begin() + 1, pointer.begin() + pos);
const String tail (pointer.begin() + pos, pointer.end());

const auto unescaped = head.replace ("~1", "/").replace ("~0", "~");

if (auto* object = v.getDynamicObject())
{
if (tail.isEmpty())
{
object->setProperty (unescaped, newValue);
return true;
}

auto v = object->getProperty (unescaped);
return updatePointer (v, tail, newValue);
}
else if (auto* array = v.getArray())
{
const auto index = [&]() -> size_t
{
if (unescaped == "-")
return (size_t) array->size();

if (unescaped == "0")
return 0;

if (! unescaped.startsWith ("0"))
return (size_t) unescaped.getLargeIntValue();

return std::numeric_limits<size_t>::max();
}();

if (tail.isEmpty())
{
if (isPositiveAndBelow (index, array->size()))
{
array->set (int (index), newValue);
return true;
}

if (index == array->size())
{
array->add (newValue);
return true;
}
}

auto v = (*array)[(int) index];
return updatePointer (v, tail, newValue);
}

return false;
}

var JSONUtils::getPointer (const var& v, String pointer, const var& defaultValue)
{
if (pointer.isEmpty())
Expand Down
12 changes: 12 additions & 0 deletions modules/juce_core/json/juce_JSONUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,18 @@ struct JSONUtils
*/
static std::optional<var> setPointer (const var& v, String pointer, const var& newValue);

/** Given a JSON array/object 'v', a string representing a JSON pointer,
and a new property value 'newValue', updates 'v' where the
property or array index referenced by the pointer has been set to 'newValue'.
If the pointer cannot be followed, due to referencing missing array indices
or fields, then this returns false.
For more details, check the JSON Pointer RFC 6901:
https://datatracker.ietf.org/doc/html/rfc6901
*/
static bool updatePointer (var& v, String pointer, const var& newValue);

/** Given a JSON array/object 'v', a string representing a JSON pointer,
returns the value of the property or array index referenced by the pointer
Expand Down

0 comments on commit f7d86f1

Please sign in to comment.