summaryrefslogtreecommitdiff
path: root/view/sharedcache/core/MetadataSerializable.hpp
diff options
context:
space:
mode:
authorMark Rowe <mrowe@bdash.net.nz>2025-02-08 10:40:44 -0800
committerMason Reed <mason@vector35.com>2025-02-12 18:43:02 -0500
commitc20bf355152d9a715dae3c19777c3d4a1046174b (patch)
treeca54b22241c36bcfd8259c16b2583b9d19487ed3 /view/sharedcache/core/MetadataSerializable.hpp
parent714d7628097c5b02e23bcad1dba9880c7afc034b (diff)
[SharedCache] Make MetadataSerializable::Load static
`MetadataSerializable` is updated to allow a subclass to optionally specify the return type of `Load`. If not specified it defaults to the subclass itself. `SharedCache` specifies `std::optional` to represent the case where the serialized metadata is in a format or version it does not recognize. By making `Load` a static member function and having it return a new object it becomes easier to reason about the state of objects when a deserialization failure occurs. It can return `std::optional` to indicate failure and there is no object left in an unknown state. Prior to this, `Load` worked on an existing instance of an object. It was unclear what state the object would be in if a deserialization failure occurred (its original state prior to `Load`? some partially-loaded state? a null state?). The failure itself also had to be communicated out of band.
Diffstat (limited to 'view/sharedcache/core/MetadataSerializable.hpp')
-rw-r--r--view/sharedcache/core/MetadataSerializable.hpp40
1 files changed, 15 insertions, 25 deletions
diff --git a/view/sharedcache/core/MetadataSerializable.hpp b/view/sharedcache/core/MetadataSerializable.hpp
index 7b44ccbd..91ab2ed2 100644
--- a/view/sharedcache/core/MetadataSerializable.hpp
+++ b/view/sharedcache/core/MetadataSerializable.hpp
@@ -34,6 +34,10 @@
avoid that.
* */
+#ifndef SHAREDCACHE_CORE_METADATASERIALIZABLE_HPP
+#define SHAREDCACHE_CORE_METADATASERIALIZABLE_HPP
+
+#include <cassert>
#include "binaryninjaapi.h"
#include "rapidjson/document.h"
#include "rapidjson/stringbuffer.h"
@@ -41,9 +45,6 @@
#include "../api/sharedcachecore.h"
#include "view/macho/machoview.h"
-#ifndef SHAREDCACHE_CORE_METADATASERIALIZABLE_HPP
-#define SHAREDCACHE_CORE_METADATASERIALIZABLE_HPP
-
namespace SharedCacheCore {
#define MSS(name) context.store(#name, name)
@@ -51,7 +52,6 @@ namespace SharedCacheCore {
#define MSS_SUBCLASS(name) Serialize(context, #name, name)
#define MSL(name) name = context.load<decltype(name)>(#name)
#define MSL_CAST(name, storedType, type) name = (type)context.load<storedType>(#name)
-#define MSL_SUBCLASS(name) Deserialize(context, #name, name)
using namespace BinaryNinja;
@@ -83,44 +83,34 @@ struct DeserializationContext {
}
};
-template <typename Derived>
-class MetadataSerializable
-{
+template <typename Derived, typename LoadResult = Derived>
+class MetadataSerializable {
public:
- std::string AsString() const
- {
+ std::string AsString() const {
SerializationContext context;
Store(context);
return context.buffer.GetString();
}
- void LoadFromString(const std::string& s)
- {
+ static LoadResult LoadFromString(const std::string& s) {
DeserializationContext context;
- context.doc.Parse(s.c_str());
- AsDerived().Load(context);
+ [[maybe_unused]] rapidjson::ParseResult result = context.doc.Parse(s.c_str());
+ assert(result);
+ return Derived::Load(context);
}
- void LoadFromValue(rapidjson::Value& s)
- {
+ static LoadResult LoadFromValue(rapidjson::Value& s) {
DeserializationContext context;
context.doc.CopyFrom(s, context.doc.GetAllocator());
- AsDerived().Load(context);
+ return Derived::Load(context);
}
- Ref<Metadata> AsMetadata() {
+ Ref<Metadata> AsMetadata() const {
return new Metadata(AsString());
}
- bool LoadFromMetadata(const Ref<Metadata>& meta)
- {
- if (!meta->IsString())
- return false;
- LoadFromString(meta->GetString());
- return true;
- }
-
+ template <typename... Args>
void Store(SerializationContext& context) const {
context.writer.StartObject();
AsDerived().Store(context);