using System;
using System.Collections.Generic;
using System.Linq;
using FullSerializer.Internal;
namespace FullSerializer {
///
/// The serialization converter allows for customization of the serialization process.
///
/// You do not want to derive from this class - there is no way to actually use it within
/// the serializer.. Instead, derive from either fsConverter or fsDirectConverter
public abstract class fsBaseConverter {
///
/// The serializer that was owns this converter.
///
public fsSerializer Serializer;
///
/// Construct an object instance that will be passed to TryDeserialize. This should **not**
/// deserialize the object.
///
/// The data the object was serialized with.
/// The field/property type that is storing the instance.
/// An object instance
public virtual object CreateInstance(fsData data, Type storageType) {
if (RequestCycleSupport(storageType)) {
throw new InvalidOperationException("Please override CreateInstance for " +
GetType().FullName + "; the object graph for " + storageType +
" can contain potentially contain cycles, so separated instance creation " +
"is needed");
}
return storageType;
}
///
/// If true, then the serializer will support cyclic references with the given converted
/// type.
///
/// The field/property type that is currently storing the object
/// that is being serialized.
public virtual bool RequestCycleSupport(Type storageType) {
if (storageType == typeof(string)) return false;
return storageType.Resolve().IsClass || storageType.Resolve().IsInterface;
}
///
/// If true, then the serializer will include inheritance data for the given converter.
///
/// The field/property type that is currently storing the object
/// that is being serialized.
public virtual bool RequestInheritanceSupport(Type storageType) {
return storageType.Resolve().IsSealed == false;
}
///
/// Serialize the actual object into the given data storage.
///
/// The object instance to serialize. This will never be null.
/// The serialized state.
/// The field/property type that is storing this instance.
/// If serialization was successful.
public abstract fsResult TrySerialize(object instance, out fsData serialized, Type storageType);
///
/// Deserialize data into the object instance.
///
/// Serialization data to deserialize from.
/// The object instance to deserialize into.
/// The field/property type that is storing the instance.
/// True if serialization was successful, false otherwise.
public abstract fsResult TryDeserialize(fsData data, ref object instance, Type storageType);
protected fsResult FailExpectedType(fsData data, params fsDataType[] types) {
return fsResult.Fail(GetType().Name + " expected one of " +
string.Join(", ", types.Select(t => t.ToString()).ToArray()) +
" but got " + data.Type + " in " + data);
}
protected fsResult CheckType(fsData data, fsDataType type) {
if (data.Type != type) {
return fsResult.Fail(GetType().Name + " expected " + type + " but got " + data.Type + " in " + data);
}
return fsResult.Success;
}
protected fsResult CheckKey(fsData data, string key, out fsData subitem) {
return CheckKey(data.AsDictionary, key, out subitem);
}
protected fsResult CheckKey(Dictionary data, string key, out fsData subitem) {
if (data.TryGetValue(key, out subitem) == false) {
return fsResult.Fail(GetType().Name + " requires a <" + key + "> key in the data " + data);
}
return fsResult.Success;
}
protected fsResult SerializeMember(Dictionary data, Type overrideConverterType, string name, T value) {
fsData memberData;
var result = Serializer.TrySerialize(typeof(T), overrideConverterType, value, out memberData);
if (result.Succeeded) data[name] = memberData;
return result;
}
protected fsResult DeserializeMember(Dictionary data, Type overrideConverterType, string name, out T value) {
fsData memberData;
if (data.TryGetValue(name, out memberData) == false) {
value = default(T);
return fsResult.Fail("Unable to find member \"" + name + "\"");
}
object storage = null;
var result = Serializer.TryDeserialize(memberData, typeof(T), overrideConverterType, ref storage);
value = (T)storage;
return result;
}
}
}