From 767cdc1f6f6a63ce997fc9476911e2c361f9d402 Mon Sep 17 00:00:00 2001 From: LukePulverenti Date: Wed, 20 Feb 2013 20:33:05 -0500 Subject: Pushing missing changes --- .../Serialization/DynamicProtobufSerializer.cs | 160 ++++++++++ .../Serialization/JsonSerializer.cs | 333 ++++++++++++++++----- MediaBrowser.Common/Serialization/JsvSerializer.cs | 44 --- .../Serialization/ProtobufSerializer.cs | 53 ---- MediaBrowser.Common/Serialization/XmlSerializer.cs | 268 +++++++++++++---- 5 files changed, 629 insertions(+), 229 deletions(-) create mode 100644 MediaBrowser.Common/Serialization/DynamicProtobufSerializer.cs delete mode 100644 MediaBrowser.Common/Serialization/JsvSerializer.cs delete mode 100644 MediaBrowser.Common/Serialization/ProtobufSerializer.cs (limited to 'MediaBrowser.Common/Serialization') diff --git a/MediaBrowser.Common/Serialization/DynamicProtobufSerializer.cs b/MediaBrowser.Common/Serialization/DynamicProtobufSerializer.cs new file mode 100644 index 0000000000..f83b31322c --- /dev/null +++ b/MediaBrowser.Common/Serialization/DynamicProtobufSerializer.cs @@ -0,0 +1,160 @@ +using MediaBrowser.Common.Mef; +using ProtoBuf; +using ProtoBuf.Meta; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Reflection; + +namespace MediaBrowser.Common.Serialization +{ + /// + /// Creates a compiled protobuf serializer based on a set of assemblies + /// + public class DynamicProtobufSerializer + { + /// + /// Gets or sets the type model. + /// + /// The type model. + public TypeModel TypeModel { get; set; } + + /// + /// Serializes to stream. + /// + /// The obj. + /// The stream. + /// obj + public void SerializeToStream(object obj, Stream stream) + { + if (obj == null) + { + throw new ArgumentNullException("obj"); + } + if (stream == null) + { + throw new ArgumentNullException("stream"); + } + + TypeModel.Serialize(stream, obj); + } + + /// + /// Deserializes from stream. + /// + /// The stream. + /// The type. + /// System.Object. + /// stream + public object DeserializeFromStream(Stream stream, Type type) + { + if (stream == null) + { + throw new ArgumentNullException("stream"); + } + + return TypeModel.Deserialize(stream, null, type); + } + + /// + /// Deserializes from stream. + /// + /// + /// The stream. + /// ``0. + public T DeserializeFromStream(Stream stream) + where T : class + { + return DeserializeFromStream(stream, typeof(T)) as T; + } + + /// + /// Serializes to file. + /// + /// + /// The obj. + /// The file. + /// file + public void SerializeToFile(T obj, string file) + { + if (string.IsNullOrEmpty(file)) + { + throw new ArgumentNullException("file"); + } + + using (Stream stream = File.Open(file, FileMode.Create)) + { + SerializeToStream(obj, stream); + } + } + + /// + /// Deserializes from file. + /// + /// + /// The file. + /// ``0. + /// file + public T DeserializeFromFile(string file) + where T : class + { + if (string.IsNullOrEmpty(file)) + { + throw new ArgumentNullException("file"); + } + + using (Stream stream = File.OpenRead(file)) + { + return DeserializeFromStream(stream); + } + } + + /// + /// Serializes to bytes. + /// + /// + /// The obj. + /// System.Byte[][]. + /// obj + public byte[] SerializeToBytes(T obj) + where T : class + { + if (obj == null) + { + throw new ArgumentNullException("obj"); + } + + using (var stream = new MemoryStream()) + { + SerializeToStream(obj, stream); + return stream.ToArray(); + } + } + + /// + /// Creates the specified assemblies. + /// + /// The assemblies. + /// DynamicProtobufSerializer. + /// assemblies + public static DynamicProtobufSerializer Create(IEnumerable assemblies) + { + if (assemblies == null) + { + throw new ArgumentNullException("assemblies"); + } + + var model = TypeModel.Create(); + var attributeType = typeof(ProtoContractAttribute); + + // Find all ProtoContracts in the current assembly + foreach (var type in assemblies.SelectMany(a => MefUtils.GetTypes(a).Where(t => Attribute.IsDefined(t, attributeType)))) + { + model.Add(type, true); + } + + return new DynamicProtobufSerializer { TypeModel = model.Compile() }; + } + } +} diff --git a/MediaBrowser.Common/Serialization/JsonSerializer.cs b/MediaBrowser.Common/Serialization/JsonSerializer.cs index f5d2abe33f..5b6e354a8c 100644 --- a/MediaBrowser.Common/Serialization/JsonSerializer.cs +++ b/MediaBrowser.Common/Serialization/JsonSerializer.cs @@ -1,74 +1,259 @@ -using System; -using System.IO; - -namespace MediaBrowser.Common.Serialization -{ - /// - /// Provides a wrapper around third party json serialization. - /// - public class JsonSerializer - { - public static void SerializeToStream(T obj, Stream stream) - { - Configure(); - - ServiceStack.Text.JsonSerializer.SerializeToStream(obj, stream); - } - - public static void SerializeToFile(T obj, string file) - { - Configure(); - - using (Stream stream = File.Open(file, FileMode.Create)) - { - ServiceStack.Text.JsonSerializer.SerializeToStream(obj, stream); - } - } - - public static object DeserializeFromFile(Type type, string file) - { - Configure(); - - using (Stream stream = File.OpenRead(file)) - { - return ServiceStack.Text.JsonSerializer.DeserializeFromStream(type, stream); - } - } - - public static T DeserializeFromFile(string file) - { - Configure(); - - using (Stream stream = File.OpenRead(file)) - { - return ServiceStack.Text.JsonSerializer.DeserializeFromStream(stream); - } - } - - public static T DeserializeFromStream(Stream stream) - { - Configure(); - - return ServiceStack.Text.JsonSerializer.DeserializeFromStream(stream); - } - - public static object DeserializeFromStream(Stream stream, Type type) - { - Configure(); - - return ServiceStack.Text.JsonSerializer.DeserializeFromStream(type, stream); - } - - private static bool _isConfigured; - private static void Configure() - { - if (!_isConfigured) - { - ServiceStack.Text.JsConfig.DateHandler = ServiceStack.Text.JsonDateHandler.ISO8601; - ServiceStack.Text.JsConfig.ExcludeTypeInfo = true; - ServiceStack.Text.JsConfig.IncludeNullValues = false; - _isConfigured = true; - } - } - } -} +using System; +using System.IO; + +namespace MediaBrowser.Common.Serialization +{ + /// + /// Provides a wrapper around third party json serialization. + /// + public class JsonSerializer + { + /// + /// Serializes to stream. + /// + /// + /// The obj. + /// The stream. + /// obj + public static void SerializeToStream(T obj, Stream stream) + where T : class + { + if (obj == null) + { + throw new ArgumentNullException("obj"); + } + + if (stream == null) + { + throw new ArgumentNullException("stream"); + } + + Configure(); + + ServiceStack.Text.JsonSerializer.SerializeToStream(obj, obj.GetType(), stream); + } + + /// + /// Serializes to file. + /// + /// + /// The obj. + /// The file. + /// obj + public static void SerializeToFile(T obj, string file) + where T : class + { + if (obj == null) + { + throw new ArgumentNullException("obj"); + } + + if (string.IsNullOrEmpty(file)) + { + throw new ArgumentNullException("file"); + } + + Configure(); + + using (Stream stream = File.Open(file, FileMode.Create)) + { + SerializeToStream(obj, stream); + } + } + + /// + /// Deserializes from file. + /// + /// The type. + /// The file. + /// System.Object. + /// type + public static object DeserializeFromFile(Type type, string file) + { + if (type == null) + { + throw new ArgumentNullException("type"); + } + + if (string.IsNullOrEmpty(file)) + { + throw new ArgumentNullException("file"); + } + + Configure(); + + using (Stream stream = File.OpenRead(file)) + { + return ServiceStack.Text.JsonSerializer.DeserializeFromStream(type, stream); + } + } + + /// + /// Deserializes from file. + /// + /// + /// The file. + /// ``0. + /// file + public static T DeserializeFromFile(string file) + where T : class + { + if (string.IsNullOrEmpty(file)) + { + throw new ArgumentNullException("file"); + } + + Configure(); + + using (Stream stream = File.OpenRead(file)) + { + return ServiceStack.Text.JsonSerializer.DeserializeFromStream(stream); + } + } + + /// + /// Deserializes from stream. + /// + /// + /// The stream. + /// ``0. + /// stream + public static T DeserializeFromStream(Stream stream) + { + if (stream == null) + { + throw new ArgumentNullException("stream"); + } + + Configure(); + + return ServiceStack.Text.JsonSerializer.DeserializeFromStream(stream); + } + + /// + /// Deserializes from string. + /// + /// + /// The text. + /// ``0. + /// text + public static T DeserializeFromString(string text) + { + if (string.IsNullOrEmpty(text)) + { + throw new ArgumentNullException("text"); + } + + Configure(); + + return ServiceStack.Text.JsonSerializer.DeserializeFromString(text); + } + + /// + /// Deserializes from stream. + /// + /// The stream. + /// The type. + /// System.Object. + /// stream + public static object DeserializeFromStream(Stream stream, Type type) + { + if (stream == null) + { + throw new ArgumentNullException("stream"); + } + + if (type == null) + { + throw new ArgumentNullException("type"); + } + + Configure(); + + return ServiceStack.Text.JsonSerializer.DeserializeFromStream(type, stream); + } + + /// + /// The _is configured + /// + private static bool _isConfigured; + /// + /// Configures this instance. + /// + internal static void Configure() + { + if (!_isConfigured) + { + ServiceStack.Text.JsConfig.DateHandler = ServiceStack.Text.JsonDateHandler.ISO8601; + ServiceStack.Text.JsConfig.ExcludeTypeInfo = true; + ServiceStack.Text.JsConfig.IncludeNullValues = false; + _isConfigured = true; + } + } + + /// + /// Deserializes from string. + /// + /// The json. + /// The type. + /// System.Object. + /// json + public static object DeserializeFromString(string json, Type type) + { + if (string.IsNullOrEmpty(json)) + { + throw new ArgumentNullException("json"); + } + + if (type == null) + { + throw new ArgumentNullException("type"); + } + + Configure(); + + return ServiceStack.Text.JsonSerializer.DeserializeFromString(json, type); + } + + /// + /// Serializes to string. + /// + /// + /// The obj. + /// System.String. + /// obj + public static string SerializeToString(T obj) + where T : class + { + if (obj == null) + { + throw new ArgumentNullException("obj"); + } + + Configure(); + return ServiceStack.Text.JsonSerializer.SerializeToString(obj, obj.GetType()); + } + + /// + /// Serializes to bytes. + /// + /// + /// The obj. + /// System.Byte[][]. + /// obj + public static byte[] SerializeToBytes(T obj) + where T : class + { + if (obj == null) + { + throw new ArgumentNullException("obj"); + } + + using (var stream = new MemoryStream()) + { + SerializeToStream(obj, stream); + return stream.ToArray(); + } + } + } +} diff --git a/MediaBrowser.Common/Serialization/JsvSerializer.cs b/MediaBrowser.Common/Serialization/JsvSerializer.cs deleted file mode 100644 index 41e5ea800a..0000000000 --- a/MediaBrowser.Common/Serialization/JsvSerializer.cs +++ /dev/null @@ -1,44 +0,0 @@ -using System; -using System.IO; - -namespace MediaBrowser.Common.Serialization -{ - /// - /// This adds support for ServiceStack's proprietary JSV output format. - /// It's a hybrid of Json and Csv but the serializer performs about 25% faster and output runs about 10% smaller - /// http://www.servicestack.net/benchmarks/NorthwindDatabaseRowsSerialization.100000-times.2010-08-17.html - /// - public static class JsvSerializer - { - public static void SerializeToStream(T obj, Stream stream) - { - ServiceStack.Text.TypeSerializer.SerializeToStream(obj, stream); - } - - public static T DeserializeFromStream(Stream stream) - { - return ServiceStack.Text.TypeSerializer.DeserializeFromStream(stream); - } - - public static object DeserializeFromStream(Stream stream, Type type) - { - return ServiceStack.Text.TypeSerializer.DeserializeFromStream(type, stream); - } - - public static void SerializeToFile(T obj, string file) - { - using (Stream stream = File.Open(file, FileMode.Create)) - { - SerializeToStream(obj, stream); - } - } - - public static T DeserializeFromFile(string file) - { - using (Stream stream = File.OpenRead(file)) - { - return DeserializeFromStream(stream); - } - } - } -} diff --git a/MediaBrowser.Common/Serialization/ProtobufSerializer.cs b/MediaBrowser.Common/Serialization/ProtobufSerializer.cs deleted file mode 100644 index 1c79a272d5..0000000000 --- a/MediaBrowser.Common/Serialization/ProtobufSerializer.cs +++ /dev/null @@ -1,53 +0,0 @@ -using System; -using System.IO; - -namespace MediaBrowser.Common.Serialization -{ - /// - /// Protocol buffers is google's binary serialization format. This is a .NET implementation of it. - /// You have to tag your classes with some annoying attributes, but in return you get the fastest serialization around with the smallest possible output. - /// - public static class ProtobufSerializer - { - /// - /// This is an auto-generated Protobuf Serialization assembly for best performance. - /// It is created during the Model project's post-build event. - /// This means that this class can currently only handle types within the Model project. - /// If we need to, we can always add a param indicating whether or not the model serializer should be used. - /// - private static readonly ProtobufModelSerializer ProtobufModelSerializer = new ProtobufModelSerializer(); - - public static void SerializeToStream(T obj, Stream stream) - { - ProtobufModelSerializer.Serialize(stream, obj); - } - - public static T DeserializeFromStream(Stream stream) - where T : class - { - return ProtobufModelSerializer.Deserialize(stream, null, typeof(T)) as T; - } - - public static object DeserializeFromStream(Stream stream, Type type) - { - return ProtobufModelSerializer.Deserialize(stream, null, type); - } - - public static void SerializeToFile(T obj, string file) - { - using (Stream stream = File.Open(file, FileMode.Create)) - { - SerializeToStream(obj, stream); - } - } - - public static T DeserializeFromFile(string file) - where T : class - { - using (Stream stream = File.OpenRead(file)) - { - return DeserializeFromStream(stream); - } - } - } -} diff --git a/MediaBrowser.Common/Serialization/XmlSerializer.cs b/MediaBrowser.Common/Serialization/XmlSerializer.cs index 11ef17c3de..8737aa8189 100644 --- a/MediaBrowser.Common/Serialization/XmlSerializer.cs +++ b/MediaBrowser.Common/Serialization/XmlSerializer.cs @@ -1,58 +1,210 @@ -using System; -using System.IO; - -namespace MediaBrowser.Common.Serialization -{ - /// - /// Provides a wrapper around third party xml serialization. - /// - public class XmlSerializer - { - public static void SerializeToStream(T obj, Stream stream) - { - ServiceStack.Text.XmlSerializer.SerializeToStream(obj, stream); - } - - public static T DeserializeFromStream(Stream stream) - { - return ServiceStack.Text.XmlSerializer.DeserializeFromStream(stream); - } - - public static object DeserializeFromStream(Type type, Stream stream) - { - return ServiceStack.Text.XmlSerializer.DeserializeFromStream(type, stream); - } - - public static void SerializeToFile(T obj, string file) - { - using (var stream = new FileStream(file, FileMode.Create)) - { - SerializeToStream(obj, stream); - } - } - - public static T DeserializeFromFile(string file) - { - using (Stream stream = File.OpenRead(file)) - { - return DeserializeFromStream(stream); - } - } - - public static void SerializeToFile(object obj, string file) - { - using (var stream = new FileStream(file, FileMode.Create)) - { - ServiceStack.Text.XmlSerializer.SerializeToStream(obj, stream); - } - } - - public static object DeserializeFromFile(Type type, string file) - { - using (Stream stream = File.OpenRead(file)) - { - return DeserializeFromStream(type, stream); - } - } - } -} +using MediaBrowser.Common.Logging; +using System; +using System.IO; +using System.Linq; +using System.Xml; + +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. + /// System.Object. + public static object GetXmlConfiguration(Type type, string path) + { + Logger.LogInfo("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.LogInfo("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. + /// ``0. + public static T GetXmlConfiguration(string path) + where T : class + { + return GetXmlConfiguration(typeof(T), path) as T; + } + } +} -- cgit v1.2.3