Spring – Rev 1

Subversion Repositories:
Rev:
using System;
using System.IO;
using System.Text;
using System.Threading.Tasks;
using System.Xml;
using System.Xml.Schema;
using System.Xml.Serialization;

namespace Spring.Serialization.Combos
{
    public static class ComboSerialization
    {
#region Private Delegates, Events, Enums, Properties, Indexers and Fields

        private static XmlSerializer CombosSerializer { get; } = new XmlSerializer(typeof(SpringCombos.Combos));

        private static XmlReaderSettings XmlReaderSettings { get; } = new XmlReaderSettings
                                                                      {
                                                                          Async = true,
                                                                          ValidationType = ValidationType.Schema,
                                                                          IgnoreWhitespace = true,
                                                                          ValidationFlags =
                                                                              XmlSchemaValidationFlags
                                                                                  .ProcessInlineSchema |
                                                                              XmlSchemaValidationFlags
                                                                                  .ProcessSchemaLocation |
                                                                              XmlSchemaValidationFlags
                                                                                  .ReportValidationWarnings,
                                                                          DtdProcessing = DtdProcessing.Parse
                                                                      };

        private static XmlWriterSettings XmlWriterSettings { get; } = new XmlWriterSettings
                                                                      {
                                                                          Async = true,
                                                                          Indent = true,
                                                                          IndentChars = "    ",
                                                                          OmitXmlDeclaration = false
                                                                      };

#endregion

#region Event Handlers

        private static void XmlReaderSettings_ValidationEventHandler(object sender, ValidationEventArgs e)
        {
            //TODO: do something...
            switch (e.Severity)
            {
                case XmlSeverityType.Error:
                    /*this.Execute(() =>
                        {
                            toolStripStatusLabel1.Text = $"{Strings.Validation_error_reading_combos}: {e.Message}";
                        });
                    */
                    break;

                case XmlSeverityType.Warning:
                    /*this.Execute(() =>
                        {
                            toolStripStatusLabel1.Text =
                                $"{Strings.Validation_warning_reading_combos}: {e.Message}";
                        });
                    */
                    break;
            }
        }

#endregion

#region Public Methods

