~ubuntu-branches/ubuntu/trusty/smuxi/trusty-proposed

« back to all changes in this revision

Viewing changes to lib/ServiceStack.Text/src/ServiceStack.Text/Common/WriteDictionary.cs

  • Committer: Package Import Robot
  • Author(s): Mirco Bauer
  • Date: 2013-05-25 22:11:31 UTC
  • mfrom: (1.2.12)
  • Revision ID: package-import@ubuntu.com-20130525221131-nd2mc0kzubuwyx20
Tags: 0.8.11-1
* [22d13d5] Imported Upstream version 0.8.11
* [6d2b95a] Refreshed patches
* [89eb66e] Added ServiceStack libraries to smuxi-engine package
* [848ab10] Enable Campfire engine
* [c6dbdc7] Always build db4o for predictable build result
* [13ec489] Exclude OS X specific libraries from dh_clideps

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
//
 
2
// http://code.google.com/p/servicestack/wiki/TypeSerializer
 
3
// ServiceStack.Text: .NET C# POCO Type Text Serializer.
 
4
//
 
5
// Authors:
 
6
//   Demis Bellot (demis.bellot@gmail.com)
 
7
//
 
8
// Copyright 2011 Liquidbit Ltd.
 
9
//
 
10
// Licensed under the same terms of ServiceStack: new BSD license.
 
11
//
 
12
 
 
13
using System;
 
14
using System.Collections;
 
15
using System.Collections.Generic;
 
16
using System.IO;
 
17
using System.Reflection;
 
18
using System.Threading;
 
19
using ServiceStack.Text.Json;
 
20
 
 
21
namespace ServiceStack.Text.Common
 
