/* 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; } }