-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathFastBinaryFormatter.cs
180 lines (153 loc) · 4.81 KB
/
FastBinaryFormatter.cs
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
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.Serialization;
using System.Reflection;
using System.IO;
namespace Grammophone.Serialization
{
/// <summary>
/// An <see cref="IFormatter"/> implementation for serializing objects in a custom binary format.
/// </summary>
/// <remarks>
/// <para>
/// The stream format is a series of bytes prepended by <see cref="ElementType"/> descriptor bytes.
/// See the <see cref="ElementType"/> members documentation for detailed structure.
/// </para>
/// <para>
/// This formatter implements almost all serialization infrastructure with one exception:
/// </para>
/// <para>
/// If a registered serialization surrogate returns in method <see cref="ISerializationSurrogate.SetObjectData"/>
/// a (non-null) different object than the one supplied
/// to populate, then the data supplied in the <see cref="SerializationInfo"/>
/// must not recursively cause a serialization cycle up to the new object.
/// A cycle is allowed though if it is established outside the de/serialized objects.
/// In particular, cycles formed by associations created by other surrogates are allowed.
/// </para>
/// <para>
/// The same restriction applies to <see cref="IObjectReference"/> implementations.
/// </para>
/// <para>
/// Note that support for returning a different non-null object in method <see cref="ISerializationSurrogate.SetObjectData"/> has
/// effect in version .NET 2.0 and later. The return value was previously ignored.
/// </para>
/// </remarks>
public class FastBinaryFormatter : IFormatter
{
#region Private fields
private SerializationBinder binder;
private StreamingContext context;
private ISurrogateSelector surrogateSelector;
private IFormatterConverter converter;
#endregion
#region Construction
/// <summary>
/// Create.
/// </summary>
public FastBinaryFormatter()
{
binder = new DefaultSerializationBinder();
context = new StreamingContext();
surrogateSelector = new SurrogateSelector();
converter = new FormatterConverter();
this.InternFieldNames = true;
}
#endregion
#region Public properties
/// <summary>
/// The type converter to be used when implementations of
/// <see cref="ISerializable"/> and <see cref="ISerializationSurrogate"/>
/// pass values through <see cref="SerializationInfo"/>.
/// Default is <see cref="FormatterConverter"/>.
/// </summary>
public IFormatterConverter Converter
{
get
{
return converter;
}
set
{
if (value == null) throw new ArgumentNullException("value");
converter = value;
}
}
/// <summary>
/// If true, serialization will intern the field names of all objects.
/// This is irrelevant to deserialization, as it will be automatically
/// detected whether field interning was used or when the stream was produced.
/// Default is true.
/// </summary>
public bool InternFieldNames { get; private set; }
#endregion
#region IFormatter Members
/// <summary>
/// The converter between types and string representations.
/// Default is <see cref="DefaultSerializationBinder"/>.
/// </summary>
public SerializationBinder Binder
{
get
{
return binder;
}
set
{
if (value == null) throw new ArgumentNullException("value");
binder = value;
}
}
/// <summary>
/// The streaming context for formatter.
/// </summary>
public StreamingContext Context
{
get
{
return context;
}
set
{
context = value;
}
}
/// <summary>
/// Deserializes the data on the provided stream and reconstitutes the graph of objects.
/// </summary>
/// <param name="serializationStream">The stream that contains the data to deserialize.</param>
/// <returns>The top object of the deserialized graph.</returns>
public object Deserialize(System.IO.Stream serializationStream)
{
var objectSerializer = new ObjectReader(serializationStream, this);
return objectSerializer.Read();
}
/// <summary>
/// Serializes an object, or graph of objects with the given root to the provided stream.
/// </summary>
/// <param name="serializationStream">The stream where the formatter puts the serialized data.</param>
/// <param name="graph">The object, or root of the object graph, to serialize.</param>
public void Serialize(System.IO.Stream serializationStream, object graph)
{
var objectSerializer = new ObjectWriter(serializationStream, this);
objectSerializer.Write(graph);
}
/// <summary>
/// The surrogate selector defining the serialization overrides.
/// </summary>
public ISurrogateSelector SurrogateSelector
{
get
{
return surrogateSelector;
}
set
{
if (surrogateSelector == null) throw new ArgumentNullException("surrogateSelector");
surrogateSelector = value;
}
}
#endregion
}
}