22
{
 
23
        internal delegate void WriteMapDelegate(
 
24
                TextWriter writer,
 
25
                object oMap,
 
26
                WriteObjectDelegate writeKeyFn,
 
27
                WriteObjectDelegate writeValueFn);
 
28
 
 
29
        internal static class WriteDictionary<TSerializer>
 
30
                where TSerializer : ITypeSerializer
 
31
        {
 
32
                private static readonly ITypeSerializer Serializer = JsWriter.GetTypeSerializer<TSerializer>();
 
33
 
 
34
                internal class MapKey
 
35
                {
 
36
                        internal Type KeyType;
 
37
                        internal Type ValueType;
 
38
 
 
39
                        public MapKey(Type keyType, Type valueType)
 
40
                        {
 
41
                                KeyType = keyType;
 
42
                                ValueType = valueType;
 
43
                        }
 
44
 
 
45
                        public bool Equals(MapKey other)
 
46
                        {
 
47
                                if (ReferenceEquals(null, other)) return false;
 
48
                                if (ReferenceEquals(this, other)) return true;
 
49
                                return Equals(other.KeyType, KeyType) && Equals(other.ValueType, ValueType);
 
50
                        }
 
51
 
 
52
                        public override bool Equals(object obj)
 
53
                        {
 
54
                                if (ReferenceEquals(null, obj)) return false;
 
55
                                if (ReferenceEquals(this, obj)) return true;
 
56
                                if (obj.GetType() != typeof(MapKey)) return false;
 
57
                                return Equals((MapKey)obj);
 
58
                        }
 
59
 
 
60
                        public override int GetHashCode()
 
61
                        {
 
62
                                unchecked
 
63
                                {
 
64
                                        return ((KeyType != null ? KeyType.GetHashCode() : 0) * 397) ^ (ValueType != null ? ValueType.GetHashCode() : 0);
 
65
                                }
 
66
                        }
 
67
                }
 
68
 
 
69
                static Dictionary<MapKey, WriteMapDelegate> CacheFns = new Dictionary<MapKey, WriteMapDelegate>();
 
70
 
 
71
                public static Action<TextWriter, object, WriteObjectDelegate, WriteObjectDelegate>
 
72
                        GetWriteGenericDictionary(Type keyType, Type valueType)
 
73
                {
 
74
                        WriteMapDelegate writeFn;
 
75
            var mapKey = new MapKey(keyType, valueType);
 
76
            if (CacheFns.TryGetValue(mapKey, out writeFn)) return writeFn.Invoke;
 
77
 
 
78
            var genericType = typeof(ToStringDictionaryMethods<,,>).MakeGenericType(keyType, valueType, typeof(TSerializer));
 
79
            var mi = genericType.GetMethod("WriteIDictionary", BindingFlags.Static | BindingFlags.Public);
 
80
            writeFn = (WriteMapDelegate)Delegate.CreateDelegate(typeof(WriteMapDelegate), mi);
 
81
 
 
82
            Dictionary<MapKey, WriteMapDelegate> snapshot, newCache;
 
83
            do
 
84
            {
 
85
                snapshot = CacheFns;
 
86
                newCache = new Dictionary<MapKey, WriteMapDelegate>(CacheFns);
 
87
                newCache[mapKey] = writeFn;
 
88
 
 
89
            } while (!ReferenceEquals(
 
90
                Interlocked.CompareExchange(ref CacheFns, newCache, snapshot), snapshot));
 
91
            
 
92
            return writeFn.Invoke;
 
93
                }
 
94
 
 
95
                public static void WriteIDictionary(TextWriter writer, object oMap)
 
96
                {
 
97
                        WriteObjectDelegate writeKeyFn = null;
 
98
                        WriteObjectDelegate writeValueFn = null;
 
99
 
 
100
                        writer.Write(JsWriter.MapStartChar);
 
101
                        var encodeMapKey = false;
 
102
 
 
103
                        var map = (IDictionary)oMap;
 
104
                        var ranOnce = false;
 
105
                        foreach (var key in map.Keys)
 
106
                        {
 
107
                                var dictionaryValue = map[key];
 
108
 
 
109
                var isNull = (dictionaryValue == null);
 
110
                if (isNull && !JsConfig.IncludeNullValues) continue;
 
111
 
 
112
                                if (writeKeyFn == null)
 
113
                                {
 
114
                                        var keyType = key.GetType();
 
115
                                        writeKeyFn = Serializer.GetWriteFn(keyType);
 
116
                                        encodeMapKey = Serializer.GetTypeInfo(keyType).EncodeMapKey;
 
117
                                }
 
118
 
 
119
                                if (writeValueFn == null)
 
120
                                        writeValueFn = Serializer.GetWriteFn(dictionaryValue.GetType());
 
121
 
 
122
                                JsWriter.WriteItemSeperatorIfRanOnce(writer, ref ranOnce);
 
123
 
 
124
                                JsState.WritingKeyCount++;
 
125
                                JsState.IsWritingValue = false;
 
126
 
 
127
                                if (encodeMapKey)
 
128
                                {
 
129
                                        JsState.IsWritingValue = true; //prevent ""null""
 
130
                                        writer.Write(JsWriter.QuoteChar);
 
131
                                        writeKeyFn(writer, key);
 
132
                                        writer.Write(JsWriter.QuoteChar);
 
133
                                }
 
134
                                else
 
135
                                {
 
136
                                        writeKeyFn(writer, key);
 
137
                                }
 
138
 
 
139
                                JsState.WritingKeyCount--;
 
140
 
 
141
                                writer.Write(JsWriter.MapKeySeperator);
 
142
 
 
143
                if (isNull)
 
144
                {
 
145
                    writer.Write(JsonUtils.Null);
 
146
                }
 
147
                else
 
148
                {
 
149
                    JsState.IsWritingValue = true;
 
150
                    writeValueFn(writer, dictionaryValue);
 
151
                    JsState.IsWritingValue = false;
 
152
                }
 
153
                        }
 
154
 
 
155
                        writer.Write(JsWriter.MapEndChar);
 
156
                }
 
157
        }
 
158
 
 
159
        internal static class ToStringDictionaryMethods<TKey, TValue, TSerializer>
 
160
                where TSerializer : ITypeSerializer
 
161
        {
 
162
                private static readonly ITypeSerializer Serializer = JsWriter.GetTypeSerializer<TSerializer>();
 
163
 
 
164
                public static void WriteIDictionary(
 
165
                        TextWriter writer,
 
166
                        object oMap,
 
167
                        WriteObjectDelegate writeKeyFn,
 
168
                        WriteObjectDelegate writeValueFn)
 
169
                {
 
170
                        if (writer == null) return; //AOT
 
171
                        WriteGenericIDictionary(writer, (IDictionary<TKey, TValue>)oMap, writeKeyFn, writeValueFn);
 
172
                }
 
173
 
 
174
                public static void WriteGenericIDictionary(
 
175
                        TextWriter writer,
 
176
                        IDictionary<TKey, TValue> map,
 
177
                        WriteObjectDelegate writeKeyFn,
 
178
                        WriteObjectDelegate writeValueFn)
 
179
                {
 
180
                    if (map == null)
 
181
                    {
 
182
                        writer.Write(JsonUtils.Null);
 
183
                return;
 
184
                    }
 
185
                        writer.Write(JsWriter.MapStartChar);
 
186
 
 
187
                        var encodeMapKey = Serializer.GetTypeInfo(typeof(TKey)).EncodeMapKey;
 
188
 
 
189
                        var ranOnce = false;
 
190
                        foreach (var kvp in map)
 
191
                        {
 
192
                var isNull = (kvp.Value == null);
 
193
                if (isNull && !JsConfig.IncludeNullValues) continue;
 
194
 
 
195
                                JsWriter.WriteItemSeperatorIfRanOnce(writer, ref ranOnce);
 
196
 
 
197
                                JsState.WritingKeyCount++;
 
198
                JsState.IsWritingValue = false;
 
199
 
 
200
                                if (encodeMapKey)
 
201
                                {
 
202
                                        JsState.IsWritingValue = true; //prevent ""null""
 
203
                                        writer.Write(JsWriter.QuoteChar);
 
204
                                        writeKeyFn(writer, kvp.Key);
 
205
                                        writer.Write(JsWriter.QuoteChar);
 
206
                                }
 
207
                                else
 
208
                                {
 
209
                                        writeKeyFn(writer, kvp.Key);
 
210
                                }
 
211
                                
 
212
                                JsState.WritingKeyCount--;
 
213
 
 
214
                                writer.Write(JsWriter.MapKeySeperator);
 
215
 
 
216
                if (isNull)
 
217
                {
 
218
                    writer.Write(JsonUtils.Null);
 
219
                }
 
220
                else
 
221
                {
 
222
                    JsState.IsWritingValue = true;
 
223
                    writeValueFn(writer, kvp.Value);
 
224
                    JsState.IsWritingValue = false;
 
225
                }
 
226
                        }
 
227
 
 
228
                        writer.Write(JsWriter.MapEndChar);
 
229
                }
 
230
        }
 
231
}
 
 
b'\\ No newline at end of file'