/* This file is part of MAUS: http://micewww.pp.rl.ac.uk/projects/maus
*
* MAUS is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* MAUS is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with MAUS. If not, see .
*/
#include
#include
#include "src/common_cpp/Utils/JsonWrapper.hh"
#include "src/common_cpp/JsonCppProcessors/Common/ReferenceResolverCppToJson.hh"
#include "src/common_cpp/JsonCppProcessors/Common/ReferenceResolverJsonToCpp.hh"
namespace MAUS {
template
PointerArrayProcessor::PointerArrayProcessor
(ProcessorBase* contents_processor)
: _proc(contents_processor) {
}
template
PointerArrayProcessor::~PointerArrayProcessor() {
if (_proc != NULL) {
delete _proc;
_proc = NULL;
}
}
template
std::vector* PointerArrayProcessor::JsonToCpp
(const Json::Value& json_array) {
if (!json_array.isConvertibleTo(Json::arrayValue)) {
// no memory allocated yet...
throw(Exception(Exception::recoverable,
"Failed to resolve Json::Value of type "+
JsonWrapper::ValueTypeToString(json_array.type())+
" to array",
"PointerArrayProcessor::JsonToCpp()"
) );
}
std::vector* vec = new std::vector(json_array.size());
for (size_t i = 0; i < json_array.size(); ++i) {
try {
// allocate the vector
if (json_array[Json::Value::ArrayIndex(i)].type() == Json::nullValue) {
(*vec)[i] = NULL;
} else {
ArrayContents* data = _proc->JsonToCpp(
json_array[Json::Value::ArrayIndex(i)]);
(*vec)[i] = data;
using ReferenceResolver::JsonToCpp::RefManager;
std::string path = JsonWrapper::Path::GetPath(
json_array[Json::Value::ArrayIndex(i)]);
if (RefManager::HasInstance())
RefManager::GetInstance().SetPointerAsValue(path, (*vec)[i]);
}
} catch (Exception exc) {
// if there's a problem, clean up before rethrowing the exception
for (size_t j = 0; j < vec->size(); ++j) {
if ((*vec)[j] != NULL) {
delete (*vec)[j];
}
}
delete vec;
throw exc;
}
}
return vec;
}
template
Json::Value* PointerArrayProcessor::
CppToJson(const std::vector& cpp_array) {
return CppToJson(cpp_array, "");
}
template
Json::Value* PointerArrayProcessor::
CppToJson(const std::vector& cpp_array,
std::string path) {
Json::Value* json_array = new Json::Value(Json::arrayValue);
JsonWrapper::Path::SetPath(*json_array, path);
json_array->resize(cpp_array.size());
for (size_t i = 0; i < cpp_array.size(); ++i) {
try {
Json::Value* data = NULL;
if (cpp_array[i] == NULL) {
data = new Json::Value(); // that is a NULL value
} else {
data = _proc->CppToJson(*cpp_array[i], GetPath(path, i));
}
// json copies memory here but not path
(*json_array)[Json::Value::ArrayIndex(i)] = *data;
JsonWrapper::Path::SetPath((*json_array)[Json::Value::ArrayIndex(i)],
GetPath(path, i));
delete data; // so we need to clean up here
using ReferenceResolver::CppToJson::RefManager;
if (RefManager::HasInstance())
RefManager::GetInstance().SetPointerAsValue
(cpp_array[i], GetPath(path, i));
} catch (Exception exc) {
// if there's a problem, clean up before rethrowing the exception
delete json_array;
throw exc;
}
}
return json_array;
}
template
std::string PointerArrayProcessor::GetPath
(std::string path, size_t index) {
return path+"/"+STLUtils::ToString(index);
}
///////////
template
ValueArrayProcessor::ValueArrayProcessor
(ProcessorBase* contents_processor)
: _proc(contents_processor) {
}
template
ValueArrayProcessor::~ValueArrayProcessor() {
if (_proc != NULL) {
delete _proc;
_proc = NULL;
}
}
template
std::vector* ValueArrayProcessor::JsonToCpp
(const Json::Value& json_array) {
if (!json_array.isConvertibleTo(Json::arrayValue)) {
// no memory allocated yet...
throw(Exception(Exception::recoverable,
"Failed to resolve Json::Value of type "+
JsonWrapper::ValueTypeToString(json_array.type())+
" to array",
"ValueArrayProcessor::JsonToCpp()"
) );
}
std::vector* vec
= new std::vector(json_array.size());
for (size_t i = 0; i < json_array.size(); ++i) {
try {
// allocate the vector
ArrayContents* data = _proc->JsonToCpp(json_array[
Json::Value::ArrayIndex(i)]);
(*vec)[i] = *data;
delete data;
} catch (Exception exc) {
// if there's a problem, clean up before rethrowing the exception
delete vec;
throw exc;
}
}
return vec;
}
template
Json::Value* ValueArrayProcessor::
CppToJson(const std::vector& cpp_array) {
return CppToJson(cpp_array, "");
}
template
Json::Value* ValueArrayProcessor::
CppToJson(const std::vector& cpp_array,
std::string path) {
Json::Value* json_array = new Json::Value(Json::arrayValue);
JsonWrapper::Path::SetPath(*json_array, path);
json_array->resize(cpp_array.size());
for (size_t i = 0; i < cpp_array.size(); ++i) {
try {
Json::Value* data = _proc->CppToJson(cpp_array[i],
GetPath(path, i));
(*json_array)[Json::Value::ArrayIndex(i)] = *data; // json copies memory but not path
JsonWrapper::Path::SetPath((*json_array)[Json::Value::ArrayIndex(i)],
GetPath(path, i));
delete data; // so we need to clean up here
} catch (Exception exc) {
// if there's a problem, clean up before rethrowing the exception
delete json_array;
throw exc;
}
}
return json_array;
}
template
std::string ValueArrayProcessor::GetPath
(std::string path, size_t index) {
return path+"/"+STLUtils::ToString(index);
}
////////////////////////////
template
std::vector* ReferenceArrayProcessor::JsonToCpp
(const Json::Value& json_array) {
using ReferenceResolver::JsonToCpp::RefManager;
using ReferenceResolver::JsonToCpp::VectorResolver;
if (!json_array.isConvertibleTo(Json::arrayValue)) {
// no memory allocated yet...
throw(Exception(Exception::recoverable,
"Failed to resolve Json::Value of type "+
JsonWrapper::ValueTypeToString(json_array.type())+
" to array",
"ValueArrayProcessor::JsonToCpp()"
) );
}
std::vector* vec
= new std::vector(json_array.size(), NULL);
for (size_t i = 0; i < json_array.size(); ++i) {
try {
(*vec)[i] = NULL;
if (json_array[Json::Value::ArrayIndex(i)].type() != Json::nullValue) {
std::string data_path = JsonWrapper::GetProperty
(json_array[Json::Value::ArrayIndex(i)],
"$ref",
JsonWrapper::stringValue).asString();
// allocate the vector
if (RefManager::HasInstance()) {
VectorResolver* res =
new VectorResolver(data_path, vec, i);
RefManager::GetInstance().AddReference(res);
}
}
} catch (Exception exc) {
// if there's a problem, clean up before rethrowing the exception
delete vec;
throw exc;
}
}
return vec;
}
template
Json::Value* ReferenceArrayProcessor::CppToJson(
const std::vector& cpp_array,
std::string path) {
using ReferenceResolver::CppToJson::RefManager;
using ReferenceResolver::CppToJson::TypedResolver;
Json::Value* array = new Json::Value(Json::arrayValue);
JsonWrapper::Path::SetPath(*array, path);
array->resize(cpp_array.size());
for (size_t i = 0; i < cpp_array.size(); ++i) {
(*array)[Json::Value::ArrayIndex(i)] = Json::Value();
if (cpp_array[Json::Value::ArrayIndex(i)] != NULL) {
JsonWrapper::Path::SetPath((*array)[Json::Value::ArrayIndex(i)], path);
JsonWrapper::Path::AppendPath((*array)[Json::Value::ArrayIndex(i)], i);
if (RefManager::HasInstance()) {
std::string arr_path = JsonWrapper::Path::GetPath(
(*array)[Json::Value::ArrayIndex(i)]);
TypedResolver* res = new TypedResolver
(cpp_array[i], arr_path);
RefManager::GetInstance().AddReference(res);
}
}
}
return array;
}
}