Пример #1
0
#pragma warning disable CS1591
        // Deserialize.
        public void Deserialize(Stream stream, out IDictionary <SettingKey, object> values, out SettingsMetadata metadata)
        {
            // build JSON document
            using var jsonDocument = JsonDocument.Parse(stream);

            // read metadata
            var rootJsonElement = jsonDocument.RootElement;

            if (rootJsonElement.ValueKind != JsonValueKind.Object)
            {
                throw new ArgumentException("Invalid root JSON element.");
            }
            var version = rootJsonElement.GetProperty("Version").Let((it) =>
            {
                if (it.ValueKind == JsonValueKind.Undefined)
                {
                    return(0);
                }
                return(it.GetInt32());
            });
            var lastModifiedTime = rootJsonElement.GetProperty("LastModifiedTime").Let((it) =>
            {
                if (it.ValueKind == JsonValueKind.Undefined)
                {
                    return(DateTime.Now);
                }
                return(DateTime.FromBinary(it.GetInt64()));
            });

            // read keys and values
            var keyValues = new Dictionary <SettingKey, object>();

            rootJsonElement.GetProperty("Values").Let((jsonValuesArray) =>
            {
                if (jsonValuesArray.ValueKind == JsonValueKind.Undefined)
                {
                    return;
                }
                foreach (var jsonValueEntry in jsonValuesArray.EnumerateArray())
                {
                    var name         = jsonValueEntry.GetProperty("Name").GetString().AsNonNull();
                    var typeName     = jsonValueEntry.GetProperty("Type").GetString().AsNonNull();
                    var defaultValue = this.ReadJsonValue(jsonValueEntry.GetProperty("Default"), typeName);
                    var value        = this.ReadJsonValue(jsonValueEntry.GetProperty("Value"), typeName);
                    keyValues[new SettingKey(name, defaultValue.GetType(), defaultValue)] = value;
                }
            });

            // complete
            values   = keyValues;
            metadata = new SettingsMetadata(version, lastModifiedTime);
        }
