aboutsummaryrefslogtreecommitdiffstats
path: root/Software/Visual_Studio/Tango.Core/Bson/BsonUtcSerializer.cs
blob: 7621bd132304e0379c512d3f3c9a0345b2113253 (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
using Newtonsoft.Json;
using Newtonsoft.Json.Bson;
using Newtonsoft.Json.Serialization;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Tango.Core.Bson
{
    public static class BsonConvert
    {
        private static BsonUtcSerializer _serializer;

        static BsonConvert()
        {
            _serializer = new BsonUtcSerializer();
        }

        public static byte[] Serialize(Object obj)
        {
            MemoryStream ms = new MemoryStream();
            using (BsonWriter writer = new BsonWriter(ms))
            {
                _serializer.Serialize(writer, obj);
                return ms.ToArray();
            }
        }

        public static byte[] Serialize<T>(T obj)
        {
            return Serialize((Object)obj);
        }

        public static Object Deserialize(byte[] data, Type type)
        {
            MemoryStream ms = new MemoryStream(data);
            using (BsonReader reader = new BsonReader(ms))
            {
                Object obj = _serializer.Deserialize(reader, type);
                return obj;
            }
        }

        public static T Deserialize<T>(byte[] data)
        {
            return (T)Deserialize(data, typeof(T));
        }
    }

    public class BsonUtcSerializer : JsonSerializer
    {
        private class DateTimeConverter : JsonConverter
        {
            public override bool CanConvert(Type objectType)
            {
                return typeof(DateTime) == objectType
                    || typeof(DateTime?) == objectType;
            }

            public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
            {
                var dateTimeOffset = (DateTime)value;
                // Serialize DateTimeOffset as round-trip formatted string
                serializer.Serialize(writer, dateTimeOffset.ToString("O"));
            }

            public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
            {
                if (reader.TokenType != JsonToken.String && reader.TokenType != JsonToken.Date)
                    return null;

                DateTime dt;

                var dateWithOffset = (String)reader.Value;

                if (String.IsNullOrEmpty(dateWithOffset))
                    return null;

                if (DateTime.TryParseExact(dateWithOffset, "O", CultureInfo.InvariantCulture, DateTimeStyles.RoundtripKind, out dt))
                    return dt;

                return null;
            }

        }

        private class DateTimeContractResolver : DefaultContractResolver
        {
            protected override JsonContract CreateContract(Type objectType)
            {
                var contract = base.CreateContract(objectType);

                if (objectType == typeof(DateTime) || objectType == typeof(DateTime?))
                    contract.Converter = new DateTimeConverter();

                return contract;
            }
        }

        public BsonUtcSerializer()
        {
            ContractResolver = new DateTimeContractResolver();
            DateTimeZoneHandling = DateTimeZoneHandling.RoundtripKind;
        }
    }
}