implemented deflatten function

This commit is contained in:
Niels 2016-04-16 20:45:40 +02:00
parent 007359675b
commit f834965b44
3 changed files with 177 additions and 2 deletions

View file

@ -8855,7 +8855,6 @@ basic_json_parser_63:
}
private:
/// return referenced value
reference get(reference j) const
{
pointer result = &j;
@ -8880,6 +8879,49 @@ basic_json_parser_63:
return *result;
}
reference get2(reference j) const
{
pointer result = &j;
for (const auto& reference_token : reference_tokens)
{
switch (result->m_type)
{
case value_t::null:
{
if (reference_token == "0")
{
result = &result->operator[](0);
}
else
{
result = &result->operator[](reference_token);
}
continue;
}
case value_t::object:
{
result = &result->operator[](reference_token);
continue;
}
case value_t::array:
{
result = &result->operator[](static_cast<size_t>(std::stoi(reference_token)));
continue;
}
default:
{
throw std::domain_error("unresolved reference token '" + reference_token + "'");
}
}
}
return *result;
}
const_reference get(const_reference j) const
{
const_pointer result = &j;
@ -9042,6 +9084,35 @@ basic_json_parser_63:
}
}
}
/*!
@param[in] value flattened JSON
@return deflattened JSON
*/
static basic_json deflatten(const basic_json& value)
{
if (not value.is_object())
{
throw std::domain_error("only objects can be deflattened");
}
basic_json result;
// iterate the JSON object values
for (const auto& element : *value.m_value.object)
{
if (not element.second.is_primitive())
{
throw std::domain_error("values in object must be primitive");
}
// assign value to reference pointed to by JSON pointer
json_pointer(element.first).get2(result) = element.second;
}
return result;
}
};
/*!
@ -9053,6 +9124,14 @@ basic_json_parser_63:
json_pointer::flatten("", *this, result);
return result;
}
/*!
@return the original JSON from a flattened version
*/
basic_json deflatten() const
{
return json_pointer::deflatten(*this);
}
};

View file

@ -8165,7 +8165,6 @@ class basic_json
}
private:
/// return referenced value
reference get(reference j) const
{
pointer result = &j;
@ -8190,6 +8189,49 @@ class basic_json
return *result;
}
reference get2(reference j) const
{
pointer result = &j;
for (const auto& reference_token : reference_tokens)
{
switch (result->m_type)
{
case value_t::null:
{
if (reference_token == "0")
{
result = &result->operator[](0);
}
else
{
result = &result->operator[](reference_token);
}
continue;
}
case value_t::object:
{
result = &result->operator[](reference_token);
continue;
}
case value_t::array:
{
result = &result->operator[](static_cast<size_t>(std::stoi(reference_token)));
continue;
}
default:
{
throw std::domain_error("unresolved reference token '" + reference_token + "'");
}
}
}
return *result;
}
const_reference get(const_reference j) const
{
const_pointer result = &j;
@ -8352,6 +8394,35 @@ class basic_json
}
}
}
/*!
@param[in] value flattened JSON
@return deflattened JSON
*/
static basic_json deflatten(const basic_json& value)
{
if (not value.is_object())
{
throw std::domain_error("only objects can be deflattened");
}
basic_json result;
// iterate the JSON object values
for (const auto& element : *value.m_value.object)
{
if (not element.second.is_primitive())
{
throw std::domain_error("values in object must be primitive");
}
// assign value to reference pointed to by JSON pointer
json_pointer(element.first).get2(result) = element.second;
}
return result;
}
};
/*!
@ -8363,6 +8434,14 @@ class basic_json
json_pointer::flatten("", *this, result);
return result;
}
/*!
@return the original JSON from a flattened version
*/
basic_json deflatten() const
{
return json_pointer::deflatten(*this);
}
};

View file

@ -12213,7 +12213,24 @@ TEST_CASE("JSON pointers")
{"/object/~01", "tilde1"}
};
// check if flattened result is as expected
CHECK(j.flatten() == j_flatten);
// check if deflattened result is as expected
CHECK(j_flatten.deflatten() == j);
// explicit roundtrip check
CHECK(j.flatten().deflatten() == j);
// roundtrip for primitive values
json j_null;
CHECK(j_null.flatten().deflatten() == j_null);
json j_number = 42;
CHECK(j_number.flatten().deflatten() == j_number);
json j_boolean = false;
CHECK(j_boolean.flatten().deflatten() == j_boolean);
json j_string = "foo";
CHECK(j_string.flatten().deflatten() == j_string);
}
}