Пример #2
0
#pragma warning disable CS1591
        // Deserialize.
        public void Deserialize(Stream stream, out IDictionary <SettingKey, object> values, out SettingsMetadata metadata)
        {
            // parse document
            var xmlDocument = new XmlDocument();

            xmlDocument.Load(stream);

            // find root element
            var settingsElement = xmlDocument.FirstChild.Let((node) =>
            {
                while (node != null)
                {
                    if (node.NodeType == XmlNodeType.Element && node.Name == "Settings")
                    {
                        return(node);
                    }
                    node = node.NextSibling;
                }
                return(null);
            }) ?? throw new XmlException("No 'Settings' element.");

            // get metadata and values
            var version          = (int?)null;
            var lastModifiedTime = (DateTime?)null;
            var keyValues        = new Dictionary <SettingKey, object>();
            var node             = settingsElement.FirstChild;

            while (node != null)
            {
                try
                {
                    if (node.NodeType != XmlNodeType.Element)
                    {
                        continue;
                    }
                    switch (node.Name)
                    {
                    case "Version":
                        if (version != null)
                        {
                            throw new XmlException("Duplicate 'Version' specified.");
                        }
                        version = node.Let((_) =>
                        {
                            if (!node.HasChildNodes)
                            {
                                return(null);
                            }
                            return(node.FirstChild?.Let((it) =>
                            {
                                if (it.NodeType == XmlNodeType.Text && int.TryParse(it.Value, out var intValue))
                                {
                                    return (int?)intValue;
                                }
                                return null;
                            }));
                        });
                        break;

                    case "LastModifiedTime":
                        if (lastModifiedTime != null)
                        {
                            throw new XmlException("Duplicate 'LastModifiedTime' specified.");
                        }
                        lastModifiedTime = node.Let((_) =>
                        {
                            if (!node.HasChildNodes)
                            {
                                return(null);
                            }
                            return(node.FirstChild?.Let((it) =>
                            {
                                if (it.NodeType == XmlNodeType.Text && long.TryParse(it.Value, out var longValue))
                                {
                                    return (DateTime?)DateTime.FromBinary(longValue);
                                }
                                return null;
                            }));
                        });
                        break;

                    case "Values":
                        if (node.HasChildNodes)
                        {
                            var keyValueNode = node.FirstChild;
                            while (keyValueNode != null)
                            {
                                try
                                {
                                    if (keyValueNode.NodeType != XmlNodeType.Element || keyValueNode.Name != "Value" || !keyValueNode.HasChildNodes)
                                    {
                                        continue;
                                    }
                                    var name         = (string?)null;
                                    var typeName     = (string?)null;
                                    var defaultValue = (object?)null;
                                    var value        = (object?)null;
                                    var childNode    = keyValueNode.FirstChild;
                                    while (childNode != null)
                                    {
                                        try
                                        {
                                            if (childNode.NodeType != XmlNodeType.Element || !childNode.HasChildNodes)
                                            {
                                                continue;
                                            }
                                            switch (childNode.Name)
                                            {
                                            case "Name":
                                                name = childNode.FirstChild?.Value;
                                                break;

                                            case "Type":
                                                typeName = childNode.FirstChild?.Value;
                                                break;

                                            case "Default":
                                                if (typeName == null)
                                                {
                                                    throw new XmlException($"No type of setting value specified for '{name}'.");
                                                }
                                                defaultValue = this.ReadXmlValue(childNode.FirstChild.AsNonNull(), typeName);
                                                break;

                                            case "Value":
                                                if (typeName == null)
                                                {
                                                    throw new XmlException($"No type of setting value specified for '{name}'.");
                                                }
                                                value = this.ReadXmlValue(childNode.FirstChild.AsNonNull(), typeName);
                                                break;
                                            }
                                        }
                                        finally
                                        {
                                            childNode = childNode.NextSibling;
                                        }
                                    }
                                    if (name == null)
                                    {
                                        throw new XmlException("No name of setting key specified.");
                                    }
                                    if (defaultValue == null)
                                    {
                                        throw new XmlException($"No default setting value specified for '{name}'.");
                                    }
                                    if (value == null)
                                    {
                                        throw new XmlException($"No value specified for '{name}'.");
                                    }
                                    keyValues[new SettingKey(name, defaultValue.GetType(), defaultValue)] = value;
                                }
                                finally
                                {
                                    keyValueNode = keyValueNode.NextSibling;
                                }
                            }
                        }
                        break;
                    }
                }
                finally
                {
                    node = node.NextSibling;
                }
            }

            // complete
            if (version == null)
            {
                throw new XmlException("No 'Version' specified.");
            }
            if (lastModifiedTime == null)
            {
                throw new XmlException("No 'LastModifiedTime' specified.");
            }
            metadata = new SettingsMetadata(version.GetValueOrDefault(), lastModifiedTime.GetValueOrDefault());
            values   = keyValues;
        }
Пример #3
0
#pragma warning disable CS1591
        // Serialize.
        public void Serialize(Stream stream, IDictionary <SettingKey, object> values, SettingsMetadata metadata)
        {
            // prepare
            using var writer = XmlWriter.Create(stream, new XmlWriterSettings()
            {
                Encoding = Encoding.UTF8,
                Indent   = true,
            });

            // start document
            writer.WriteStartDocument();
            writer.WriteStartElement("Settings");

            // versin
            writer.WriteStartElement("Version");
            writer.WriteValue(metadata.Version);
            writer.WriteEndElement();

            // last modified time
            writer.WriteStartElement("LastModifiedTime");
            writer.WriteValue(metadata.LastModifiedTime.ToBinary());
            writer.WriteEndElement();

            // key-values
            writer.WriteStartElement("Values");
            foreach (var keyValue in values)
            {
                var key      = keyValue.Key;
                var value    = keyValue.Value;
                var typeName = this.GetTypeName(key.DefaultValue.GetType());
                writer.WriteStartElement("Value");
                writer.WriteStartElement("Name");
                writer.WriteValue(key.Name);
                writer.WriteEndElement();
                writer.WriteStartElement("Type");
                writer.WriteValue(typeName);
                writer.WriteEndElement();
                writer.WriteStartElement("Default");
                this.WriteXmlValue(writer, key.DefaultValue);
                writer.WriteEndElement();
                writer.WriteStartElement("Value");
                this.WriteXmlValue(writer, value);
                writer.WriteEndElement();
                writer.WriteEndElement();
            }
            writer.WriteEndElement();

            // complete
            writer.WriteEndElement();
            writer.WriteEndDocument();
        }