forked from ServiceStack/ServiceStack
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathConsistentArraySerializer.cs
More file actions
98 lines (88 loc) · 3.77 KB
/
ConsistentArraySerializer.cs
File metadata and controls
98 lines (88 loc) · 3.77 KB
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
// -----------------------------------------------------------------------
// <copyright file="ConsistentArraySerializer.cs" company="Asynkron HB">
// Copyright (C) 2015-2017 Asynkron HB All rights reserved
// </copyright>
// -----------------------------------------------------------------------
using System;
using System.IO;
using Wire.Extensions;
namespace Wire.ValueSerializers
{
public class ConsistentArraySerializer : ValueSerializer
{
public const byte Manifest = 252;
public static readonly ConsistentArraySerializer Instance = new ConsistentArraySerializer();
public override object ReadValue(Stream stream, DeserializerSession session)
{
var elementSerializer = session.Serializer.GetDeserializerByManifest(stream, session);
//read the element type
var elementType = elementSerializer.GetElementType();
//get the element type serializer
var length = stream.ReadInt32(session);
var array = Array.CreateInstance(elementType, length); //create the array
if (session.Serializer.Options.PreserveObjectReferences)
{
session.TrackDeserializedObject(array);
}
if (elementType.IsFixedSizeType())
{
var size = elementType.GetTypeSize();
var totalSize = size*length;
var buffer = session.GetBuffer(totalSize);
stream.Read(buffer, 0, totalSize);
Buffer.BlockCopy(buffer, 0, array, 0, totalSize);
}
else
{
for (var i = 0; i < length; i++)
{
var value = elementSerializer.ReadValue(stream, session); //read the element value
array.SetValue(value, i); //set the element value
}
}
return array;
}
public override Type GetElementType()
{
throw new NotSupportedException();
}
public override void WriteManifest(Stream stream, SerializerSession session)
{
stream.WriteByte(Manifest);
}
// private static void WriteValues<T>(T[] array, Stream stream, Type elementType, ValueSerializer elementSerializer,
// private static object ReadValues<T>(Stream stream, DeserializerSession session, bool preserveObjectReferences)
public override void WriteValue(Stream stream, object value, SerializerSession session)
{
if (session.Serializer.Options.PreserveObjectReferences)
{
session.TrackSerializedObject(value);
}
var elementType = value.GetType().GetElementType();
var elementSerializer = session.Serializer.GetSerializerByType(elementType);
elementSerializer.WriteManifest(stream, session); //write array element type
// ReSharper disable once PossibleNullReferenceException
//TODO fix this
WriteValues((dynamic) value, stream, elementSerializer, session);
}
private static void WriteValues<T>(T[] array, Stream stream, ValueSerializer elementSerializer,
SerializerSession session)
{
Int32Serializer.WriteValueImpl(stream, array.Length, session);
if (typeof(T).IsFixedSizeType())
{
var size = typeof(T).GetTypeSize();
var result = new byte[array.Length*size];
Buffer.BlockCopy(array, 0, result, 0, result.Length);
stream.Write(result);
}
else
{
foreach (var value in array)
{
elementSerializer.WriteValue(stream, value, session);
}
}
}
}
}