using MediaBrowser.Common.Logging; using System; using System.IO; using System.Linq; using System.Xml; using MediaBrowser.Model.Logging; namespace MediaBrowser.Common.Serialization { /// /// Provides a wrapper around third party xml serialization. /// public class XmlSerializer { /// /// Serializes to writer. /// /// /// The obj. /// The writer. public static void SerializeToWriter(T obj, XmlTextWriter writer) { writer.Formatting = Formatting.Indented; var netSerializer = new System.Xml.Serialization.XmlSerializer(typeof(T)); netSerializer.Serialize(writer, obj); } /// /// Serializes to writer. /// /// The obj. /// The writer. public static void SerializeToWriter(object obj, XmlTextWriter writer) { writer.Formatting = Formatting.Indented; var netSerializer = new System.Xml.Serialization.XmlSerializer(obj.GetType()); netSerializer.Serialize(writer, obj); } /// /// Deserializes from stream. /// /// /// The stream. /// ``0. public static T DeserializeFromStream(Stream stream) { using (var reader = new XmlTextReader(stream)) { var netSerializer = new System.Xml.Serialization.XmlSerializer(typeof(T)); return (T)netSerializer.Deserialize(reader); } } /// /// Deserializes from stream. /// /// The type. /// The stream. /// System.Object. public static object DeserializeFromStream(Type type, Stream stream) { using (var reader = new XmlTextReader(stream)) { var netSerializer = new System.Xml.Serialization.XmlSerializer(type); return netSerializer.Deserialize(reader); } } /// /// Serializes to stream. /// /// The obj. /// The stream. public static void SerializeToStream(object obj, Stream stream) { using (var writer = new XmlTextWriter(stream, null)) { SerializeToWriter(obj, writer); } } /// /// Deserializes from file. /// /// /// The file. /// ``0. public static T DeserializeFromFile(string file) { using (var stream = File.OpenRead(file)) { return DeserializeFromStream(stream); } } /// /// Serializes to file. /// /// The obj. /// The file. public static void SerializeToFile(object obj, string file) { using (var stream = new FileStream(file, FileMode.Create)) { SerializeToStream(obj, stream); } } /// /// Deserializes from file. /// /// The type. /// The file. /// System.Object. public static object DeserializeFromFile(Type type, string file) { using (var stream = File.OpenRead(file)) { return DeserializeFromStream(type, stream); } } /// /// Deserializes from bytes. /// /// The type. /// The buffer. /// System.Object. public static object DeserializeFromBytes(Type type, byte[] buffer) { using (var stream = new MemoryStream(buffer)) { return DeserializeFromStream(type, stream); } } /// /// Serializes to bytes. /// /// The obj. /// System.Byte[][]. public static byte[] SerializeToBytes(object obj) { using (var stream = new MemoryStream()) { SerializeToStream(obj, stream); return stream.ToArray(); } } /// /// Reads an xml configuration file from the file system /// It will immediately re-serialize and save if new serialization data is available due to property changes /// /// The type. /// The path. /// The logger. /// System.Object. public static object GetXmlConfiguration(Type type, string path, ILogger logger) { logger.Info("Loading {0} at {1}", type.Name, path); object configuration; byte[] buffer = null; // Use try/catch to avoid the extra file system lookup using File.Exists try { buffer = File.ReadAllBytes(path); configuration = DeserializeFromBytes(type, buffer); } catch (FileNotFoundException) { configuration = Activator.CreateInstance(type); } // Take the object we just got and serialize it back to bytes var newBytes = SerializeToBytes(configuration); // If the file didn't exist before, or if something has changed, re-save if (buffer == null || !buffer.SequenceEqual(newBytes)) { logger.Info("Saving {0} to {1}", type.Name, path); // Save it after load in case we got new items File.WriteAllBytes(path, newBytes); } return configuration; } /// /// Reads an xml configuration file from the file system /// It will immediately save the configuration after loading it, just /// in case there are new serializable properties /// /// /// The path. /// The logger. /// ``0. public static T GetXmlConfiguration(string path, ILogger logger) where T : class { return GetXmlConfiguration(typeof(T), path, logger) as T; } } }