Skip to content

Commit

Permalink
Add functions to serialize and deserialize arrays
Browse files Browse the repository at this point in the history
  • Loading branch information
brunexgeek committed Apr 28, 2024
1 parent 610d1f3 commit 97de93a
Show file tree
Hide file tree
Showing 2 changed files with 150 additions and 0 deletions.
80 changes: 80 additions & 0 deletions source/cpp/json.hh
Original file line number Diff line number Diff line change
Expand Up @@ -415,6 +415,86 @@ void clear( T &value ) { json<T>::clear(value); }
template<typename T, typename J = protogen_X_Y_Z::json<T>>
bool empty( const T &value ) { return json<T>::empty(value); }

//
// Deserialization of arrays
//

template<typename T, typename std::enable_if<is_container<T>::value, int>::type = 0>
bool deserialize_array( T& container, protogen_X_Y_Z::istream& in, protogen_X_Y_Z::Parameters *params = nullptr )
{
protogen_X_Y_Z::json_context ctx;
if (params != nullptr) {
params->error.clear();
ctx.params = *params;
}
protogen_X_Y_Z::tokenizer tok(in, ctx.params);
ctx.tok = &tok;
int result = json<T>::read(ctx, container);
if (result == protogen_X_Y_Z::PGR_OK) return true;
if (params != nullptr) params->error = std::move(ctx.params.error);
return false;
}

template<typename T, typename std::enable_if<is_container<T>::value, int>::type = 0>
bool deserialize_array( T& container, const std::string &in, Parameters *params = nullptr )
{
iterator_istream<std::string::const_iterator> is(in.begin(), in.end());
return deserialize_array(container, is, params);
}

template<typename T, typename std::enable_if<is_container<T>::value, int>::type = 0>
bool deserialize_array( T& container, const char *in, size_t len, Parameters *params = nullptr )
{
auto begin = mem_iterator<char>(in, len);
auto end = mem_iterator<char>(in + len, 0);
iterator_istream<mem_iterator<char>> is(begin, end);
return deserialize_array(container, is, params);
}

template<typename T, typename std::enable_if<is_container<T>::value, int>::type = 0>
bool deserialize_array( T& container, const std::vector<char> &in, Parameters *params = nullptr )
{
iterator_istream<std::vector<char>::const_iterator> is(in.begin(), in.end());
return deserialize_array(container, is, params);
}

//
// Serialization of arrays
//

template<typename T, typename std::enable_if<is_container<T>::value, int>::type = 0>
bool serialize_array( const T& container, protogen_X_Y_Z::ostream &out, protogen_X_Y_Z::Parameters *params = nullptr )
{
protogen_X_Y_Z::json_context ctx;
ctx.os = &out;
if (params != nullptr) {
params->error.clear();
ctx.params = *params;
}
int result = json<T>::write(ctx, container);
if (result == protogen_X_Y_Z::PGR_OK) return true;
if (params != nullptr) params->error = std::move(ctx.params.error);
return false;
}

template<typename T, typename std::enable_if<is_container<T>::value, int>::type = 0>
bool serialize_array( const T& container, std::string &out, Parameters *params = nullptr )
{
typedef std::back_insert_iterator<std::string> ittype;
ittype begin(out);
iterator_ostream<ittype> os(begin);
return serialize_array(container, os, params);
}

template<typename T, typename std::enable_if<is_container<T>::value, int>::type = 0>
bool serialize_array( const T& container, std::vector<char> &out, Parameters *params = nullptr )
{
typedef std::back_insert_iterator<std::vector<char>> ittype;
ittype begin(out);
iterator_ostream<ittype> os(begin);
return serialize_array(container, os, params);
}

#define PG_X_Y_Z_ENTITY(N,O,S) \
struct N : public O, public protogen_X_Y_Z::message< O, S > \
{ \
Expand Down
70 changes: 70 additions & 0 deletions tests/tests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -384,6 +384,74 @@ bool RUN_TEST8( int argc, char **argv)
return true;
}

bool RUN_TEST9( int argc, char **argv)
{
(void) argc;
(void) argv;

std::list<phonebook::Person> people;
for (int i = 0; i < 5; ++i)
{
phonebook::Person person;
person.email = "[email protected]";
person.id = 1234 + i;
person.name = "Person " + std::to_string(i);
people.push_back(std::move(person));
}

std::string json1;
protogen_3_0_0::serialize_array(people, json1);

people.clear();
auto result = protogen_3_0_0::deserialize_array(people, json1);
std::string json2;
protogen_3_0_0::serialize_array(people, json2);

if (!result || json1 != json2)
{
std::cerr << "[TEST #9] Failed!" << std::endl;
std::cerr << " " << json1 << '\n';
std::cerr << " " << json2 << '\n';
return false;
}
else
{
std::cerr << "[TEST #9] Passed!" << std::endl;
std::cerr << " " << json1 << '\n';
return true;
}
}

bool RUN_TEST10( int argc, char **argv)
{
(void) argc;
(void) argv;

std::list<phonebook::Person> people;

std::string json1;
std::vector<char> json2;

if (!protogen_3_0_0::serialize_array(people, json1))
goto FAILED;
//if (!protogen_3_0_0::deserialize_array(people, json1.c_str(), json1.length()))
// goto FAILED;
if (!protogen_3_0_0::deserialize_array(people, json1))
goto FAILED;

if (!protogen_3_0_0::serialize_array(people, json2))
goto FAILED;
if (!protogen_3_0_0::deserialize_array(people, json2))
goto FAILED;

std::cerr << "[TEST #10] Passed!" << std::endl;
return true;

FAILED:
std::cerr << "[TEST #10] Failed!" << std::endl;
return false;
}

int main( int argc, char **argv)
{
bool result = true;
Expand All @@ -395,5 +463,7 @@ int main( int argc, char **argv)
result &= RUN_TEST7A(argc, argv);
result &= RUN_TEST7B(argc, argv);
result &= RUN_TEST8(argc, argv);
result &= RUN_TEST9(argc, argv);
result &= RUN_TEST10(argc, argv);
return (int) !result;
}

0 comments on commit 97de93a

Please sign in to comment.