/// <summary> /// Serialize the object. /// </summary> /// <param name="data">Data carrier to serialize to</param> /// <param name="target">Object or root of object model to be serialized</param> /// <exception cref="ArgumentNullException">thrown if <paramref name="data"/> is null or <paramref name="target"/> is null</exception> public void SerializeObject <TTarget>(IDataAdapter data, TTarget target) { if (data == null) { throw new ArgumentNullException(nameof(data)); } if (target == null) { throw new ArgumentNullException(nameof(target)); } haveContainers = false; haveReferences = false; havePrivateProperties = false; SerializeSubValue(typeof(TTarget), target, data, null); if (!settings.SaveOptimizationFlags) { return; } OptimizationFlags flags = 0; if (!haveContainers) { flags |= OptimizationFlags.NoContainers; } if (!haveReferences) { flags |= OptimizationFlags.NoReferences; } if (havePrivateProperties) { flags |= OptimizationFlags.PrivateProperties; } if (settings.EnumsAsValue) { flags |= OptimizationFlags.EnumAsValue; } if (flags != 0) { data.AddIntValue((long)flags, ATTRIBUTE_FLAGS, true); } if (typesCache.Count > 0) { IDataArray array = data.AddChild(ELEMENT_TYPES).AddArray(); foreach (KeyValuePair <Type, int> pair in typesCache) { array.AddArrayValue().SetStringValue(TypeCache.GetTypeFullName(pair.Key, settings.AssemblyQualifiedNames)); } } }
private void SerializeValue(Type type, object value, IDataAdapter data, Info info, bool isReadOnly) { if (info.Category == TypeCategory.Primitive) { // no need to serialize if (isReadOnly) { return; } SerializePrimitive(type, value, data, info.Name, info.Location != NanoLocation.SubNode); return; } if (info.Category == TypeCategory.Enum) { // no need to serialize if (isReadOnly) { return; } if (settings.EnumsAsValue) { data.AddIntValue(((IConvertible)value).ToInt64(null), info.Name, info.Location != NanoLocation.SubNode); } else { data.AddStringValue(value.ToString(), info.Name, info.Location != NanoLocation.SubNode); } return; } if (info.Location == NanoLocation.Attribute) { throw new SerializationException($"Unable to serialize {type.Name} to attribute"); } IDataAdapter subNode = data.AddChild(info.Name); SerializeSubValue(type, value, subNode, info.GenericArgs); }
void INanoSerializable.Serialize(IDataAdapter data, ISubSerializer subSerializer) { data.AddStringValue(A, "1", true); subSerializer.ContinueSerialization(typeof(object), B, data.AddChild("1").AddChild("2")); }
private void SerializeContainer(object value, IDataAdapter data, TypeCategory category, Type[] genericArgs) { Type type = value.GetType(); // arrays if (category == TypeCategory.Array) { Array array = (Array)value; Type elementType = type.GetElementType(); int[] coords = new int[array.Rank]; if (array.Rank > 1) { data.AddIntValue(array.Rank, ATTRIBUTE_ARRAY_RANK, true); } SerializeArrayRank(array, elementType, coords, 0, data); haveContainers = true; return; } // dictionaries if (category == TypeCategory.IDictionary) { Type keyType = genericArgs[0]; Type valueType = genericArgs[1]; Func <object, object> getKeyFunc = null; Func <object, object> getValueFunc = null; IDataArray array = data.AddArray(); foreach (object o in (IEnumerable)value) { if (getKeyFunc == null) { Type objectType = o.GetType(); if (!TypeCache.TryGetNamedAccessor(objectType, "Key", ref getKeyFunc)) { getKeyFunc = InvocationHelper.CreateGetDelegate(o.GetType(), keyType, objectType.GetProperty("Key").GetMethod); TypeCache.AddTypeNamedAccessor(objectType, "Key", getKeyFunc); } if (!TypeCache.TryGetNamedAccessor(objectType, "Value", ref getValueFunc)) { getValueFunc = InvocationHelper.CreateGetDelegate(o.GetType(), valueType, objectType.GetProperty("Value").GetMethod); TypeCache.AddTypeNamedAccessor(objectType, "Value", getValueFunc); } } IDataAdapter itemEl = array.AddArrayValue(); SerializeSubValue(keyType, getKeyFunc(o), itemEl.AddChild(settings.DictionaryKeyName), null); SerializeSubValue(valueType, getValueFunc(o), itemEl.AddChild(settings.DictionaryValueName), null); } haveContainers = true; return; } // generics if (category == TypeCategory.GenericIList || category == TypeCategory.ISet || category == TypeCategory.GenericQueue || category == TypeCategory.GenericStack || category == TypeCategory.LinkedList) { SerializeContainer((IEnumerable)value, genericArgs[0], data); return; } // non-generic versions if (category == TypeCategory.IList || category == TypeCategory.Queue || category == TypeCategory.Stack) { SerializeContainer((IEnumerable)value, typeof(object), data); return; } }