Beispiel #1
0
        public object Deserialize(EventReader reader, Type type)
        {
            if (reader == null)
            {
                throw new ArgumentNullException("reader");
            }
            if (type == null)
            {
                throw new ArgumentNullException("type");
            }
            bool   flag  = reader.Allow <StreamStart>() != null;
            bool   flag2 = reader.Allow <DocumentStart>() != null;
            object obj2  = null;

            if (!reader.Accept <DocumentEnd>() && !reader.Accept <StreamEnd>())
            {
                using (SerializerState state = new SerializerState())
                {
                    obj2 = this.valueDeserializer.DeserializeValue(reader, type, state, this.valueDeserializer);
                    state.OnDeserialization();
                }
            }
            if (flag2)
            {
                reader.Expect <DocumentEnd>();
            }
            if (flag)
            {
                reader.Expect <StreamEnd>();
            }
            return(obj2);
        }
Beispiel #2
0
        /// <summary>
        /// Deserializes an object of the specified type.
        /// </summary>
        /// <param name="reader">The <see cref="EventReader" /> where to deserialize the object.</param>
        /// <param name="type">The static type of the object to deserialize.</param>
        /// <param name="options">Options that control how the deserialization is to be performed.</param>
        /// <returns>Returns the deserialized object.</returns>
        public object Deserialize(EventReader reader, Type type, DeserializationFlags options = DeserializationFlags.None)
        {
            if (reader == null)
            {
                throw new ArgumentNullException("reader");
            }

            if (type == null)
            {
                throw new ArgumentNullException("type");
            }

            var hasStreamStart = reader.Allow <StreamStart>() != null;

            var hasDocumentStart = reader.Allow <DocumentStart>() != null;

            object result = DeserializeValue(reader, type, null);

            if (hasDocumentStart)
            {
                reader.Expect <DocumentEnd>();
            }

            if (hasStreamStart)
            {
                reader.Expect <StreamEnd>();
            }

            return(result);
        }
Beispiel #3
0
        /// <summary>
        /// Deserializes an object from the specified <see cref="EventReader" /> with an expected specific type.
        /// </summary>
        /// <param name="reader">The reader.</param>
        /// <param name="expectedType">The expected type, maybe null.</param>
        /// <param name="existingObject">An existing object, may be null.</param>
        /// <param name="contextSettings">The context settings.</param>
        /// <param name="context">The context used to deserialize the object.</param>
        /// <returns>A deserialized object.</returns>
        /// <exception cref="System.ArgumentNullException">reader</exception>
        public object Deserialize(EventReader reader, Type expectedType, object existingObject, SerializerContextSettings contextSettings, out SerializerContext context)
        {
            if (reader == null)
            {
                throw new ArgumentNullException("reader");
            }

            var hasStreamStart   = reader.Allow <StreamStart>() != null;
            var hasDocumentStart = reader.Allow <DocumentStart>() != null;

            context = null;

            object result = null;

            if (!reader.Accept <DocumentEnd>() && !reader.Accept <StreamEnd>())
            {
                context = new SerializerContext(this, contextSettings)
                {
                    Reader = reader
                };
                result = context.ReadYaml(existingObject, expectedType);
            }

            if (hasDocumentStart)
            {
                reader.Expect <DocumentEnd>();
            }

            if (hasStreamStart)
            {
                reader.Expect <StreamEnd>();
            }

            return(result);
        }
Beispiel #4
0
        /// <summary>
        /// Deserializes an object of the specified type.
        /// </summary>
        /// <param name="reader">The <see cref="EventReader" /> where to deserialize the object.</param>
        /// <param name="type">The static type of the object to deserialize.</param>
        /// <param name="options">Options that control how the deserialization is to be performed.</param>
        /// <returns>Returns the deserialized object.</returns>
        public object Deserialize(EventReader reader, Type type)
        {
            if (reader == null)
            {
                throw new ArgumentNullException("reader");
            }

            if (type == null)
            {
                throw new ArgumentNullException("type");
            }

            var hasStreamStart = reader.Allow <StreamStart>() != null;

            var hasDocumentStart = reader.Allow <DocumentStart>() != null;

            object result = null;

            if (!reader.Accept <DocumentEnd>() && !reader.Accept <StreamEnd>())
            {
                result = valueDeserializer.DeserializeValue(reader, type, new SerializerState(), valueDeserializer);
            }

            if (hasDocumentStart)
            {
                reader.Expect <DocumentEnd>();
            }

            if (hasStreamStart)
            {
                reader.Expect <StreamEnd>();
            }

            return(result);
        }
Beispiel #5
0
        public static YamlDocument Load(EventReader eventReader, YamlNodeTracker tracker = null)
        {
            var documentStart = eventReader.Allow <DocumentStart>();

            var contents = ReadElement(eventReader, tracker);

            var documentEnd = eventReader.Allow <DocumentEnd>();

            return(new YamlDocument(documentStart, documentEnd, contents, tracker));
        }
Beispiel #6
0
        /// <summary>
        /// Deserializes an object from the specified <see cref="EventReader" /> with an expected specific type.
        /// </summary>
        /// <param name="reader">The reader.</param>
        /// <param name="expectedType">The expected type, maybe null.</param>
        /// <param name="existingObject">An existing object, may be null.</param>
        /// <param name="contextSettings">The context settings.</param>
        /// <param name="context">The context used to deserialize the object.</param>
        /// <returns>A deserialized object.</returns>
        /// <exception cref="System.ArgumentNullException">reader</exception>
        public object Deserialize(EventReader reader, Type expectedType, object existingObject, SerializerContextSettings contextSettings, out SerializerContext context)
        {
            if (reader == null)
            {
                throw new ArgumentNullException(nameof(reader));
            }

            var hasStreamStart   = reader.Allow <StreamStart>() != null;
            var hasDocumentStart = reader.Allow <DocumentStart>() != null;

            context = null;

            object result = null;

            if (!reader.Accept <DocumentEnd>() && !reader.Accept <StreamEnd>())
            {
                context = new SerializerContext(this, contextSettings)
                {
                    Reader = reader
                };
                var node = context.Reader.Parser.Current;
                try
                {
                    var objectContext = new ObjectContext(context, existingObject, context.FindTypeDescriptor(expectedType));
                    result = context.Serializer.ObjectSerializer.ReadYaml(ref objectContext);
                }
                catch (YamlException)
                {
                    throw;
                }
                catch (Exception ex)
                {
                    ex = ex.Unwrap();
                    throw new YamlException(node, ex);
                }
            }

            if (hasDocumentStart)
            {
                reader.Expect <DocumentEnd>();
            }

            if (hasStreamStart)
            {
                reader.Expect <StreamEnd>();
            }

            return(result);
        }
