This repository has been archived by the owner on Dec 24, 2022. It is now read-only.
/
JsvWriter.Generic.cs
108 lines (92 loc) · 3 KB
/
JsvWriter.Generic.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
//
// https://github.com/ServiceStack/ServiceStack.Text
// ServiceStack.Text: .NET C# POCO JSON, JSV and CSV Text Serializers.
//
// Authors:
// Demis Bellot (demis.bellot@gmail.com)
//
// Copyright 2012 ServiceStack Ltd.
//
// Licensed under the same terms of ServiceStack: new BSD license.
//
using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Threading;
using ServiceStack.Text.Common;
namespace ServiceStack.Text.Jsv
{
internal static class JsvWriter
{
public static readonly JsWriter<JsvTypeSerializer> Instance = new JsWriter<JsvTypeSerializer>();
private static Dictionary<Type, WriteObjectDelegate> WriteFnCache = new Dictionary<Type, WriteObjectDelegate>();
public static WriteObjectDelegate GetWriteFn(Type type)
{
try
{
WriteObjectDelegate writeFn;
if (WriteFnCache.TryGetValue(type, out writeFn)) return writeFn;
var genericType = typeof(JsvWriter<>).MakeGenericType(type);
var mi = genericType.GetMethod("WriteFn", BindingFlags.Public | BindingFlags.Static);
var writeFactoryFn = (Func<WriteObjectDelegate>)Delegate.CreateDelegate(typeof(Func<WriteObjectDelegate>), mi);
writeFn = writeFactoryFn();
Dictionary<Type, WriteObjectDelegate> snapshot, newCache;
do
{
snapshot = WriteFnCache;
newCache = new Dictionary<Type, WriteObjectDelegate>(WriteFnCache);
newCache[type] = writeFn;
} while (!ReferenceEquals(
Interlocked.CompareExchange(ref WriteFnCache, newCache, snapshot), snapshot));
return writeFn;
}
catch (Exception ex)
{
Tracer.Instance.WriteError(ex);
throw;
}
}
public static void WriteLateBoundObject(TextWriter writer, object value)
{
if (value == null) return;
var type = value.GetType();
var writeFn = type == typeof(object)
? WriteType<object, JsvTypeSerializer>.WriteObjectType
: GetWriteFn(type);
var prevState = JsState.IsWritingDynamic;
JsState.IsWritingDynamic = true;
writeFn(writer, value);
JsState.IsWritingDynamic = prevState;
}
public static WriteObjectDelegate GetValueTypeToStringMethod(Type type)
{
return Instance.GetValueTypeToStringMethod(type);
}
}
/// <summary>
/// Implement the serializer using a more static approach
/// </summary>
/// <typeparam name="T"></typeparam>
internal static class JsvWriter<T>
{
private static readonly WriteObjectDelegate CacheFn;
public static WriteObjectDelegate WriteFn()
{
return CacheFn ?? WriteObject;
}
static JsvWriter()
{
CacheFn = typeof(T) == typeof(object)
? JsvWriter.WriteLateBoundObject
: JsvWriter.Instance.GetWriteFn<T>();
}
public static void WriteObject(TextWriter writer, object value)
{
#if MONOTOUCH
if (writer == null) return;
#endif
CacheFn(writer, value);
}
}
}