// SPDX-FileCopyrightText: Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen // SPDX-License-Identifier: BSD-3-Clause #include "vtkCommand.h" #include "vtkDeserializer.h" #include "vtkInformation.h" #include "vtkInformationDataObjectKey.h" #include "vtkInformationDoubleKey.h" #include "vtkInformationDoubleVectorKey.h" #include "vtkInformationIdTypeKey.h" #include "vtkInformationInformationKey.h" #include "vtkInformationInformationVectorKey.h" #include "vtkInformationIntegerKey.h" #include "vtkInformationIntegerPointerKey.h" #include "vtkInformationIntegerVectorKey.h" #include "vtkInformationIterator.h" #include "vtkInformationKey.h" #include "vtkInformationKeyLookup.h" #include "vtkInformationKeyVectorKey.h" #include "vtkInformationObjectBaseKey.h" #include "vtkInformationObjectBaseVectorKey.h" #include "vtkInformationStringKey.h" #include "vtkInformationStringVectorKey.h" #include "vtkInformationUnsignedLongKey.h" #include "vtkInformationVariantKey.h" #include "vtkInformationVariantVectorKey.h" #include "vtkInformationVector.h" #include "vtkIntArray.h" #include "vtkObjectBase.h" #include "vtkSerializer.h" #include "vtkVariantSerDesHelper.h" // clang-format off #include "vtk_nlohmannjson.h" #include #include VTK_NLOHMANN_JSON(json.hpp) // clang-format on extern "C" { /** * Register the (de)serialization handlers of vtkInformation * @param ser a vtkSerializer instance * @param deser a vtkDeserializer instance */ int RegisterHandlers_vtkInformationSerDesHelper(void* ser, void* deser, void* invoker); } static nlohmann::json Serialize_vtkInformation(vtkObjectBase* object, vtkSerializer* serializer) { using json = nlohmann::json; json state; auto* information = vtkInformation::SafeDownCast(object); if (auto f = serializer->GetHandler(typeid(vtkInformation::Superclass))) { state = f(object, serializer); } state["SuperClassNames"].push_back("vtkObject"); vtkNew iter; iter->SetInformation(information); iter->InitTraversal(); auto& dst = state["Keys"] = json::array(); while (!iter->IsDoneWithTraversal()) { json keyState; vtkInformationKey* key = iter->GetCurrentKey(); keyState["Name"] = key->GetName(); keyState["Location"] = key->GetLocation(); // keyState["ClassName"] = key->GetClassName(); if (key->IsA("vtkInformationStringKey")) { keyState["Value"] = information->Get(static_cast(key)); } else if (key->IsA("vtkInformationIntegerKey")) { keyState["Value"] = information->Get(static_cast(key)); } else if (key->IsA("vtkInformationDoubleKey")) { keyState["Value"] = information->Get(static_cast(key)); } else if (key->IsA("vtkInformationIdTypeKey")) { keyState["Value"] = information->Get(static_cast(key)); } else if (key->IsA("vtkInformationUnsignedLongKey")) { keyState["Value"] = information->Get(static_cast(key)); } else if (key->IsA("vtkInformationVariantKey")) { const vtkVariant* variant = &information->Get(static_cast(key)); keyState["Value"] = Serialize_vtkVariant(variant, serializer); } else if (key->IsA("vtkInformationIntegerVectorKey")) { auto& valArray = keyState["Value"] = json::array(); int* ptr = information->Get(static_cast(key)); int length = information->Length(static_cast(key)); for (int i = 0; i < length; ++i) { valArray.push_back(ptr[i]); } } else if (key->IsA("vtkInformationStringVectorKey")) { auto& valArray = keyState["Value"] = json::array(); int length = information->Length(static_cast(key)); for (int i = 0; i < length; ++i) { valArray.push_back(information->Get(static_cast(key), i)); } } else if (key->IsA("vtkInformationIntegerPointerKey")) { auto& valArray = keyState["Value"] = json::array(); int* ptr = information->Get(static_cast(key)); int length = information->Length(static_cast(key)); for (int i = 0; i < length; ++i) { valArray.push_back(ptr[i]); } } else if (key->IsA("vtkInformationDoubleVectorKey")) { auto& valArray = keyState["Value"] = json::array(); double* ptr = information->Get(static_cast(key)); int length = information->Length(static_cast(key)); for (int i = 0; i < length; ++i) { valArray.push_back(ptr[i]); } } else if (key->IsA("vtkInformationVariantVectorKey")) { auto& valArray = keyState["Value"] = json::array(); const vtkVariant* ptr = information->Get(static_cast(key)); int length = information->Length(static_cast(key)); for (int i = 0; i < length; ++i) { valArray.push_back(Serialize_vtkVariant(&ptr[i], serializer)); } } else if (key->IsA("vtkInformationKeyVectorKey")) { auto& valArray = keyState["Value"] = json::array(); vtkInformationKey** ptr = information->Get(static_cast(key)); int length = information->Length(static_cast(key)); for (int i = 0; i < length; ++i) { json subkey; subkey["Name"] = ptr[i]->GetName(); subkey["Location"] = ptr[i]->GetLocation(); valArray.push_back(subkey); } } else if (key->IsA("vtkInformationInformationKey")) { keyState["Value"] = serializer->SerializeJSON( information->Get(static_cast(key))); } else if (key->IsA("vtkInformationInformationVectorKey")) { auto& valArray = keyState["Value"] = json::array(); vtkSmartPointer infoVector = information->Get(static_cast(key)); int length = infoVector->GetNumberOfInformationObjects(); for (int i = 0; i < length; ++i) { valArray.push_back(serializer->SerializeJSON(infoVector->GetInformationObject(i))); } } else if (key->IsA("vtkInformationObjectBaseKey")) { keyState["Value"] = serializer->SerializeJSON(information->Get(static_cast(key))); } else if (key->IsA("vtkInformationObjectBaseVectorKey")) { auto& valArray = keyState["Value"] = json::array(); int length = information->Length(static_cast(key)); for (int i = 0; i < length; ++i) { valArray.push_back(serializer->SerializeJSON( information->Get(static_cast(key), i))); } } else if (key->IsA("vtkInformationDataObjectKey")) { keyState["Value"] = serializer->SerializeJSON(reinterpret_cast( information->Get(static_cast(key)))); } dst.push_back(keyState); iter->GoToNextItem(); } return state; } static void Deserialize_vtkInformation( const nlohmann::json& state, vtkObjectBase* object, vtkDeserializer* deserializer) { auto* information = vtkInformation::SafeDownCast(object); if (auto f = deserializer->GetHandler(typeid(vtkInformation::Superclass))) { f(state, object, deserializer); } const auto* context = deserializer->GetContext(); for (const auto& keyState : state["Keys"]) { vtkInformationKey* key = vtkInformationKeyLookup::Find(keyState["Name"], keyState["Location"]); // std::string className = keyState["ClassName"]; if (key->IsA("vtkInformationStringKey")) { information->Set(static_cast(key), keyState["Value"]); } else if (key->IsA("vtkInformationIntegerKey")) { information->Set(static_cast(key), keyState["Value"]); } else if (key->IsA("vtkInformationDoubleKey")) { information->Set(static_cast(key), keyState["Value"]); } else if (key->IsA("vtkInformationIdTypeKey")) { information->Set(static_cast(key), keyState["Value"]); } else if (key->IsA("vtkInformationUnsignedLongKey")) { information->Set(static_cast(key), keyState["Value"]); } else if (key->IsA("vtkInformationVariantKey")) { vtkVariant variant; Deserialize_vtkVariant(keyState["Value"], &variant, deserializer); information->Set(static_cast(key), variant); } else if (key->IsA("vtkInformationIntegerVectorKey")) { std::vector vec = keyState["Value"]; information->Set(static_cast(key), vec.data(), static_cast(vec.size())); } else if (key->IsA("vtkInformationStringVectorKey")) { for (const std::string item : keyState["Value"]) { information->Append(static_cast(key), item); } } else if (key->IsA("vtkInformationIntegerPointerKey")) { int size = static_cast(keyState["Value"].size()); vtkNew arr; int* ptr = new int[size]; for (int i = 0; i < size; i++) { ptr[i] = keyState["Value"][i]; } arr->SetArray(ptr, size, 0); // Add observer to delete arr/free ptr when information is deleted arr->Register(information); information->AddObserver(vtkCommand::DeleteEvent, arr.GetPointer(), &vtkIntArray::Delete); information->Set(static_cast(key), ptr, size); } else if (key->IsA("vtkInformationDoubleVectorKey")) { std::vector vec = keyState["Value"]; information->Set( static_cast(key), vec.data(), static_cast(vec.size())); } else if (key->IsA("vtkInformationVariantVectorKey")) { for (const auto& item : keyState["Value"]) { vtkVariant variant; Deserialize_vtkVariant(item, &variant, deserializer); information->Append(static_cast(key), variant); } } else if (key->IsA("vtkInformationKeyVectorKey")) { for (const auto& item : keyState["Value"]) { auto obj = context->GetObjectAtId(item["Id"]); vtkInformationKey* subkey = vtkInformationKeyLookup::Find(item["Name"], item["Location"]); information->Append(static_cast(subkey), subkey); } } else if (key->IsA("vtkInformationInformationKey")) { auto obj = context->GetObjectAtId(keyState["Value"]["Id"]); deserializer->DeserializeJSON(keyState["Value"]["Id"], obj); information->Set( static_cast(key), vtkInformation::SafeDownCast(obj)); } else if (key->IsA("vtkInformationInformationVectorKey")) { vtkSmartPointer infoVec = vtkInformationVector::New(); information->Set(static_cast(key), infoVec); infoVec->UnRegister(nullptr); for (const auto& item : keyState["Value"]) { auto obj = context->GetObjectAtId(item["Id"]); deserializer->DeserializeJSON(item["Id"], obj); information->Get(static_cast(key)) ->Append(vtkInformation::SafeDownCast(obj)); } } else if (key->IsA("vtkInformationObjectBaseKey")) { vtkSmartPointer obj; deserializer->DeserializeJSON(keyState["Value"]["Id"], obj); information->Set(static_cast(key), obj); } else if (key->IsA("vtkInformationObjectBaseVectorKey")) { for (const auto& item : keyState["Value"]) { vtkSmartPointer obj; deserializer->DeserializeJSON(item["Id"], obj); information->Append(static_cast(key), obj); } } else if (key->IsA("vtkInformationDataObjectKey")) { auto obj = context->GetObjectAtId(keyState["Value"]["Id"]); deserializer->DeserializeJSON(keyState["Value"]["Id"], obj); information->Set(static_cast(key), reinterpret_cast(obj.GetPointer())); } } } int RegisterHandlers_vtkInformationSerDesHelper(void* ser, void* deser, void* vtkNotUsed(invoker)) { int success = 0; if (auto* asObjectBase = static_cast(ser)) { if (auto* serializer = vtkSerializer::SafeDownCast(asObjectBase)) { serializer->RegisterHandler(typeid(vtkInformation), Serialize_vtkInformation); success = 1; } } if (auto* asObjectBase = static_cast(deser)) { if (auto* deserializer = vtkDeserializer::SafeDownCast(asObjectBase)) { deserializer->RegisterHandler(typeid(vtkInformation), Deserialize_vtkInformation); deserializer->RegisterConstructor("vtkInformation", vtkInformation::New); success = 1; } } return success; }