Beispiel #7
0
        public static YamlStream Load(EventReader eventReader, YamlNodeTracker tracker = null)
        {
            var streamStart = eventReader.Allow <StreamStart>();

            var documents = new List <YamlDocument>();

            while (!eventReader.Accept <StreamEnd>())
            {
                documents.Add(YamlDocument.Load(eventReader, tracker));
            }

            var streamEnd = eventReader.Allow <StreamEnd>();

            return(new YamlStream(streamStart, streamEnd, documents, tracker));
        }
Beispiel #8
0
        public void DeserializeManyDocuments()
        {
            var yaml       = @"---
Name: Andy
---
Name: Brad
---
Name: Charles
...";
            var serializer = new Serializer();
            var reader     = new EventReader(new Parser(new StringReader(yaml)));

            reader.Allow <StreamStart>();

            var people = new List <Person>();

            while (!reader.Accept <StreamEnd>())
            {
                var person = serializer.Deserialize <Person>(reader);
                people.Add(person);
            }

            Assert.AreEqual(3, people.Count);
            Assert.AreEqual("Andy", people[0].Name);
            Assert.AreEqual("Brad", people[1].Name);
            Assert.AreEqual("Charles", people[2].Name);
        }
Beispiel #9
0
 bool INodeDeserializer.Deserialize(EventReader reader, Type expectedType, Func <EventReader, Type, object> nestedObjectDeserializer, out object value)
 {
     if (reader.Allow <MappingStart>() == null)
     {
         value = null;
         return(false);
     }
     value = this._objectFactory.Create(expectedType);
     while (!reader.Accept <MappingEnd>())
     {
Beispiel #10
0
        public object DeserializeValue(EventReader reader, Type expectedType, SerializerState state, IValueDeserializer nestedObjectDeserializer)
        {
            object value;
            var    alias = reader.Allow <AnchorAlias>();

            if (alias != null)
            {
                var          aliasState = state.Get <AliasState>();
                ValuePromise valuePromise;
                if (!aliasState.TryGetValue(alias.Value, out valuePromise))
                {
                    valuePromise = new ValuePromise(alias);
                    aliasState.Add(alias.Value, valuePromise);
                }

                return(valuePromise.HasValue ? valuePromise.Value : valuePromise);
            }

            string anchor = null;

            var nodeEvent = reader.Peek <NodeEvent>();

            if (nodeEvent != null && !string.IsNullOrEmpty(nodeEvent.Anchor))
            {
                anchor = nodeEvent.Anchor;
            }

            value = innerDeserializer.DeserializeValue(reader, expectedType, state, nestedObjectDeserializer);

            if (anchor != null)
            {
                var aliasState = state.Get <AliasState>();

                ValuePromise valuePromise;
                if (!aliasState.TryGetValue(anchor, out valuePromise))
                {
                    aliasState.Add(anchor, new ValuePromise(value));
                }
                else if (!valuePromise.HasValue)
                {
                    valuePromise.Value = value;
                }
                else
                {
                    throw new DuplicateAnchorException(nodeEvent.Start, nodeEvent.End, string.Format(
                                                           "Anchor '{0}' already defined",
                                                           anchor
                                                           ));
                }
            }

            return(value);
        }
Beispiel #11
0
        /// <summary>
        /// Deserializes an object of the specified type.
        /// </summary>
        /// <param name="reader">The <see cref="EventReader" /> where to deserialize the object.</param>
        /// <param name="type">The static type of the object to deserialize.</param>
        /// <returns>Returns the deserialized object.</returns>
        public object Deserialize(EventReader reader, Type type, IValueDeserializer deserializer = null)
        {
            if (reader == null)
            {
                throw new ArgumentNullException("reader");
            }

            if (type == null)
            {
                throw new ArgumentNullException("type");
            }

            var hasStreamStart = reader.Allow <StreamStart>() != null;

            var hasDocumentStart = reader.Allow <DocumentStart>() != null;

            deserializer = deserializer ?? _valueDeserializer;
            object result = null;

            if (!reader.Accept <DocumentEnd>() && !reader.Accept <StreamEnd>())
            {
                using (var state = new SerializerState())
                {
                    result = deserializer.DeserializeValue(reader, type, state, deserializer);
                    state.OnDeserialization();
                }
            }

            if (hasDocumentStart)
            {
                reader.Expect <DocumentEnd>();
            }

            if (hasStreamStart)
            {
                reader.Expect <StreamEnd>();
            }

            return(result);
        }
        public bool Deserialize(EventReader reader, Type expectedType, Func<EventReader, Type, object> nestedObjectDeserializer, out object value)
        {
            if (reader == null)
            {
                value = null;
                return false;
            }

            // only try this if we're targeting a boolean or an untyped object
            if (expectedType == typeof(object) || expectedType == typeof(bool) ) 
            {
                // peek at the current token
                Scalar scalar = reader.Peek<Scalar>();

                // if it's unquoted 
                if (scalar != null && scalar.Style == ScalarStyle.Plain)
                {
                    // and the value is actually true or false
                    switch (scalar.Value.ToUpperInvariant())
                    {
                        case "TRUE":
                            value = true;
                            reader.Allow<Scalar>();
                            return true;
                        case "FALSE":
                            value = false;
                            reader.Allow<Scalar>();
                            return true;

                    }
                }
            }

            // otherwise, fall thru
            value = null;
            return false;
        }
Beispiel #13
0
        public bool Deserialize(EventReader reader, Type expectedType, Func <EventReader, Type, object> nestedObjectDeserializer, out object value)
        {
            if (reader == null)
            {
                value = null;
                return(false);
            }

            // only try this if we're targeting a boolean or an untyped object
            if (expectedType == typeof(object) || expectedType == typeof(bool))
            {
                // peek at the current token
                Scalar scalar = reader.Peek <Scalar>();

                // if it's unquoted
                if (scalar != null && scalar.Style == ScalarStyle.Plain)
                {
                    // and the value is actually true or false
                    switch (scalar.Value.ToUpperInvariant())
                    {
                    case "TRUE":
                        value = true;
                        reader.Allow <Scalar>();
                        return(true);

                    case "FALSE":
                        value = false;
                        reader.Allow <Scalar>();
                        return(true);
                    }
                }
            }

            // otherwise, fall thru
            value = null;
            return(false);
        }
        public object DeserializeValue(EventReader reader, Type expectedType, SerializerState state, IValueDeserializer nestedObjectDeserializer)
        {
            AnchorAlias alias = reader.Allow <AnchorAlias>();

            if (alias != null)
            {
                ValuePromise promise;
                AliasState   state2 = state.Get <AliasState>();
                if (!state2.TryGetValue(alias.Value, out promise))
                {
                    promise = new ValuePromise(alias);
                    state2.Add(alias.Value, promise);
                }
                return(!promise.HasValue ? promise : promise.Value);
            }
            string    key    = null;
            NodeEvent event2 = reader.Peek <NodeEvent>();

            if ((event2 != null) && !string.IsNullOrEmpty(event2.Anchor))
            {
                key = event2.Anchor;
            }
            object obj2 = this.innerDeserializer.DeserializeValue(reader, expectedType, state, nestedObjectDeserializer);

            if (key != null)
            {
                ValuePromise promise2;
                AliasState   state3 = state.Get <AliasState>();
                if (!state3.TryGetValue(key, out promise2))
                {
                    state3.Add(key, new ValuePromise(obj2));
                }
                else
                {
                    if (promise2.HasValue)
                    {
                        throw new DuplicateAnchorException(event2.Start, event2.End, $"Anchor '{key}' already defined");
                    }
                    promise2.Value = obj2;
                }
            }
            return(obj2);
        }
Beispiel #15
0
        bool INodeDeserializer.Deserialize(EventReader reader, Type expectedType, Func <EventReader, Type, object> nestedObjectDeserializer, out object value)
        {
            var mapping = reader.Allow <MappingStart>();

            if (mapping == null)
            {
                value = null;
                return(false);
            }

            value = _objectFactory.Create(expectedType);
            while (!reader.Accept <MappingEnd>())
            {
                var propertyName = reader.Expect <Scalar>();
                var property     = _typeDescriptor.GetProperty(expectedType, null, propertyName.Value, _ignoreUnmatched);
                if (property == null)
                {
                    reader.SkipThisAndNestedEvents();
                    continue;
                }

                var propertyValue        = nestedObjectDeserializer(reader, property.Type);
                var propertyValuePromise = propertyValue as IValuePromise;
                if (propertyValuePromise == null)
                {
                    var convertedValue = TypeConverter.ChangeType(propertyValue, property.Type);
                    property.Write(value, convertedValue);
                }
                else
                {
                    var valueRef = value;
                    propertyValuePromise.ValueAvailable += v =>
                    {
                        var convertedValue = TypeConverter.ChangeType(v, property.Type);
                        property.Write(valueRef, convertedValue);
                    };
                }
            }

            reader.Expect <MappingEnd>();
            return(true);
        }
		bool INodeDeserializer.Deserialize(EventReader reader, Type expectedType, Func<EventReader, Type, object> nestedObjectDeserializer, out object value)
		{
			var mapping = reader.Allow<MappingStart>();
			if (mapping == null)
			{
				value = null;
				return false;
			}
			
			value = _objectFactory.Create(expectedType);
			while (!reader.Accept<MappingEnd>())
			{
				var propertyName = reader.Expect<Scalar>();
				var property = _typeDescriptor.GetProperty(expectedType, null, propertyName.Value, _ignoreUnmatched);
				if (property == null)
				{
					reader.SkipThisAndNestedEvents();
					continue;
				}

				var propertyValue = nestedObjectDeserializer(reader, property.Type);
				var propertyValuePromise = propertyValue as IValuePromise;
				if (propertyValuePromise == null)
				{
					var convertedValue = TypeConverter.ChangeType(propertyValue, property.Type);
					property.Write(value, convertedValue);
				}
				else
				{
					var valueRef = value;
					propertyValuePromise.ValueAvailable += v =>
					{
						var convertedValue = TypeConverter.ChangeType(v, property.Type);
						property.Write(valueRef, convertedValue);
					};
				}
			}

			reader.Expect<MappingEnd>();
			return true;
		}
        public object DeserializeValue(EventReader reader, Type expectedType, SerializerState state, IValueDeserializer nestedObjectDeserializer)
        {
            object value;
            var    alias = reader.Allow <AnchorAlias>();

            if (alias != null)
            {
                var aliasState = state.Get <AliasState>();
                if (aliasState.TryGetValue(alias.Value, out value))
                {
                    return(value);
                }

                throw new AnchorNotFoundException(alias.Start, alias.End, string.Format(
                                                      "Anchor '{0}' not found",
                                                      alias.Value
                                                      ));
            }

            string anchor = null;

            var nodeEvent = reader.Peek <NodeEvent>();

            if (nodeEvent != null && !string.IsNullOrEmpty(nodeEvent.Anchor))
            {
                anchor = nodeEvent.Anchor;
            }

            value = innerDeserializer.DeserializeValue(reader, expectedType, state, nestedObjectDeserializer);

            if (anchor != null)
            {
                var aliasState = state.Get <AliasState>();
                aliasState.Add(anchor, value);
            }

            return(value);
        }
Beispiel #18
0
        bool INodeDeserializer.Deserialize(EventReader reader, Type expectedType, Func <EventReader, Type, object> nestedObjectDeserializer, out object value)
        {
            var mapping = reader.Allow <MappingStart>();

            if (mapping == null)
            {
                value = null;
                return(false);
            }

            value = _objectFactory.Create(expectedType);
            while (!reader.Accept <MappingEnd>())
            {
                var propertyName = reader.Expect <Scalar>();

                var property       = _typeDescriptor.GetProperty(expectedType, propertyName.Value).Property;
                var propertyValue  = nestedObjectDeserializer(reader, property.PropertyType);
                var convertedValue = TypeConverter.ChangeType(propertyValue, property.PropertyType);
                property.SetValue(value, convertedValue, null);
            }

            reader.Expect <MappingEnd>();
            return(true);
        }
        bool INodeDeserializer.Deserialize(EventReader reader, Type expectedType, Func <EventReader, Type, object> nestedObjectDeserializer, out object value)
        {
            Scalar scalar = reader.Allow <Scalar>();

            if (scalar == null)
            {
                value = null;
                return(false);
            }
            if (expectedType.IsEnum())
            {
                value = Enum.Parse(expectedType, scalar.Value, true);
            }
            else
            {
                TypeCode typeCode = expectedType.GetTypeCode();
                switch (typeCode)
                {
                case TypeCode.Boolean:
                    value = bool.Parse(scalar.Value);
                    break;

                case TypeCode.Char:
                    value = scalar.Value[0];
                    break;

                case TypeCode.SByte:
                case TypeCode.Byte:
                case TypeCode.Int16:
                case TypeCode.UInt16:
                case TypeCode.Int32:
                case TypeCode.UInt32:
                case TypeCode.Int64:
                case TypeCode.UInt64:
                    value = this.DeserializeIntegerHelper(typeCode, scalar.Value, YamlFormatter.NumberFormat);
                    break;

                case TypeCode.Single:
                    value = float.Parse(scalar.Value, YamlFormatter.NumberFormat);
                    break;

                case TypeCode.Double:
                    value = double.Parse(scalar.Value, YamlFormatter.NumberFormat);
                    break;

                case TypeCode.Decimal:
                    value = decimal.Parse(scalar.Value, YamlFormatter.NumberFormat);
                    break;

                case TypeCode.DateTime:
                    value = DateTime.Parse(scalar.Value, CultureInfo.InvariantCulture);
                    break;

                case TypeCode.String:
                    value = scalar.Value;
                    break;

                default:
                    value = !ReferenceEquals(expectedType, typeof(object)) ? TypeConverter.ChangeType(scalar.Value, expectedType) : scalar.Value;
                    break;
                }
            }
            return(true);
        }
Beispiel #20
0
        public static bool MigrateAssetIfNeeded(AssetMigrationContext context, PackageLoadingAssetFile loadAsset, string dependencyName, PackageVersion untilVersion = null)
        {
            var assetFullPath = loadAsset.FilePath.FullPath;

            // Determine if asset was Yaml or not
            var assetFileExtension = Path.GetExtension(assetFullPath);

            if (assetFileExtension == null)
            {
                return(false);
            }

            assetFileExtension = assetFileExtension.ToLowerInvariant();

            var serializer = AssetFileSerializer.FindSerializer(assetFileExtension);

            if (!(serializer is YamlAssetSerializer))
            {
                return(false);
            }

            // We've got a Yaml asset, let's get expected and serialized versions
            var            serializedVersion = PackageVersion.Zero;
            PackageVersion expectedVersion;
            Type           assetType;

            // Read from Yaml file the asset version and its type (to get expected version)
            // Note: It tries to read as few as possible (SerializedVersion is expected to be right after Id, so it shouldn't try to read further than that)
            using (var assetStream = loadAsset.OpenStream())
                using (var streamReader = new StreamReader(assetStream))
                {
                    var yamlEventReader = new EventReader(new Parser(streamReader));

                    // Skip header
                    yamlEventReader.Expect <StreamStart>();
                    yamlEventReader.Expect <DocumentStart>();
                    var mappingStart = yamlEventReader.Expect <MappingStart>();

                    var  tagTypeRegistry = AssetYamlSerializer.Default.GetSerializerSettings().TagTypeRegistry;
                    bool typeAliased;
                    assetType = tagTypeRegistry.TypeFromTag(mappingStart.Tag, out typeAliased);

                    var expectedVersions = AssetRegistry.GetCurrentFormatVersions(assetType);
                    expectedVersion = expectedVersions?.FirstOrDefault(x => x.Key == dependencyName).Value ?? PackageVersion.Zero;

                    Scalar assetKey;
                    while ((assetKey = yamlEventReader.Allow <Scalar>()) != null)
                    {
                        // Only allow Id before SerializedVersion
                        if (assetKey.Value == nameof(Asset.Id))
                        {
                            yamlEventReader.Skip();
                        }
                        else if (assetKey.Value == nameof(Asset.SerializedVersion))
                        {
                            // Check for old format: only a scalar
                            var scalarVersion = yamlEventReader.Allow <Scalar>();
                            if (scalarVersion != null)
                            {
                                serializedVersion = PackageVersion.Parse("0.0." + Convert.ToInt32(scalarVersion.Value, CultureInfo.InvariantCulture));

                                // Let's update to new format
                                using (var yamlAsset = loadAsset.AsYamlAsset())
                                {
                                    yamlAsset.DynamicRootNode.RemoveChild(nameof(Asset.SerializedVersion));
                                    AssetUpgraderBase.SetSerializableVersion(yamlAsset.DynamicRootNode, dependencyName, serializedVersion);

                                    var baseBranch = yamlAsset.DynamicRootNode["~Base"];
                                    if (baseBranch != null)
                                    {
                                        var baseAsset = baseBranch["Asset"];
                                        if (baseAsset != null)
                                        {
                                            baseAsset.RemoveChild(nameof(Asset.SerializedVersion));
                                            AssetUpgraderBase.SetSerializableVersion(baseAsset, dependencyName, serializedVersion);
                                        }
                                    }
                                }
                            }
                            else
                            {
                                // New format: package => version mapping
                                yamlEventReader.Expect <MappingStart>();

                                while (!yamlEventReader.Accept <MappingEnd>())
                                {
                                    var packageName    = yamlEventReader.Expect <Scalar>().Value;
                                    var packageVersion = PackageVersion.Parse(yamlEventReader.Expect <Scalar>().Value);

                                    // For now, we handle only one dependency at a time
                                    if (packageName == dependencyName)
                                    {
                                        serializedVersion = packageVersion;
                                    }
                                }

                                yamlEventReader.Expect <MappingEnd>();
                            }
                            break;
                        }
                        else
                        {
                            // If anything else than Id or SerializedVersion, let's stop
                            break;
                        }
                    }
                }

            if (serializedVersion > expectedVersion)
            {
                // Try to open an asset newer than what we support (probably generated by a newer Stride)
                throw new InvalidOperationException($"Asset of type {assetType} has been serialized with newer version {serializedVersion}, but only version {expectedVersion} is supported. Was this asset created with a newer version of Stride?");
            }

            if (serializedVersion < expectedVersion)
            {
                // Perform asset upgrade
                context.Log.Verbose($"{Path.GetFullPath(assetFullPath)} needs update, from version {serializedVersion} to version {expectedVersion}");

                using (var yamlAsset = loadAsset.AsYamlAsset())
                {
                    var yamlRootNode = yamlAsset.RootNode;

                    // Check if there is any asset updater
                    var assetUpgraders = AssetRegistry.GetAssetUpgraders(assetType, dependencyName);
                    if (assetUpgraders == null)
                    {
                        throw new InvalidOperationException($"Asset of type {assetType} should be updated from version {serializedVersion} to {expectedVersion}, but no asset migration path was found");
                    }

                    // Instantiate asset updaters
                    var currentVersion = serializedVersion;
                    while (currentVersion != expectedVersion)
                    {
                        PackageVersion targetVersion;
                        // This will throw an exception if no upgrader is available for the given version, exiting the loop in case of error.
                        var upgrader = assetUpgraders.GetUpgrader(currentVersion, out targetVersion);

                        // Stop if the next version would be higher than what is expected
                        if (untilVersion != null && targetVersion > untilVersion)
                        {
                            break;
                        }

                        upgrader.Upgrade(context, dependencyName, currentVersion, targetVersion, yamlRootNode, loadAsset);
                        currentVersion = targetVersion;
                    }

                    // Make sure asset is updated to latest version
                    YamlNode       serializedVersionNode;
                    PackageVersion newSerializedVersion = null;
                    if (yamlRootNode.Children.TryGetValue(new YamlScalarNode(nameof(Asset.SerializedVersion)), out serializedVersionNode))
                    {
                        var newSerializedVersionForDefaultPackage = ((YamlMappingNode)serializedVersionNode).Children[new YamlScalarNode(dependencyName)];
                        newSerializedVersion = PackageVersion.Parse(((YamlScalarNode)newSerializedVersionForDefaultPackage).Value);
                    }

                    if (untilVersion == null && newSerializedVersion != expectedVersion)
                    {
                        throw new InvalidOperationException($"Asset of type {assetType} was migrated, but still its new version {newSerializedVersion} doesn't match expected version {expectedVersion}.");
                    }

                    context.Log.Verbose($"{Path.GetFullPath(assetFullPath)} updated from version {serializedVersion} to version {expectedVersion}");
                }

                return(true);
            }

            return(false);
        }
Beispiel #21
0
        bool INodeDeserializer.Deserialize(EventReader reader, Type expectedType, Func <EventReader, Type, object> nestedObjectDeserializer, out object value)
        {
            var scalar = reader.Allow <Scalar>();

            if (scalar == null)
            {
                value = null;
                return(false);
            }

            if (expectedType.IsEnum)
            {
                value = Enum.Parse(expectedType, scalar.Value);
            }
            else
            {
                TypeCode typeCode = Type.GetTypeCode(expectedType);
                switch (typeCode)
                {
                case TypeCode.Boolean:
                    value = bool.Parse(scalar.Value);
                    break;

                case TypeCode.Byte:
                    value = Byte.Parse(scalar.Value, numberFormat);
                    break;

                case TypeCode.Int16:
                    value = Int16.Parse(scalar.Value, numberFormat);
                    break;

                case TypeCode.Int32:
                    value = Int32.Parse(scalar.Value, numberFormat);
                    break;

                case TypeCode.Int64:
                    value = Int64.Parse(scalar.Value, numberFormat);
                    break;

                case TypeCode.SByte:
                    value = SByte.Parse(scalar.Value, numberFormat);
                    break;

                case TypeCode.UInt16:
                    value = UInt16.Parse(scalar.Value, numberFormat);
                    break;

                case TypeCode.UInt32:
                    value = UInt32.Parse(scalar.Value, numberFormat);
                    break;

                case TypeCode.UInt64:
                    value = UInt64.Parse(scalar.Value, numberFormat);
                    break;

                case TypeCode.Single:
                    value = Single.Parse(scalar.Value, numberFormat);
                    break;

                case TypeCode.Double:
                    value = Double.Parse(scalar.Value, numberFormat);
                    break;

                case TypeCode.Decimal:
                    value = Decimal.Parse(scalar.Value, numberFormat);
                    break;

                case TypeCode.String:
                    value = scalar.Value;
                    break;

                case TypeCode.Char:
                    value = scalar.Value[0];
                    break;

                case TypeCode.DateTime:
                    // TODO: This is probably incorrect. Use the correct regular expression.
                    value = DateTime.Parse(scalar.Value, CultureInfo.InvariantCulture);
                    break;

                default:
                    if (expectedType == typeof(object))
                    {
                        // Default to string
                        value = scalar.Value;
                    }
                    else
                    {
                        value = TypeConverter.ChangeType(scalar.Value, expectedType);
                    }
                    break;
                }
            }
            return(true);
        }
        public static bool MigrateAssetIfNeeded(AssetMigrationContext context, PackageLoadingAssetFile loadAsset, string dependencyName, PackageVersion untilVersion = null)
        {
            var assetFullPath = loadAsset.FilePath.FullPath;

            // Determine if asset was Yaml or not
            var assetFileExtension = Path.GetExtension(assetFullPath);
            if (assetFileExtension == null)
                return false;

            assetFileExtension = assetFileExtension.ToLowerInvariant();

            var serializer = AssetFileSerializer.FindSerializer(assetFileExtension);
            if (!(serializer is YamlAssetSerializer))
                return false;

            // We've got a Yaml asset, let's get expected and serialized versions
            var serializedVersion = PackageVersion.Zero;
            PackageVersion expectedVersion;
            Type assetType;

            // Read from Yaml file the asset version and its type (to get expected version)
            // Note: It tries to read as few as possible (SerializedVersion is expected to be right after Id, so it shouldn't try to read further than that)
            using (var assetStream = loadAsset.OpenStream())
            using (var streamReader = new StreamReader(assetStream))
            {
                var yamlEventReader = new EventReader(new Parser(streamReader));

                // Skip header
                yamlEventReader.Expect<StreamStart>();
                yamlEventReader.Expect<DocumentStart>();
                var mappingStart = yamlEventReader.Expect<MappingStart>();

                var tagTypeRegistry = AssetYamlSerializer.Default.GetSerializerSettings().TagTypeRegistry;
                bool typeAliased;
                assetType = tagTypeRegistry.TypeFromTag(mappingStart.Tag, out typeAliased);

                var expectedVersions = AssetRegistry.GetCurrentFormatVersions(assetType);
                expectedVersion = expectedVersions?.FirstOrDefault(x => x.Key == dependencyName).Value ?? PackageVersion.Zero;

                Scalar assetKey;
                while ((assetKey = yamlEventReader.Allow<Scalar>()) != null)
                {
                    // Only allow Id before SerializedVersion
                    if (assetKey.Value == nameof(Asset.Id))
                    {
                        yamlEventReader.Skip();
                    }
                    else if (assetKey.Value == nameof(Asset.SerializedVersion))
                    {
                        // Check for old format: only a scalar
                        var scalarVersion = yamlEventReader.Allow<Scalar>();
                        if (scalarVersion != null)
                        {
                            serializedVersion = PackageVersion.Parse("0.0." + Convert.ToInt32(scalarVersion.Value, CultureInfo.InvariantCulture));

                            // Let's update to new format
                            using (var yamlAsset = loadAsset.AsYamlAsset())
                            {
                                yamlAsset.DynamicRootNode.RemoveChild(nameof(Asset.SerializedVersion));
                                AssetUpgraderBase.SetSerializableVersion(yamlAsset.DynamicRootNode, dependencyName, serializedVersion);

                                var baseBranch = yamlAsset.DynamicRootNode["~Base"];
                                if (baseBranch != null)
                                {
                                    var baseAsset = baseBranch["Asset"];
                                    if (baseAsset != null)
                                    {
                                        baseAsset.RemoveChild(nameof(Asset.SerializedVersion));
                                        AssetUpgraderBase.SetSerializableVersion(baseAsset, dependencyName, serializedVersion);
                                    }
                                }
                            }
                        }
                        else
                        {
                            // New format: package => version mapping
                            yamlEventReader.Expect<MappingStart>();

                            while (!yamlEventReader.Accept<MappingEnd>())
                            {
                                var packageName = yamlEventReader.Expect<Scalar>().Value;
                                var packageVersion = PackageVersion.Parse(yamlEventReader.Expect<Scalar>().Value);

                                // For now, we handle only one dependency at a time
                                if (packageName == dependencyName)
                                {
                                    serializedVersion = packageVersion;
                                }
                            }

                            yamlEventReader.Expect<MappingEnd>();
                        }
                        break;
                    }
                    else
                    {
                        // If anything else than Id or SerializedVersion, let's stop
                        break;
                    }
                }
            }

            if (serializedVersion > expectedVersion)
            {
                // Try to open an asset newer than what we support (probably generated by a newer Xenko)
                throw new InvalidOperationException($"Asset of type {assetType} has been serialized with newer version {serializedVersion}, but only version {expectedVersion} is supported. Was this asset created with a newer version of Xenko?");
            }

            if (serializedVersion < expectedVersion)
            {
                // Perform asset upgrade
                context.Log.Verbose("{0} needs update, from version {1} to version {2}", Path.GetFullPath(assetFullPath), serializedVersion, expectedVersion);

                using (var yamlAsset = loadAsset.AsYamlAsset())
                {
                    var yamlRootNode = yamlAsset.RootNode;

                    // Check if there is any asset updater
                    var assetUpgraders = AssetRegistry.GetAssetUpgraders(assetType, dependencyName);
                    if (assetUpgraders == null)
                    {
                        throw new InvalidOperationException($"Asset of type {assetType} should be updated from version {serializedVersion} to {expectedVersion}, but no asset migration path was found");
                    }

                    // Instantiate asset updaters
                    var currentVersion = serializedVersion;
                    while (currentVersion != expectedVersion)
                    {
                        PackageVersion targetVersion;
                        // This will throw an exception if no upgrader is available for the given version, exiting the loop in case of error.
                        var upgrader = assetUpgraders.GetUpgrader(currentVersion, out targetVersion);

                        // Stop if the next version would be higher than what is expected
                        if (untilVersion != null && targetVersion > untilVersion)
                            break;

                        upgrader.Upgrade(context, dependencyName, currentVersion, targetVersion, yamlRootNode, loadAsset);
                        currentVersion = targetVersion;
                    }

                    // Make sure asset is updated to latest version
                    YamlNode serializedVersionNode;
                    PackageVersion newSerializedVersion = null;
                    if (yamlRootNode.Children.TryGetValue(new YamlScalarNode(nameof(Asset.SerializedVersion)), out serializedVersionNode))
                    {
                        var newSerializedVersionForDefaultPackage = ((YamlMappingNode)serializedVersionNode).Children[new YamlScalarNode(dependencyName)];
                        newSerializedVersion = PackageVersion.Parse(((YamlScalarNode)newSerializedVersionForDefaultPackage).Value);
                    }

                    if (untilVersion == null && newSerializedVersion != expectedVersion)
                    {
                        throw new InvalidOperationException($"Asset of type {assetType} was migrated, but still its new version {newSerializedVersion} doesn't match expected version {expectedVersion}.");
                    }

                    context.Log.Info("{0} updated from version {1} to version {2}", Path.GetFullPath(assetFullPath), serializedVersion, expectedVersion);
                }

                return true;
            }

            return false;
        }
Beispiel #23
0
        public static bool MigrateAssetIfNeeded(AssetMigrationContext context, PackageLoadingAssetFile loadAsset)
        {
            var assetFullPath = loadAsset.FilePath.FullPath;

            // Determine if asset was Yaml or not
            var assetFileExtension = Path.GetExtension(assetFullPath);

            if (assetFileExtension == null)
            {
                return(false);
            }

            assetFileExtension = assetFileExtension.ToLowerInvariant();

            var serializer = AssetSerializer.FindSerializer(assetFileExtension);

            if (!(serializer is AssetYamlSerializer))
            {
                return(false);
            }

            // We've got a Yaml asset, let's get expected and serialized versions
            var  serializedVersion = 0;
            int  expectedVersion;
            Type assetType;

            // Read from Yaml file the asset version and its type (to get expected version)
            // Note: It tries to read as few as possible (SerializedVersion is expected to be right after Id, so it shouldn't try to read further than that)
            using (var assetStream = loadAsset.OpenStream())
                using (var streamReader = new StreamReader(assetStream))
                {
                    var yamlEventReader = new EventReader(new Parser(streamReader));

                    // Skip header
                    yamlEventReader.Expect <StreamStart>();
                    yamlEventReader.Expect <DocumentStart>();
                    var mappingStart = yamlEventReader.Expect <MappingStart>();

                    var  yamlSerializerSettings = YamlSerializer.GetSerializerSettings();
                    var  tagTypeRegistry        = yamlSerializerSettings.TagTypeRegistry;
                    bool typeAliased;
                    assetType = tagTypeRegistry.TypeFromTag(mappingStart.Tag, out typeAliased);

                    expectedVersion = AssetRegistry.GetCurrentFormatVersion(assetType);

                    Scalar assetKey;
                    while ((assetKey = yamlEventReader.Allow <Scalar>()) != null)
                    {
                        // Only allow Id before SerializedVersion
                        if (assetKey.Value == "Id")
                        {
                            yamlEventReader.Skip();
                            continue;
                        }
                        if (assetKey.Value == "SerializedVersion")
                        {
                            serializedVersion = Convert.ToInt32(yamlEventReader.Expect <Scalar>().Value, CultureInfo.InvariantCulture);
                            break;
                        }
                    }
                }

            if (serializedVersion > expectedVersion)
            {
                // Try to open an asset newer than what we support (probably generated by a newer Paradox)
                throw new InvalidOperationException(string.Format("Asset of type {0} has been serialized with newer version {1}, but only version {2} is supported. Was this asset created with a newer version of Paradox?", assetType, serializedVersion, expectedVersion));
            }

            if (serializedVersion < expectedVersion)
            {
                // Perform asset upgrade
                context.Log.Verbose("{0} needs update, from version {1} to version {2}", Path.GetFullPath(assetFullPath), serializedVersion, expectedVersion);

                // transform the stream into string.
                string assetAsString;
                using (var assetStream = loadAsset.OpenStream())
                    using (var assetStreamReader = new StreamReader(assetStream, Encoding.UTF8))
                    {
                        assetAsString = assetStreamReader.ReadToEnd();
                    }

                // Load the asset as a YamlNode object
                var input      = new StringReader(assetAsString);
                var yamlStream = new YamlStream();
                yamlStream.Load(input);
                var yamlRootNode = (YamlMappingNode)yamlStream.Documents[0].RootNode;

                // Check if there is any asset updater
                var assetUpgraders = AssetRegistry.GetAssetUpgraders(assetType);
                if (assetUpgraders == null)
                {
                    throw new InvalidOperationException(string.Format("Asset of type {0} should be updated from version {1} to {2}, but no asset migration path was found", assetType, serializedVersion, expectedVersion));
                }

                // Instantiate asset updaters
                var currentVersion = serializedVersion;
                while (currentVersion != expectedVersion)
                {
                    int targetVersion;
                    // This will throw an exception if no upgrader is available for the given version, exiting the loop in case of error.
                    var upgrader = assetUpgraders.GetUpgrader(currentVersion, out targetVersion);
                    upgrader.Upgrade(context, currentVersion, targetVersion, yamlRootNode, loadAsset);
                    currentVersion = targetVersion;
                }

                // Make sure asset is updated to latest version
                YamlNode serializedVersionNode;
                var      newSerializedVersion = 0;
                if (yamlRootNode.Children.TryGetValue(new YamlScalarNode("SerializedVersion"), out serializedVersionNode))
                {
                    newSerializedVersion = Convert.ToInt32(((YamlScalarNode)serializedVersionNode).Value);
                }

                if (newSerializedVersion != expectedVersion)
                {
                    throw new InvalidOperationException(string.Format("Asset of type {0} was migrated, but still its new version {1} doesn't match expected version {2}.", assetType, newSerializedVersion, expectedVersion));
                }

                context.Log.Info("{0} updated from version {1} to version {2}", Path.GetFullPath(assetFullPath), serializedVersion, expectedVersion);

                var preferredIndent = YamlSerializer.GetSerializerSettings().PreferredIndent;

                // Save asset back to disk
                using (var memoryStream = new MemoryStream())
                {
                    using (var streamWriter = new StreamWriter(memoryStream))
                    {
                        yamlStream.Save(streamWriter, true, preferredIndent);
                    }
                    loadAsset.AssetContent = memoryStream.ToArray();
                }

                return(true);
            }

            return(false);
        }
Beispiel #24
0
        public static bool MigrateAssetIfNeeded(ILogger log, string assetFullPath)
        {
            // Determine if asset was Yaml or not
            var assetFileExtension = Path.GetExtension(assetFullPath);

            if (assetFileExtension == null)
            {
                return(false);
            }

            assetFileExtension = assetFileExtension.ToLowerInvariant();

            var serializer = AssetSerializer.FindSerializer(assetFileExtension);

            if (!(serializer is AssetYamlSerializer))
            {
                return(false);
            }

            // We've got a Yaml asset, let's get expected and serialized versions
            var  serializedVersion = 0;
            var  expectedVersion   = 0;
            Type assetType;

            // Read from Yaml file the asset version and its type (to get expected version)
            // Note: It tries to read as few as possible (SerializedVersion is expected to be right after Id, so it shouldn't try to read further than that)
            using (var streamReader = new StreamReader(assetFullPath))
            {
                var yamlEventReader = new EventReader(new Parser(streamReader));

                // Skip header
                yamlEventReader.Expect <StreamStart>();
                yamlEventReader.Expect <DocumentStart>();
                var mappingStart = yamlEventReader.Expect <MappingStart>();

                var yamlSerializerSettings = YamlSerializer.GetSerializerSettings();
                var tagTypeRegistry        = yamlSerializerSettings.TagTypeRegistry;
                assetType = tagTypeRegistry.TypeFromTag(mappingStart.Tag);

                expectedVersion = AssetRegistry.GetFormatVersion(assetType);

                Scalar assetKey;
                while ((assetKey = yamlEventReader.Allow <Scalar>()) != null)
                {
                    // Only allow Id before SerializedVersion
                    if (assetKey.Value == "Id")
                    {
                        yamlEventReader.Skip();
                        continue;
                    }
                    if (assetKey.Value == "SerializedVersion")
                    {
                        serializedVersion = Convert.ToInt32(yamlEventReader.Expect <Scalar>().Value, CultureInfo.InvariantCulture);
                        break;
                    }
                }
            }

            if (serializedVersion > expectedVersion)
            {
                // Try to open an asset newer than what we support (probably generated by a newer Paradox)
                throw new InvalidOperationException(string.Format("Asset of type {0} has been serialized with newer version {1}, but only version {2} is supported. Was this asset created with a newer version of Paradox?", assetType, serializedVersion, expectedVersion));
            }

            if (serializedVersion < expectedVersion)
            {
                // Perform asset upgrade
                log.Info("{0} needs update, from version {0} to version {1}", Path.GetFullPath(assetFullPath), serializedVersion, expectedVersion);

                // Load the asset as a YamlNode object
                var input      = new StringReader(File.ReadAllText(assetFullPath));
                var yamlStream = new YamlStream();
                yamlStream.Load(input);
                var yamlRootNode = (YamlMappingNode)yamlStream.Documents[0].RootNode;

                // Check if there is any asset updater
                var assetUpdaterTypes = AssetRegistry.GetFormatVersionUpdaterTypes(assetType);
                if (assetUpdaterTypes == null)
                {
                    throw new InvalidOperationException(string.Format("Asset of type {0} should be updated from version {1} to {2}, but no asset migration path was found", assetType, serializedVersion, expectedVersion));
                }

                // Instantiate asset updaters
                var assetUpgraders = assetUpdaterTypes.Select(x => (IAssetUpgrader)Activator.CreateInstance(x)).ToArray();

                // TODO: Select best asset updater if more than one (need to check from what to what version they update, score, if multiple need to be chained, etc...)
                // I think it's better to wait for some actual scenarios to implement this right the first time
                if (assetUpgraders.Length != 1)
                {
                    throw new InvalidOperationException(string.Format("Asset of type {0} has multiple migration paths, but selecting the right one is not implemented yet.", assetType));
                }

                // Perform upgrade
                assetUpgraders[0].Upgrade(log, yamlRootNode);

                // Make sure asset is updated to latest version
                YamlNode serializedVersionNode;
                serializedVersion = 0;
                if (yamlRootNode.Children.TryGetValue(new YamlScalarNode("SerializedVersion"), out serializedVersionNode))
                {
                    serializedVersion = Convert.ToInt32(((YamlScalarNode)serializedVersionNode).Value);
                }

                if (serializedVersion != expectedVersion)
                {
                    throw new InvalidOperationException(string.Format("Asset of type {0} was migrated, but still its new version {1} doesn't match expected version {2}.", assetType, serializedVersion, expectedVersion));
                }

                var preferredIndent = YamlSerializer.GetSerializerSettings().PreferredIndent;

                // Save asset back to disk
                using (var streamWriter = new StreamWriter(assetFullPath))
                    yamlStream.Save(streamWriter, true, preferredIndent);

                return(true);
            }

            return(false);
        }
		bool INodeDeserializer.Deserialize(EventReader reader, Type expectedType, Func<EventReader, Type, object> nestedObjectDeserializer, out object value)
		{
			var scalar = reader.Allow<Scalar>();
			if (scalar == null)
			{
				value = null;
				return false;
			}

			if (expectedType.IsEnum())
			{
				value = Enum.Parse(expectedType, scalar.Value);
			}
			else
			{
				TypeCode typeCode = expectedType.GetTypeCode();
				switch (typeCode)
				{
					case TypeCode.Boolean:
						value = bool.Parse(scalar.Value);
						break;

					case TypeCode.Byte:
					case TypeCode.Int16:
					case TypeCode.Int32:
					case TypeCode.Int64:
					case TypeCode.SByte:
					case TypeCode.UInt16:
					case TypeCode.UInt32:
					case TypeCode.UInt64:
						value = DeserializeIntegerHelper(typeCode, scalar.Value, YamlFormatter.NumberFormat);
						break;

					case TypeCode.Single:
						value = Single.Parse(scalar.Value, YamlFormatter.NumberFormat);
						break;

					case TypeCode.Double:
						value = Double.Parse(scalar.Value, YamlFormatter.NumberFormat);
						break;

					case TypeCode.Decimal:
						value = Decimal.Parse(scalar.Value, YamlFormatter.NumberFormat);
						break;

					case TypeCode.String:
						value = scalar.Value;
						break;

					case TypeCode.Char:
						value = scalar.Value[0];
						break;

					case TypeCode.DateTime:
						// TODO: This is probably incorrect. Use the correct regular expression.
						value = DateTime.Parse(scalar.Value, CultureInfo.InvariantCulture);
						break;

					default:
						if (expectedType == typeof(object))
						{
							// Default to string
							value = scalar.Value;
						}
						else
						{
							value = TypeConverter.ChangeType(scalar.Value, expectedType);
						}
						break;
				}
			}
			return true;
		}
Beispiel #26
0
        public static bool MigrateAssetIfNeeded(AssetMigrationContext context, PackageLoadingAssetFile loadAsset)
        {
            var assetFullPath = loadAsset.FilePath.FullPath;

            // Determine if asset was Yaml or not
            var assetFileExtension = Path.GetExtension(assetFullPath);
            if (assetFileExtension == null)
                return false;

            assetFileExtension = assetFileExtension.ToLowerInvariant();

            var serializer = AssetSerializer.FindSerializer(assetFileExtension);
            if (!(serializer is AssetYamlSerializer))
                return false;

            // We've got a Yaml asset, let's get expected and serialized versions
            var serializedVersion = 0;
            int expectedVersion;
            Type assetType;

            // Read from Yaml file the asset version and its type (to get expected version)
            // Note: It tries to read as few as possible (SerializedVersion is expected to be right after Id, so it shouldn't try to read further than that)
            using (var assetStream = loadAsset.OpenStream())
            using (var streamReader = new StreamReader(assetStream))
            {
                var yamlEventReader = new EventReader(new Parser(streamReader));

                // Skip header
                yamlEventReader.Expect<StreamStart>();
                yamlEventReader.Expect<DocumentStart>();
                var mappingStart = yamlEventReader.Expect<MappingStart>();

                var yamlSerializerSettings = YamlSerializer.GetSerializerSettings();
                var tagTypeRegistry = yamlSerializerSettings.TagTypeRegistry;
                bool typeAliased;
                assetType = tagTypeRegistry.TypeFromTag(mappingStart.Tag, out typeAliased);

                expectedVersion = AssetRegistry.GetCurrentFormatVersion(assetType);

                Scalar assetKey;
                while ((assetKey = yamlEventReader.Allow<Scalar>()) != null)
                {
                    // Only allow Id before SerializedVersion
                    if (assetKey.Value == "Id")
                    {
                        yamlEventReader.Skip();
                        continue;
                    }
                    if (assetKey.Value == "SerializedVersion")
                    {
                        serializedVersion = Convert.ToInt32(yamlEventReader.Expect<Scalar>().Value, CultureInfo.InvariantCulture);
                        break;
                    }
                }
            }

            if (serializedVersion > expectedVersion)
            {
                // Try to open an asset newer than what we support (probably generated by a newer Paradox)
                throw new InvalidOperationException(string.Format("Asset of type {0} has been serialized with newer version {1}, but only version {2} is supported. Was this asset created with a newer version of Paradox?", assetType, serializedVersion, expectedVersion));
            }

            if (serializedVersion < expectedVersion)
            {
                // Perform asset upgrade
                context.Log.Verbose("{0} needs update, from version {1} to version {2}", Path.GetFullPath(assetFullPath), serializedVersion, expectedVersion);

                // transform the stream into string.
                string assetAsString;
                using (var assetStream = loadAsset.OpenStream())
                using (var assetStreamReader = new StreamReader(assetStream, Encoding.UTF8))
                {
                    assetAsString = assetStreamReader.ReadToEnd();
                }

                // Load the asset as a YamlNode object
                var input = new StringReader(assetAsString);
                var yamlStream = new YamlStream();
                yamlStream.Load(input);
                var yamlRootNode = (YamlMappingNode)yamlStream.Documents[0].RootNode;

                // Check if there is any asset updater
                var assetUpgraders = AssetRegistry.GetAssetUpgraders(assetType);
                if (assetUpgraders == null)
                {
                    throw new InvalidOperationException(string.Format("Asset of type {0} should be updated from version {1} to {2}, but no asset migration path was found", assetType, serializedVersion, expectedVersion));
                }

                // Instantiate asset updaters
                var currentVersion = serializedVersion;
                while (currentVersion != expectedVersion)
                {
                    int targetVersion;
                    // This will throw an exception if no upgrader is available for the given version, exiting the loop in case of error.
                    var upgrader = assetUpgraders.GetUpgrader(currentVersion, out targetVersion);
                    upgrader.Upgrade(context, currentVersion, targetVersion, yamlRootNode, loadAsset);
                    currentVersion = targetVersion;
                }

                // Make sure asset is updated to latest version
                YamlNode serializedVersionNode;
                var newSerializedVersion = 0;
                if (yamlRootNode.Children.TryGetValue(new YamlScalarNode("SerializedVersion"), out serializedVersionNode))
                {
                    newSerializedVersion = Convert.ToInt32(((YamlScalarNode)serializedVersionNode).Value);
                }

                if (newSerializedVersion != expectedVersion)
                {
                    throw new InvalidOperationException(string.Format("Asset of type {0} was migrated, but still its new version {1} doesn't match expected version {2}.", assetType, newSerializedVersion, expectedVersion));
                }

                context.Log.Info("{0} updated from version {1} to version {2}", Path.GetFullPath(assetFullPath), serializedVersion, expectedVersion);

                var preferredIndent = YamlSerializer.GetSerializerSettings().PreferredIndent;

                // Save asset back to disk
                using (var memoryStream = new MemoryStream())
                {
                    using (var streamWriter = new StreamWriter(memoryStream))
                    {
                        yamlStream.Save(streamWriter, true, preferredIndent);
                    }
                    loadAsset.AssetContent = memoryStream.ToArray();
                }

                return true;
            }

            return false;
        }
Beispiel #27
0
        /// <summary>
        /// Deserializes an object of the specified type.
        /// </summary>
        /// <param name="reader">The <see cref="EventReader" /> where to deserialize the object.</param>
        /// <param name="type">The static type of the object to deserialize.</param>
        /// <param name="options">Options that control how the deserialization is to be performed.</param>
        /// <returns>Returns the deserialized object.</returns>
        public object Deserialize(EventReader reader, Type type, DeserializationOptions options = DeserializationOptions.None)
        {
            if (reader == null)
            {
                throw new ArgumentNullException("reader");
            }

            if (type == null)
            {
                throw new ArgumentNullException("type");
            }

            var hasStreamStart = reader.Allow<StreamStart>() != null;

            var hasDocumentStart = reader.Allow<DocumentStart>() != null;

            if (hasDocumentStart)
            {
                reader.Expect<DocumentEnd>();
            }

            if (hasStreamStart)
            {
                reader.Expect<StreamEnd>();
            }
        }
Beispiel #28
0
        public static YamlValue Load(EventReader eventReader, YamlNodeTracker tracker = null)
        {
            var scalar = eventReader.Allow <Scalar>();

            return(new YamlValue(scalar, tracker));
        }