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

« back to all changes in this revision

Viewing changes to lib/ServiceStack.Text/src/ServiceStack.Text/Common/JsWriter.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
using System;
 
2
using System.Collections;
 
3
using System.Collections.Generic;
 
4
using System.IO;
 
5
 
 
6
using ServiceStack.Text.Json;
 
7
using ServiceStack.Text.Jsv;
 
8
 
 
9
namespace ServiceStack.Text.Common
 
10
{
 
11
    public static class JsWriter
 
12
    {
 
13
        public const string TypeAttr = "__type";
 
14
 
 
15
        public const char MapStartChar = '{';
 
16
        public const char MapKeySeperator = ':';
 
17
        public const char ItemSeperator = ',';
 
18
        public const char MapEndChar = '}';
 
19
        public const string MapNullValue = "\"\"";
 
20
        public const string EmptyMap = "{}";
 
21
 
 
22
        public const char ListStartChar = '[';
 
23
        public const char ListEndChar = ']';
 
24
        public const char ReturnChar = '\r';
 
25
        public const char LineFeedChar = '\n';
 
26
 
 
27
        public const char QuoteChar = '"';
 
28
        public const string QuoteString = "\"";
 
29
        public const string EscapedQuoteString = "\\\"";
 
30
        public const string ItemSeperatorString = ",";
 
31
        public const string MapKeySeperatorString = ":";
 
32
 
 
33
        public static readonly char[] CsvChars = new[] { ItemSeperator, QuoteChar };
 
34
        public static readonly char[] EscapeChars = new[] { QuoteChar, MapKeySeperator, ItemSeperator, MapStartChar, MapEndChar, ListStartChar, ListEndChar, ReturnChar, LineFeedChar };
 
35
 
 
36
        private const int LengthFromLargestChar = '}' + 1;
 
37
        private static readonly bool[] EscapeCharFlags = new bool[LengthFromLargestChar];
 
38
 
 
39
        static JsWriter()
 
40
        {
 
41
            foreach (var escapeChar in EscapeChars)
 
42
            {
 
43
                EscapeCharFlags[escapeChar] = true;
 
44
            }
 
45
            var loadConfig = JsConfig.IncludeNullValues;
 
46
        }
 
47
 
 
48
        public static void WriteDynamic(Action callback)
 
49
        {
 
50
            JsState.IsWritingDynamic = true;
 
51
            try
 
52
            {
 
53
                callback();
 
54
            }
 
55
            finally
 
56
            {
 
57
                JsState.IsWritingDynamic = false;
 
58
            }
 
59
        }
 
60
 
 
61
        /// <summary>
 
62
        /// micro optimizations: using flags instead of value.IndexOfAny(EscapeChars)
 
63
        /// </summary>
 
64
        /// <param name="value"></param>
 
65
        /// <returns></returns>
 
66
        public static bool HasAnyEscapeChars(string value)
 
67
        {
 
68
            var len = value.Length;
 
69
            for (var i = 0; i < len; i++)
 
70
            {
 
71
                var c = value[i];
 
72
                if (c >= LengthFromLargestChar || !EscapeCharFlags[c]) continue;
 
73
                return true;
 
74
            }
 
75
            return false;
 
76
        }
 
77
 
 
78
        internal static void WriteItemSeperatorIfRanOnce(TextWriter writer, ref bool ranOnce)
 
79
        {
 
80
            if (ranOnce)
 
81
                writer.Write(ItemSeperator);
 
82
            else
 
83
                ranOnce = true;
 
84
 
 
85
            foreach (var escapeChar in EscapeChars)
 
86
            {
 
87
                EscapeCharFlags[escapeChar] = true;
 
88
            }
 
89
        }
 
90
 
 
91
        internal static bool ShouldUseDefaultToStringMethod(Type type)
 
92
        {
 
93
            return type == typeof(byte) || type == typeof(byte?)
 
94
                || type == typeof(short) || type == typeof(short?)
 
95
                || type == typeof(ushort) || type == typeof(ushort?)
 
96
                || type == typeof(int) || type == typeof(int?)
 
97
                || type == typeof(uint) || type == typeof(uint?)
 
98
                || type == typeof(long) || type == typeof(long?)
 
99
                || type == typeof(ulong) || type == typeof(ulong?)
 
100
                || type == typeof(bool) || type == typeof(bool?)
 
101
                || type == typeof(DateTime) || type == typeof(DateTime?)
 
102
                || type == typeof(Guid) || type == typeof(Guid?)
 
103
                || type == typeof(float) || type == typeof(float?)
 
104
                || type == typeof(double) || type == typeof(double?)
 
105
                || type == typeof(decimal) || type == typeof(decimal?);
 
106
        }
 
107
 
 
108
        internal static ITypeSerializer GetTypeSerializer<TSerializer>()
 
109
        {
 
110
            if (typeof(TSerializer) == typeof(JsvTypeSerializer))
 
111
                return JsvTypeSerializer.Instance;
 
112
 
 
113
            if (typeof(TSerializer) == typeof(JsonTypeSerializer))
 
114
                return JsonTypeSerializer.Instance;
 
115
 
 
116
            throw new NotSupportedException(typeof(TSerializer).Name);
 
117
        }
 
118
    }
 
119
 
 
120
    internal class JsWriter<TSerializer>
 
121
        where TSerializer : ITypeSerializer
 
122
    {
 
123
        private static readonly ITypeSerializer Serializer = JsWriter.GetTypeSerializer<TSerializer>();
 
124
 
 
125
        public JsWriter()
 
126
        {
 
127
            this.SpecialTypes = new Dictionary<Type, WriteObjectDelegate>
 
128
                {
 
129
                        { typeof(Uri), Serializer.WriteObjectString },
 
130
                        { typeof(Type), WriteType },
 
131
                        { typeof(Exception), Serializer.WriteException },
 
132
#if !MONOTOUCH && !SILVERLIGHT && !XBOX
 
133
                { typeof(System.Data.Linq.Binary), Serializer.WriteLinqBinary },
 
134
#endif
 
135
                };
 
136
        }
 
137
 
 
138
        public WriteObjectDelegate GetValueTypeToStringMethod(Type type)
 
139
        {
 
140
                        if (type == typeof(char) || type == typeof(char?))
 
141
                                return Serializer.WriteChar;
 
142
                        if (type == typeof(int) || type == typeof(int?))
 
143
                                return Serializer.WriteInt32;
 
144
                        if (type == typeof(long) || type == typeof(long?))
 
145
                                return Serializer.WriteInt64;
 
146
                        if (type == typeof(ulong) || type == typeof(ulong?))
 
147
                                return Serializer.WriteUInt64;
 
148
                        if (type == typeof(uint) || type == typeof(uint?))
 
149
                                return Serializer.WriteUInt32;
 
150
 
 
151
                        if (type == typeof(byte) || type == typeof(byte?))
 
152
                                return Serializer.WriteByte;
 
153
 
 
154
                        if (type == typeof(short) || type == typeof(short?))
 
155
                                return Serializer.WriteInt16;
 
156
            if (type == typeof(ushort) || type == typeof(ushort?))
 
157
                                return Serializer.WriteUInt16;
 
158
 
 
159
            if (type == typeof(bool) || type == typeof(bool?))
 
160
                return Serializer.WriteBool;
 
161
 
 
162
            if (type == typeof(DateTime))
 
163
                return Serializer.WriteDateTime;
 
164
 
 
165
            if (type == typeof(DateTime?))
 
166
                return Serializer.WriteNullableDateTime;
 
167
 
 
168
            if (type == typeof(Guid))
 
169
                return Serializer.WriteGuid;
 
170
 
 
171
            if (type == typeof(Guid?))
 
172
                return Serializer.WriteNullableGuid;
 
173
 
 
174
            if (type == typeof(float) || type == typeof(float?))
 
175
                return Serializer.WriteFloat;
 
176
 
 
177
            if (type == typeof(double) || type == typeof(double?))
 
178
                return Serializer.WriteDouble;
 
179
 
 
180
            if (type == typeof(decimal) || type == typeof(decimal?))
 
181
                return Serializer.WriteDecimal;
 
182
 
 
183
            if (type.IsEnum || type.UnderlyingSystemType.IsEnum)
 
184
                return type.GetCustomAttributes(typeof(FlagsAttribute), false).Length > 0
 
185
                    ? (WriteObjectDelegate)Serializer.WriteEnumFlags
 
186
                    : Serializer.WriteEnum;
 
187
 
 
188
            return Serializer.WriteObjectString;
 
189
        }
 
190
 
 
191
        internal WriteObjectDelegate GetWriteFn<T>()
 
192
        {
 
193
            if (typeof(T) == typeof(string))
 
194
            {
 
195
                return Serializer.WriteObjectString;
 
196
            }
 
197
 
 
198
            if (typeof(T).IsValueType)
 
199
            {
 
200
                return JsConfig<T>.SerializeFn != null
 
201
                    ? JsConfig<T>.WriteFn<TSerializer>
 
202
                    : GetValueTypeToStringMethod(typeof(T));
 
203
            }
 
204
 
 
205
            var specialWriteFn = GetSpecialWriteFn(typeof(T));
 
206
            if (specialWriteFn != null)
 
207
            {
 
208
                return specialWriteFn;
 
209
            }
 
210
 
 
211
            if (typeof(T).IsArray)
 
212
            {
 
213
                if (typeof(T) == typeof(byte[]))
 
214
                    return (w, x) => WriteLists.WriteBytes(Serializer, w, x);
 
215
 
 
216
                if (typeof(T) == typeof(string[]))
 
217
                    return (w, x) => WriteLists.WriteStringArray(Serializer, w, x);
 
218
 
 
219
                if (typeof(T) == typeof(int[]))
 
220
                    return WriteListsOfElements<int, TSerializer>.WriteGenericArrayValueType;
 
221
                if (typeof(T) == typeof(long[]))
 
222
                    return WriteListsOfElements<long, TSerializer>.WriteGenericArrayValueType;
 
223
 
 
224
                var elementType = typeof(T).GetElementType();
 
225
                var writeFn = WriteListsOfElements<TSerializer>.GetGenericWriteArray(elementType);
 
226
                return writeFn;
 
227
            }
 
228
 
 
229
            if (typeof(T).IsGenericType())
 
230
            {
 
231
                if (typeof(T).IsOrHasGenericInterfaceTypeOf(typeof(IList<>)))
 
232
                    return WriteLists<T, TSerializer>.Write;
 
233
 
 
234
                var mapInterface = typeof(T).GetTypeWithGenericTypeDefinitionOf(typeof(IDictionary<,>));
 
235
                if (mapInterface != null)
 
236
                {
 
237
                    var mapTypeArgs = mapInterface.GetGenericArguments();
 
238
                    var writeFn = WriteDictionary<TSerializer>.GetWriteGenericDictionary(
 
239
                        mapTypeArgs[0], mapTypeArgs[1]);
 
240
 
 
241
                    var keyWriteFn = Serializer.GetWriteFn(mapTypeArgs[0]);
 
242
                    var valueWriteFn = Serializer.GetWriteFn(mapTypeArgs[1]);
 
243
 
 
244
                    return (w, x) => writeFn(w, x, keyWriteFn, valueWriteFn);
 
245
                }
 
246
 
 
247
                var enumerableInterface = typeof(T).GetTypeWithGenericTypeDefinitionOf(typeof(IEnumerable<>));
 
248
                if (enumerableInterface != null)
 
249
                {
 
250
                    var elementType = enumerableInterface.GetGenericArguments()[0];
 
251
                    var writeFn = WriteListsOfElements<TSerializer>.GetGenericWriteEnumerable(elementType);
 
252
                    return writeFn;
 
253
                }
 
254
            }
 
255
 
 
256
            var isCollection = typeof(T).IsOrHasGenericInterfaceTypeOf(typeof(ICollection));
 
257
            if (isCollection)
 
258
            {
 
259
                var isDictionary = typeof(T).IsAssignableFrom(typeof(IDictionary))
 
260
                    || typeof(T).HasInterface(typeof(IDictionary));
 
261
                if (isDictionary)
 
262
                {
 
263
                    return WriteDictionary<TSerializer>.WriteIDictionary;
 
264
                }
 
265
 
 
266
                return WriteListsOfElements<TSerializer>.WriteIEnumerable;
 
267
            }
 
268
 
 
269
            var isEnumerable = typeof(T).IsAssignableFrom(typeof(IEnumerable))
 
270
                || typeof(T).HasInterface(typeof(IEnumerable));
 
271
 
 
272
            if (isEnumerable)
 
273
            {
 
274
                return WriteListsOfElements<TSerializer>.WriteIEnumerable;
 
275
            }
 
276
 
 
277
            if (typeof(T).IsClass || typeof(T).IsInterface)
 
278
            {
 
279
                var typeToStringMethod = WriteType<T, TSerializer>.Write;
 
280
                if (typeToStringMethod != null)
 
281
                {
 
282
                    return typeToStringMethod;
 
283
                }
 
284
            }
 
285
 
 
286
            return Serializer.WriteBuiltIn;
 
287
        }
 
288
 
 
289
 
 
290
        public Dictionary<Type, WriteObjectDelegate> SpecialTypes;
 
291
 
 
292
        public WriteObjectDelegate GetSpecialWriteFn(Type type)
 
293
        {
 
294
            WriteObjectDelegate writeFn = null;
 
295
            if (SpecialTypes.TryGetValue(type, out writeFn))
 
296
                return writeFn;
 
297
 
 
298
            if (type.IsInstanceOfType(typeof(Type)))
 
299
                return WriteType;
 
300
 
 
301
            if (type.IsInstanceOf(typeof(Exception)))
 
302
                return Serializer.WriteException;
 
303
 
 
304
            return null;
 
305
        }
 
306
 
 
307
        public void WriteType(TextWriter writer, object value)
 
308
        {
 
309
            Serializer.WriteRawString(writer, ((Type)value).ToTypeString());
 
310
        }
 
311
 
 
312
    }
 
313
}
 
 
b'\\ No newline at end of file'