aboutsummaryrefslogtreecommitdiff
path: root/MediaBrowser.Common/Serialization/DynamicProtobufSerializer.cs
blob: 359cf9da06f81ee291b163c65c8f69b9c78a1a2b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
using ProtoBuf;
using ProtoBuf.Meta;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;

namespace MediaBrowser.Common.Serialization
{
    /// <summary>
    /// Creates a compiled protobuf serializer based on a set of assemblies
    /// </summary>
    public class DynamicProtobufSerializer
    {
        /// <summary>
        /// Gets or sets the type model.
        /// </summary>
        /// <value>The type model.</value>
        public TypeModel TypeModel { get; set; }

        /// <summary>
        /// Serializes to stream.
        /// </summary>
        /// <param name="obj">The obj.</param>
        /// <param name="stream">The stream.</param>
        /// <exception cref="System.ArgumentNullException">obj</exception>
        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);
        }

        /// <summary>
        /// Deserializes from stream.
        /// </summary>
        /// <param name="stream">The stream.</param>
        /// <param name="type">The type.</param>
        /// <returns>System.Object.</returns>
        /// <exception cref="System.ArgumentNullException">stream</exception>
        public object DeserializeFromStream(Stream stream, Type type)
        {
            if (stream == null)
            {
                throw new ArgumentNullException("stream");
            }
            
            return TypeModel.Deserialize(stream, null, type);
        }

        /// <summary>
        /// Deserializes from stream.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="stream">The stream.</param>
        /// <returns>``0.</returns>
        public T DeserializeFromStream<T>(Stream stream)
            where T : class
        {
            return DeserializeFromStream(stream, typeof(T)) as T;
        }

        /// <summary>
        /// Serializes to file.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="obj">The obj.</param>
        /// <param name="file">The file.</param>
        /// <exception cref="System.ArgumentNullException">file</exception>
        public void SerializeToFile<T>(T obj, string file)
        {
            if (string.IsNullOrEmpty(file))
            {
                throw new ArgumentNullException("file");
            }
            
            using (Stream stream = File.Open(file, FileMode.Create))
            {
                SerializeToStream(obj, stream);
            }
        }

        /// <summary>
        /// Deserializes from file.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="file">The file.</param>
        /// <returns>``0.</returns>
        /// <exception cref="System.ArgumentNullException">file</exception>
        public T DeserializeFromFile<T>(string file)
            where T : class
        {
            if (string.IsNullOrEmpty(file))
            {
                throw new ArgumentNullException("file");
            }
            
            using (Stream stream = File.OpenRead(file))
            {
                return DeserializeFromStream<T>(stream);
            }
        }

        /// <summary>
        /// Serializes to bytes.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="obj">The obj.</param>
        /// <returns>System.Byte[][].</returns>
        /// <exception cref="System.ArgumentNullException">obj</exception>
        public byte[] SerializeToBytes<T>(T obj)
            where T : class
        {
            if (obj == null)
            {
                throw new ArgumentNullException("obj");
            }
            
            using (var stream = new MemoryStream())
            {
                SerializeToStream(obj, stream);
                return stream.ToArray();
            }
        }

        /// <summary>
        /// Creates the specified assemblies.
        /// </summary>
        /// <returns>DynamicProtobufSerializer.</returns>
        /// <exception cref="System.ArgumentNullException">assemblies</exception>
        public static DynamicProtobufSerializer Create(IEnumerable<Type> types)
        {
            if (types == null)
            {
                throw new ArgumentNullException("types");
            }
            
            var model = TypeModel.Create();
            var attributeType = typeof(ProtoContractAttribute);

            // Find all ProtoContracts in the current assembly
            foreach (var type in types.Where(t => Attribute.IsDefined(t, attributeType)))
            {
                model.Add(type, true);
            }

            return new DynamicProtobufSerializer { TypeModel = model.Compile() };
        }
    }
}