public object Deserialize([NotNull] MonoBehaviour monoBehavior, [NotNull] Type type) { if (monoBehavior == null) { throw new ArgumentNullException(nameof(monoBehavior)); } var typeNodes = monoBehavior.serializedType.m_Nodes; // Types nodes are empty, which means null if (typeNodes == null) { return(SerializingHelper.CreateDefaultOf(type)); } // We should actually read the contents and deserialize an object var structure = StructureReader.ReadMembers(typeNodes, monoBehavior.reader); Debug.Assert(structure.Length == 1); var rootObject = structure[0].Value; Debug.Assert(rootObject != null); Debug.Assert(rootObject is CustomType); var serializer = _context.Value.GetSerializerOf(type); var obj = serializer.DeserializeObject((CustomType)rootObject, 0); return(obj); }
private static (string Name, object Value) ReadMemberValue([NotNull, ItemNotNull] IReadOnlyList <TypeTreeNode> typeNodes, ref int nodeIndex, [NotNull] BinaryReader reader) { var typeNode = typeNodes[nodeIndex]; object value; var align = (typeNode.m_MetaFlag & 0x4000) != 0; switch (typeNode.m_Type) { case "SInt8": value = reader.ReadSByte(); break; case "UInt8": case "char": value = reader.ReadByte(); break; case "short": case "SInt16": value = reader.ReadInt16(); break; case "UInt16": case "unsigned short": value = reader.ReadUInt16(); break; case "int": case "SInt32": value = reader.ReadInt32(); break; case "UInt32": case "unsigned int": case "Type*": value = reader.ReadUInt32(); break; case "long long": case "SInt64": value = reader.ReadInt64(); break; case "UInt64": case "unsigned long long": case "FileSize": value = reader.ReadUInt64(); break; case "float": value = reader.ReadSingle(); break; case "double": value = reader.ReadDouble(); break; case "bool": value = reader.ReadBoolean(); break; case "string": value = reader.ReadAlignedString(); nodeIndex += 3; break; case "map": { // IDictionary<TKey, TValue> if ((typeNodes[nodeIndex + 1].m_MetaFlag & 0x4000) != 0) { align = true; } var count = reader.ReadInt32(); var map = GetChildTypeNodes(typeNodes, nodeIndex); nodeIndex += map.Count - 1; var first = GetChildTypeNodes(map, 4); var second = GetChildTypeNodes(map, 4 + first.Count); var dict = new Dictionary <object, object>(); Type keyType = null, valueType = null; for (var j = 0; j < count; j += 1) { var tmp1 = 0; var(_, keyObject) = ReadMemberValue(first, ref tmp1, reader); var tmp2 = 0; var(_, valueObject) = ReadMemberValue(second, ref tmp2, reader); if (keyType == null && !ReferenceEquals(keyObject, null)) { keyType = SerializingHelper.NonNullTypeOf(keyObject); } if (valueType == null && !ReferenceEquals(valueObject, null)) { valueType = SerializingHelper.NonNullTypeOf(valueObject); } dict.Add(keyObject, valueObject); } if (keyType == null) { keyType = typeof(object); } if (valueType == null) { valueType = typeof(object); } value = new ObjectDictionary(dict, keyType, valueType); break; } case "TypelessData": { // Raw byte array var size = reader.ReadInt32(); var data = reader.ReadBytes(size); nodeIndex += 2; value = new RawData(data); break; } default: { if (nodeIndex < typeNodes.Count - 1 && typeNodes[nodeIndex + 1].m_Type == "Array") { // Array if ((typeNodes[nodeIndex + 1].m_MetaFlag & 0x4000) != 0) { align = true; } var count = reader.ReadUInt32(); var vector = GetChildTypeNodes(typeNodes, nodeIndex); nodeIndex += vector.Count - 1; var array = new object[count]; Type elementType = null; for (var j = 0; j < count; j += 1) { var tmp = 3; var(_, item) = ReadMemberValue(vector, ref tmp, reader); if (elementType == null && !ReferenceEquals(item, null)) { elementType = SerializingHelper.NonNullTypeOf(item); } array[j] = item; } if (elementType == null) { elementType = typeof(object); } value = new ObjectArray(array, elementType); } else { // Object var classTree = GetChildTypeNodes(typeNodes, nodeIndex); var classTreeCount = classTree.Count; nodeIndex += classTreeCount - 1; var variables = new Dictionary <string, object>(); for (var j = 1; j < classTreeCount; j += 1) { var(memberName, memberValue) = ReadMemberValue(classTree, ref j, reader); variables.Add(memberName, memberValue); } value = new CustomType(typeNode.m_Type, variables); } break; } } if (align) { reader.AlignStream(); } return(typeNode.m_Name, value); }