        /// <summary>
        ///     Deserialize text to Spring combos.
        /// </summary>
        /// <param name="text">the text to deserialize</param>
        /// <returns>a deserialization success or fail object</returns>
        public static async Task<SerializationState> Deserialize(string text)
        {
            XmlReaderSettings.ValidationEventHandler += XmlReaderSettings_ValidationEventHandler;

            try
            {
                using (var memoryStream = new MemoryStream(Encoding.UTF8.GetBytes(text)))
                {
                    using (var xmlReader = XmlReader.Create(memoryStream, XmlReaderSettings))
                    {
                        var stringBuilder = new StringBuilder();

                        using (var stringWriter = new StringWriter(stringBuilder))
                        {
                            while (await xmlReader.ReadAsync())
                            {
                                await stringWriter.WriteAsync(await xmlReader.ReadOuterXmlAsync());
                            }
                        }

                        using (var stringReader = new StringReader(stringBuilder.ToString()))
                        {
                            var combos = (SpringCombos.Combos) CombosSerializer.Deserialize(stringReader);

                            using (var writeMemoryStream = new MemoryStream())
                            {
                                using (var xmlWriter =
                                    XmlWriter.Create(writeMemoryStream, XmlWriterSettings))
                                {
                                    await xmlWriter.WriteDocTypeAsync("SpringCombos",
                                        null,
                                        null,
                                        "<!ATTLIST SpringCombos xmlns:xsi CDATA #IMPLIED xsi:noNamespaceSchemaLocation CDATA #IMPLIED>");

                                    CombosSerializer.Serialize(xmlWriter, combos);

                                    writeMemoryStream.Position = 0L;

                                    using (var readMemoryStream = new MemoryStream())
                                    {
                                        await writeMemoryStream.CopyToAsync(readMemoryStream);

                                        readMemoryStream.Position = 0L;

                                        var contents = Encoding.UTF8.GetString(readMemoryStream.ToArray());

                                        return new SerializationSuccess<SpringCombos.Combos>
                                               {
                                                   Result = combos,
                                                   Text = contents
                                               };
                                    }
                                }
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                return new SerializationFailure { Exception = ex };
            }
            finally
            {
                XmlReaderSettings.ValidationEventHandler -= XmlReaderSettings_ValidationEventHandler;
            }
        }

        public static async Task<SerializationState> Deserialize(FileInfo fileInfo, int index)
        {
            var result = await Deserialize(fileInfo);

            switch (result)
            {
                case SerializationSuccess<SpringCombos.Combos> serializationSuccess:
                    foreach (var combo in serializationSuccess.Result.Combo)
                    {
                        combo.Index = index++;
                    }

                    break;
            }

            return result;
        }

        /// <summary>
        ///     Serialize Spring combos.
        /// </summary>
        /// <param name="combos">the spring combos to serialize</param>
        /// <returns>a serialization success or fail object</returns>
        public static async Task<SerializationState> Serialize(this SpringCombos.Combos combos)
        {
            try
            {
                using (var writeMemoryStream = new MemoryStream())
                {
                    using (var xmlWriter =
                        XmlWriter.Create(writeMemoryStream, XmlWriterSettings))
                    {
                        await xmlWriter.WriteDocTypeAsync("SpringCombos",
                            null,
                            null,
                            "<!ATTLIST SpringCombos xmlns:xsi CDATA #IMPLIED xsi:noNamespaceSchemaLocation CDATA #IMPLIED>");

                        CombosSerializer.Serialize(xmlWriter, combos);

                        writeMemoryStream.Position = 0L;

                        using (var readMemoryStream = new MemoryStream())
                        {
                            await writeMemoryStream.CopyToAsync(readMemoryStream);

                            readMemoryStream.Position = 0L;

                            var contents = Encoding.UTF8.GetString(readMemoryStream.ToArray());

                            return new SerializationSuccess<SpringCombos.Combos>
                                   { Result = combos, Text = contents };
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                return new SerializationFailure { Exception = ex };
            }
        }

        /// <summary>
        ///     Serialize Spring combos to a file.
        /// </summary>
        /// <param name="combos">the combos to serialize</param>
        /// <param name="fileName">path to a file</param>
        /// <returns>a serialization success or fail object</returns>
        public static async Task<SerializationState> Serialize(this SpringCombos.Combos combos, string fileName)
        {
            try
            {
                using (var writeMemoryStream = new MemoryStream())
                {
                    using (var xmlWriter =
                        XmlWriter.Create(writeMemoryStream, XmlWriterSettings))
                    {
                        await xmlWriter.WriteDocTypeAsync("SpringCombos",
                            null,
                            null,
                            "<!ATTLIST SpringCombos xmlns:xsi CDATA #IMPLIED xsi:noNamespaceSchemaLocation CDATA #IMPLIED>");

                        CombosSerializer.Serialize(xmlWriter, combos);

                        using (var fileStream = new FileStream(fileName, FileMode.Create))
                        {
                            writeMemoryStream.Position = 0L;

                            await writeMemoryStream.CopyToAsync(fileStream);

                            var contents = Encoding.UTF8.GetString(writeMemoryStream.ToArray());

                            return new SerializationSuccess<SpringCombos.Combos>
                                   {
                                       Result = combos,
                                       Text = contents
                                   };
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                return new SerializationFailure { Exception = ex };
            }
        }

#endregion

#region Private Methods

        /// <summary>
        ///     Deserialize a file to Spring combos.
        /// </summary>
        /// <param name="fileInfo">the file info</param>
        /// <returns>a deserialization success or fail object</returns>
        private static async Task<SerializationState> Deserialize(FileSystemInfo fileInfo)
        {
            XmlReaderSettings.ValidationEventHandler += XmlReaderSettings_ValidationEventHandler;

            try
            {
                using (var fileStream = new FileStream(fileInfo.FullName, FileMode.Open))
                {
                    using (var xmlReader = XmlReader.Create(fileStream, XmlReaderSettings))
                    {
                        var stringBuilder = new StringBuilder();

                        using (var stringWriter = new StringWriter(stringBuilder))
                        {
                            while (await xmlReader.ReadAsync())
                            {
                                await stringWriter.WriteAsync(await xmlReader.ReadOuterXmlAsync());
                            }
                        }

                        using (var stringReader = new StringReader(stringBuilder.ToString()))
                        {
                            var combos = (SpringCombos.Combos) CombosSerializer.Deserialize(stringReader) ??
                                         new SpringCombos.Combos();

                            using (var writeMemoryStream = new MemoryStream())
                            {
                                using (var xmlWriter =
                                    XmlWriter.Create(writeMemoryStream, XmlWriterSettings))
                                {
                                    await xmlWriter.WriteDocTypeAsync("SpringCombos",
                                        null,
                                        null,
                                        "<!ATTLIST SpringCombos xmlns:xsi CDATA #IMPLIED xsi:noNamespaceSchemaLocation CDATA #IMPLIED>");

                                    CombosSerializer.Serialize(xmlWriter, combos);

                                    writeMemoryStream.Position = 0L;

                                    using (var readMemoryStream = new MemoryStream())
                                    {
                                        await writeMemoryStream.CopyToAsync(readMemoryStream);

                                        readMemoryStream.Position = 0L;

                                        var contents = Encoding.UTF8.GetString(readMemoryStream.ToArray());

                                        return new SerializationSuccess<SpringCombos.Combos>
                                               {
                                                   Result = combos,
                                                   Text = contents
                                               };
                                    }
                                }
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                return new SerializationFailure { Exception = ex };
            }
            finally
            {
                XmlReaderSettings.ValidationEventHandler -= XmlReaderSettings_ValidationEventHandler;
            }
        }

#endregion
    }
}