internal void ReadValueWithoutAdapters <TValue>(ref TValue value, UnsafeValueView view, bool isRoot = false) { #if UNITY_EDITOR if (RuntimeTypeInfoCache <TValue> .IsLazyLoadReference && view.Type == TokenType.String) { var json = view.AsStringView().ToString(); if (json == s_EmptyGlobalObjectId) // Workaround issue where GlobalObjectId.TryParse returns false for empty GlobalObjectId { return; } if (UnityEditor.GlobalObjectId.TryParse(json, out var id)) { var instanceID = UnityEditor.GlobalObjectId.GlobalObjectIdentifierToInstanceIDSlow(id); PropertyContainer.SetValue(ref value, "m_InstanceID", instanceID); return; } m_SerializedTypeProvider.Events.Add(new DeserializationEvent(EventType.Error, $"An error occured while deserializing asset reference Value=[{json}].")); return; } #endif switch (view.Type) { case TokenType.String: { var v = view.AsStringView().ToString(); TypeConversion.TryConvert(ref v, out value); break; } case TokenType.Primitive: { var p = view.AsPrimitiveView(); if (p.IsIntegral()) { if (p.IsSigned()) { var v = p.AsInt64(); TypeConversion.TryConvert(ref v, out value); } else { var v = p.AsUInt64(); TypeConversion.TryConvert(ref v, out value); } } else if (p.IsDecimal() || p.IsInfinity() || p.IsNaN()) { var v = p.AsFloat(); TypeConversion.TryConvert(ref v, out value); } else if (p.IsBoolean()) { var v = p.AsBoolean(); TypeConversion.TryConvert(ref v, out value); } else if (p.IsNull()) { value = default; } break; } default: { var metadata = view.Type == TokenType.Object ? GetSerializedContainerMetadata(view.AsObjectView()) : default; m_SerializedTypeProvider.View = view; m_SerializedTypeProvider.SerializedType = isRoot ? m_SerializedType : null; if (RuntimeTypeInfoCache <TValue> .IsNullable) { m_SerializedTypeProvider.SerializedType = Nullable.GetUnderlyingType(typeof(TValue)); } if (metadata.IsSerializedReference) { if (null == m_SerializedReferences) { m_SerializedTypeProvider.Events.Add(new DeserializationEvent(EventType.Exception, new Exception("Deserialization encountered a serialized object reference while running with DisableSerializedReferences."))); return; } value = (TValue)m_SerializedReferences.GetDeserializedReference(metadata.SerializedId); return; } try { DefaultTypeConstruction.Construct(ref value, m_SerializedTypeProvider); } catch (ArgumentException e) { m_SerializedTypeProvider.Events.Add(new DeserializationEvent(EventType.Exception, new ArgumentException(e.Message))); return; } if (metadata.HasSerializedId) { // This call is harmless to skip if we don't have serialized references. m_SerializedReferences?.AddDeserializedReference(metadata.SerializedId, value); } using (new SerializedContainerMetadataScope(this, metadata)) using (new UnsafeViewScope(this, view)) { if (RuntimeTypeInfoCache <TValue> .IsNullable) { // Unpack Nullable<T> as T var underlyingType = Nullable.GetUnderlyingType(typeof(TValue)); var underlyingValue = System.Convert.ChangeType(value, underlyingType); if (!PropertyContainer.TryAccept(this, ref underlyingValue, out var errorCode)) { switch (errorCode) { case VisitErrorCode.NullContainer: throw new ArgumentNullException(nameof(value)); case VisitErrorCode.InvalidContainerType: throw new InvalidContainerTypeException(value.GetType()); case VisitErrorCode.MissingPropertyBag: throw new MissingPropertyBagException(value.GetType()); default: throw new Exception($"Unexpected {nameof(VisitErrorCode)}=[{errorCode}]"); } } // Repack the T as Nullable<T> value = (TValue)underlyingValue; } else { if (!PropertyContainer.TryAccept(this, ref value, out var errorCode)) { switch (errorCode) { case VisitErrorCode.NullContainer: throw new ArgumentNullException(nameof(value)); case VisitErrorCode.InvalidContainerType: throw new InvalidContainerTypeException(value.GetType()); case VisitErrorCode.MissingPropertyBag: throw new MissingPropertyBagException(value.GetType()); default: throw new Exception($"Unexpected {nameof(VisitErrorCode)}=[{errorCode}]"); } } } } break; } } }
void ReadValue <TValue>(ref TValue value, UnsafeValueView view, bool isRoot = false) { var runAdapters = !(isRoot && m_DisableRootAdapters); // Special check so we have higher perf for primitives. if (runAdapters && !RuntimeTypeInfoCache <TValue> .IsPrimitiveOrString) { if (m_Adapters.TryDeserialize(view, ref value, m_SerializedTypeProvider.Events)) { return; } } switch (view.Type) { case TokenType.String: { TypeConversion.TryConvert(view.AsStringView().ToString(), out value); break; } case TokenType.Primitive: { var p = view.AsPrimitiveView(); if (p.IsIntegral()) { if (p.IsSigned()) { TypeConversion.TryConvert(p.AsInt64(), out value); } else { TypeConversion.TryConvert(p.AsUInt64(), out value); } } else if (p.IsDecimal() || p.IsInfinity() || p.IsNaN()) { TypeConversion.TryConvert(p.AsFloat(), out value); } else if (p.IsBoolean()) { TypeConversion.TryConvert(p.AsBoolean(), out value); } else if (p.IsNull()) { value = default; } break; } default: { var metadata = view.Type == TokenType.Object ? GetSerializedContainerMetadata(view.AsObjectView()) : default; m_SerializedTypeProvider.View = view; m_SerializedTypeProvider.SerializedType = isRoot ? m_SerializedType : null; if (metadata.IsSerializedReference) { if (null == m_SerializedReferences) { m_SerializedTypeProvider.Events.Add(new DeserializationEvent(EventType.Exception, new Exception("Deserialization encountered a serialized object reference while running with DisableSerializedReferences."))); return; } value = (TValue)m_SerializedReferences.GetDeserializedReference(metadata.SerializedId); return; } try { DefaultTypeConstruction.Construct(ref value, m_SerializedTypeProvider); } catch (ArgumentException e) { m_SerializedTypeProvider.Events.Add(new DeserializationEvent(EventType.Exception, new ArgumentException(e.Message))); return; } if (metadata.HasSerializedId) { // This call is harmless to skip if we don't have serialized references. m_SerializedReferences?.AddDeserializedReference(metadata.SerializedId, value); } using (new SerializedContainerMetadataScope(this, metadata)) using (new UnsafeViewScope(this, view)) { if (!PropertyContainer.Visit(ref value, this, out var errorCode)) { switch (errorCode) { case VisitErrorCode.NullContainer: throw new ArgumentNullException(nameof(value)); case VisitErrorCode.InvalidContainerType: throw new InvalidContainerTypeException(value.GetType()); case VisitErrorCode.MissingPropertyBag: throw new MissingPropertyBagException(value.GetType()); default: throw new Exception($"Unexpected {nameof(VisitErrorCode)}=[{errorCode}]"); } } } break; } } }
protected void ReadValue <TValue>(ref TValue value, UnsafeValueView view, bool isRoot = false) { switch (view.Type) { case TokenType.String: { TypeConversion.TryConvert(view.AsStringView().ToString(), out value); break; } case TokenType.Primitive: { var p = view.AsPrimitiveView(); if (p.IsIntegral()) { if (p.IsSigned()) { TypeConversion.TryConvert(p.AsInt64(), out value); } else if (value is long) { TypeConversion.TryConvert(p.AsInt64(), out value); } else { TypeConversion.TryConvert(p.AsUInt64(), out value); } } else if (p.IsDecimal() || p.IsInfinity() || p.IsNaN()) { TypeConversion.TryConvert(p.AsFloat(), out value); } else if (p.IsBoolean()) { TypeConversion.TryConvert(p.AsBoolean(), out value); } else if (p.IsNull()) { value = default; } break; } default: { var metadata = view.Type == TokenType.Object ? GetSerializedContainerMetadata(view.AsObjectView()) : default; m_SerializedTypeProvider.View = view; m_SerializedTypeProvider.SerializedType = isRoot ? m_SerializedType : null; try { var customValue = m_CustomTypeConstructor?.Construct(typeof(TValue), view); if (customValue != null) { value = (TValue)customValue; } if (value == null) { DefaultTypeConstruction.Construct(ref value, m_SerializedTypeProvider); } } catch (ArgumentException e) { m_SerializedTypeProvider.Events.Add(new DeserializationEvent(EventType.Exception, new ArgumentException(e.Message))); return; } using (new SerializedContainerMetadataScope(this, metadata)) using (new UnsafeViewScope(this, view)) { var type = value?.GetType(); #if !NET_DOTS && !ENABLE_IL2CPP if (type != null) { SceneSerialization.RegisterPropertyBag(type); } #endif if (!PropertyContainer.Visit(ref value, this, out var errorCode)) { switch (errorCode) { case VisitErrorCode.NullContainer: throw new ArgumentNullException(nameof(value)); case VisitErrorCode.InvalidContainerType: throw new InvalidContainerTypeException(type); case VisitErrorCode.MissingPropertyBag: throw new MissingPropertyBagException(type); default: throw new Exception($"Unexpected {nameof(VisitErrorCode)}=[{errorCode}]"); } } } break; } } }
void ReadValue <TValue>(ref TValue value, bool isRoot = false) { var runAdapters = !(isRoot && m_DisableRootAdapters); if (runAdapters && m_Adapters.TryDeserialize(m_Stream, ref value)) { return; } if (RuntimeTypeInfoCache <TValue> .IsEnum) { BinarySerialization.ReadPrimitiveUnsafe(m_Stream, ref value, Enum.GetUnderlyingType(typeof(TValue))); return; } var token = default(byte); if (RuntimeTypeInfoCache <TValue> .CanBeNull) { token = m_Stream->ReadNext <byte>(); switch (token) { case k_TokenNull: value = default; return; case k_TokenSerializedReference: var id = m_Stream->ReadNext <int>(); if (null == m_SerializedReferences) { throw new Exception("Deserialization encountered a serialized object reference while running with DisableSerializedReferences."); } value = (TValue)m_SerializedReferences.GetDeserializedReference(id); return; } } if (RuntimeTypeInfoCache <TValue> .IsNullable) { BinarySerialization.ReadPrimitiveBoxed(m_Stream, ref value, Nullable.GetUnderlyingType(typeof(TValue))); return; } #if !UNITY_DOTSPLAYER if (runAdapters && token == k_TokenUnityEngineObjectReference) { var unityEngineObject = default(UnityEngine.Object); m_Adapters.TryDeserialize(m_Stream, ref unityEngineObject); value = (TValue)(object)unityEngineObject; return; } #endif if (token == k_TokenPolymorphic) { m_Stream->ReadNext(out var assemblyQualifiedTypeName); if (string.IsNullOrEmpty(assemblyQualifiedTypeName)) { throw new ArgumentException(); } var concreteType = Type.GetType(assemblyQualifiedTypeName); if (null == concreteType) { if (FormerNameAttribute.TryGetCurrentTypeName(assemblyQualifiedTypeName, out var currentAssemblyQualifiedTypeName)) { concreteType = Type.GetType(currentAssemblyQualifiedTypeName); } if (null == concreteType) { throw new ArgumentException(); } } m_SerializedTypeProviderSerializedType = concreteType; } else { // If we have a user provided root type pass it to the type construction. m_SerializedTypeProviderSerializedType = isRoot ? m_SerializedType : null; } DefaultTypeConstruction.Construct(ref value, this); if (RuntimeTypeInfoCache <TValue> .IsObjectType && !RuntimeTypeInfoCache.IsContainerType(value.GetType())) { BinarySerialization.ReadPrimitiveBoxed(m_Stream, ref value, value.GetType()); return; } if (!PropertyContainer.Visit(ref value, this, out var errorCode)) { switch (errorCode) { case VisitErrorCode.NullContainer: throw new ArgumentNullException(nameof(value)); case VisitErrorCode.InvalidContainerType: throw new InvalidContainerTypeException(value.GetType()); case VisitErrorCode.MissingPropertyBag: throw new MissingPropertyBagException(value.GetType()); default: throw new Exception($"Unexpected {nameof(VisitErrorCode)}=[{errorCode}]"); } } }
internal void ReadValueWithoutAdapters <TValue>(ref TValue value, bool isRoot) { if (RuntimeTypeInfoCache <TValue> .IsEnum) { BinarySerialization.ReadPrimitiveUnsafe(m_Stream, ref value, Enum.GetUnderlyingType(typeof(TValue))); return; } var token = default(byte); if (RuntimeTypeInfoCache <TValue> .CanBeNull) { token = m_Stream->ReadNext <byte>(); switch (token) { case k_TokenNull: value = default; return; case k_TokenSerializedReference: var id = m_Stream->ReadNext <int>(); if (null == m_SerializedReferences) { throw new Exception("Deserialization encountered a serialized object reference while running with DisableSerializedReferences."); } value = (TValue)m_SerializedReferences.GetDeserializedReference(id); return; } } if (RuntimeTypeInfoCache <TValue> .IsNullable) { var underlyingType = Nullable.GetUnderlyingType(typeof(TValue)); if (RuntimeTypeInfoCache.IsContainerType(underlyingType)) { m_SerializedTypeProviderSerializedType = underlyingType; DefaultTypeConstruction.Construct(ref value, this); var underlyingValue = Convert.ChangeType(value, underlyingType); if (!PropertyContainer.TryAccept(this, ref underlyingValue, out var errorCode)) { switch (errorCode) { case VisitErrorCode.NullContainer: throw new ArgumentNullException(nameof(value)); case VisitErrorCode.InvalidContainerType: throw new InvalidContainerTypeException(value.GetType()); case VisitErrorCode.MissingPropertyBag: throw new MissingPropertyBagException(value.GetType()); default: throw new Exception($"Unexpected {nameof(VisitErrorCode)}=[{errorCode}]"); } } // Repack the T as Nullable<T> value = (TValue)underlyingValue; } else { BinarySerialization.ReadPrimitiveBoxed(m_Stream, ref value, Nullable.GetUnderlyingType(typeof(TValue))); } return; } #if !UNITY_DOTSPLAYER if (!(isRoot && m_DisableRootAdapters) && token == k_TokenUnityEngineObjectReference) { value = (TValue)(m_Adapters.Internal as Adapters.Contravariant.IBinaryAdapter <UnityEngine.Object>).Deserialize(new BinaryDeserializationContext <TValue>(this, default, isRoot));;