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

« back to all changes in this revision

Viewing changes to lib/ServiceStack.Text/src/ServiceStack.Text/Json/JsonTypeSerializer.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.Globalization;
 
15
using System.IO;
 
16
using System.Text;
 
17
using ServiceStack.Text.Common;
 
18
 
 
19
namespace ServiceStack.Text.Json
 
20
{
 
21
        internal class JsonTypeSerializer
 
22
                : ITypeSerializer
 
23
        {
 
24
                public static ITypeSerializer Instance = new JsonTypeSerializer();
 
25
 
 
26
                public string TypeAttrInObject { get { return "{\"__type\":"; } }
 
27
 
 
28
                public static readonly bool[] WhiteSpaceFlags = new bool[(int)' ' + 1];
 
29
 
 
30
                static JsonTypeSerializer()
 
31
                {
 
32
                        WhiteSpaceFlags[(int)' '] = true;
 
33
                        WhiteSpaceFlags[(int)'\t'] = true;
 
34
                        WhiteSpaceFlags[(int)'\r'] = true;
 
35
                        WhiteSpaceFlags[(int)'\n'] = true;
 
36
                }
 
37
 
 
38
                public WriteObjectDelegate GetWriteFn<T>()
 
39
                {
 
40
                        return JsonWriter<T>.WriteFn();
 
41
                }
 
42
 
 
43
                public WriteObjectDelegate GetWriteFn(Type type)
 
44
                {
 
45
                        return JsonWriter.GetWriteFn(type);
 
46
                }
 
47
 
 
48
                public TypeInfo GetTypeInfo(Type type)
 
49
                {
 
50
                        return JsonWriter.GetTypeInfo(type);
 
51
                }
 
52
 
 
53
                /// <summary>
 
54
                /// Shortcut escape when we're sure value doesn't contain any escaped chars
 
55
                /// </summary>
 
56
                /// <param name="writer"></param>
 
57
                /// <param name="value"></param>
 
58
                public void WriteRawString(TextWriter writer, string value)
 
59
                {
 
60
                        writer.Write(JsWriter.QuoteChar);
 
61
                        writer.Write(value);
 
62
                        writer.Write(JsWriter.QuoteChar);
 
63
                }
 
64
 
 
65
                public void WritePropertyName(TextWriter writer, string value)
 
66
                {
 
67
                        if (JsState.WritingKeyCount > 0)
 
68
                        {
 
69
                                writer.Write(JsWriter.EscapedQuoteString);
 
70
                                writer.Write(value);
 
71
                                writer.Write(JsWriter.EscapedQuoteString);
 
72
                        }
 
73
                        else
 
74
                        {
 
75
                                WriteRawString(writer, value);
 
76
                        }
 
77
                }
 
78
 
 
79
                public void WriteString(TextWriter writer, string value)
 
80
                {
 
81
                        JsonUtils.WriteString(writer, value);
 
82
                }
 
83
 
 
84
                public void WriteBuiltIn(TextWriter writer, object value)
 
85
                {
 
86
                        if (JsState.WritingKeyCount > 0 && !JsState.IsWritingValue) writer.Write(JsonUtils.QuoteChar);
 
87
 
 
88
                        WriteRawString(writer, value.ToString());
 
89
 
 
90
                        if (JsState.WritingKeyCount > 0 && !JsState.IsWritingValue) writer.Write(JsonUtils.QuoteChar);
 
91
                }
 
92
 
 
93
                public void WriteObjectString(TextWriter writer, object value)
 
94
                {
 
95
                        JsonUtils.WriteString(writer, value != null ? value.ToString() : null);
 
96
                }
 
97
 
 
98
                public void WriteException(TextWriter writer, object value)
 
99
                {
 
100
                        WriteString(writer, ((Exception)value).Message);
 
101
                }
 
102
 
 
103
                public void WriteDateTime(TextWriter writer, object oDateTime)
 
104
                {
 
105
                        WriteRawString(writer, DateTimeSerializer.ToWcfJsonDate((DateTime)oDateTime));
 
106
                }
 
107
 
 
108
                public void WriteNullableDateTime(TextWriter writer, object dateTime)
 
109
                {
 
110
                        if (dateTime == null)
 
111
                                writer.Write( JsonUtils.Null );
 
112
                        else
 
113
                                WriteDateTime(writer, dateTime);
 
114
                }
 
115
 
 
116
                public void WriteGuid(TextWriter writer, object oValue)
 
117
                {
 
118
                        WriteRawString(writer, ((Guid)oValue).ToString("N"));
 
119
                }
 
120
 
 
121
                public void WriteNullableGuid(TextWriter writer, object oValue)
 
122
                {
 
123
                        if (oValue == null) return;
 
124
                        WriteRawString(writer, ((Guid)oValue).ToString("N"));
 
125
                }
 
126
 
 
127
                public void WriteBytes(TextWriter writer, object oByteValue)
 
128
                {
 
129
                        if (oByteValue == null) return;
 
130
                        WriteRawString(writer, Convert.ToBase64String((byte[])oByteValue));
 
131
                }
 
132
 
 
133
                public void WriteChar(TextWriter writer, object charValue)
 
134
                {
 
135
                        if (charValue == null)
 
136
                                writer.Write(JsonUtils.Null);
 
137
                        else
 
138
                                WriteRawString(writer, ((char)charValue).ToString(CultureInfo.InvariantCulture));
 
139
                }
 
140
 
 
141
                public void WriteByte(TextWriter writer, object byteValue)
 
142
                {
 
143
                        if (byteValue == null)
 
144
                                writer.Write(JsonUtils.Null);
 
145
                        else
 
146
                                writer.Write((byte)byteValue);
 
147
                }
 
148
 
 
149
                public void WriteInt16(TextWriter writer, object intValue)
 
150
                {
 
151
                        if (intValue == null)
 
152
                                writer.Write(JsonUtils.Null);
 
153
                        else
 
154
                                writer.Write((short)intValue);
 
155
                }
 
156
 
 
157
                public void WriteUInt16(TextWriter writer, object intValue)
 
158
                {
 
159
                        if (intValue == null)
 
160
                                writer.Write(JsonUtils.Null);
 
161
                        else
 
162
                                writer.Write((ushort)intValue);
 
163
                }
 
164
 
 
165
                public void WriteInt32(TextWriter writer, object intValue)
 
166
                {
 
167
                        if (intValue == null)
 
168
                                writer.Write(JsonUtils.Null);
 
169
                        else
 
170
                                writer.Write((int)intValue);
 
171
                }
 
172
 
 
173
                public void WriteUInt32(TextWriter writer, object uintValue)
 
174
                {
 
175
                        if (uintValue == null)
 
176
                                writer.Write(JsonUtils.Null);
 
177
                        else
 
178
                                writer.Write((uint)uintValue);
 
179
                }
 
180
 
 
181
                public void WriteInt64(TextWriter writer, object integerValue)
 
182
                {
 
183
                        if (integerValue == null)
 
184
                                writer.Write(JsonUtils.Null);
 
185
                        else
 
186
                                writer.Write((long)integerValue);
 
187
                }
 
188
 
 
189
                public void WriteUInt64(TextWriter writer, object ulongValue)
 
190
                {
 
191
                        if (ulongValue == null)
 
192
                        {
 
193
                                writer.Write(JsonUtils.Null);
 
194
                        }
 
195
                        else
 
196
                                writer.Write((ulong)ulongValue);
 
197
                }
 
198
 
 
199
                public void WriteBool(TextWriter writer, object boolValue)
 
200
                {
 
201
                        if (boolValue == null)
 
202
                                writer.Write(JsonUtils.Null);
 
203
                        else
 
204
                                writer.Write(((bool)boolValue) ? JsonUtils.True : JsonUtils.False);
 
205
                }
 
206
 
 
207
                public void WriteFloat(TextWriter writer, object floatValue)
 
208
                {
 
209
                        if (floatValue == null)
 
210
                                writer.Write(JsonUtils.Null);
 
211
                        else
 
212
                        {
 
213
                                var floatVal = (float)floatValue;
 
214
                                if (Equals(floatVal, float.MaxValue) || Equals(floatVal, float.MinValue))
 
215
                                        writer.Write(floatVal.ToString("r", CultureInfo.InvariantCulture));
 
216
                                else
 
217
                                        writer.Write(floatVal.ToString(CultureInfo.InvariantCulture));
 
218
                        }
 
219
                }
 
220
 
 
221
                public void WriteDouble(TextWriter writer, object doubleValue)
 
222
                {
 
223
                        if (doubleValue == null)
 
224
                                writer.Write(JsonUtils.Null);
 
225
                        else
 
226
                        {
 
227
                                var doubleVal = (double)doubleValue;
 
228
                                if (Equals(doubleVal, double.MaxValue) || Equals(doubleVal, double.MinValue))
 
229
                                        writer.Write(doubleVal.ToString("r", CultureInfo.InvariantCulture));
 
230
                                else
 
231
                                        writer.Write(doubleVal.ToString(CultureInfo.InvariantCulture));
 
232
                        }
 
233
                }
 
234
 
 
235
                public void WriteDecimal(TextWriter writer, object decimalValue)
 
236
                {
 
237
                        if (decimalValue == null)
 
238
                                writer.Write(JsonUtils.Null);
 
239
                        else
 
240
                                writer.Write(((decimal)decimalValue).ToString(CultureInfo.InvariantCulture));
 
241
                }
 
242
 
 
243
                public void WriteEnum(TextWriter writer, object enumValue)
 
244
                {
 
245
                        if (enumValue == null) return;
 
246
                        WriteRawString(writer, enumValue.ToString());
 
247
                }
 
248
 
 
249
                public void WriteEnumFlags(TextWriter writer, object enumFlagValue)
 
250
                {
 
251
                        if (enumFlagValue == null) return;
 
252
                        var intVal = (int)enumFlagValue;
 
253
                        writer.Write(intVal);
 
254
                }
 
255
 
 
256
                public void WriteLinqBinary(TextWriter writer, object linqBinaryValue)
 
257
                {
 
258
#if !MONOTOUCH && !SILVERLIGHT && !XBOX
 
259
                        WriteRawString(writer, Convert.ToBase64String(((System.Data.Linq.Binary)linqBinaryValue).ToArray()));
 
260
#endif
 
261
                }
 
262
 
 
263
                public ParseStringDelegate GetParseFn<T>()
 
264
                {
 
265
                        return JsonReader.Instance.GetParseFn<T>();
 
266
                }
 
267
 
 
268
                public ParseStringDelegate GetParseFn(Type type)
 
269
                {
 
270
                        return JsonReader.GetParseFn(type);
 
271
                }
 
272
 
 
273
                public string ParseRawString(string value)
 
274
                {
 
275
                        if (String.IsNullOrEmpty(value)) return value;
 
276
 
 
277
                        return value[0] == JsonUtils.QuoteChar
 
278
                                ? value.Substring(1, value.Length - 2)
 
279
                                : value;
 
280
                }
 
281
 
 
282
                public string ParseString(string value)
 
283
                {
 
284
                        return string.IsNullOrEmpty(value) ? value : ParseRawString(value);
 
285
                }
 
286
 
 
287
                static readonly char[] IsSafeJsonChars = new[] { JsonUtils.QuoteChar, JsonUtils.EscapeChar };
 
288
 
 
289
                internal static string ParseJsonString(string json, ref int index)
 
290
                {
 
291
                        var jsonLength = json.Length;
 
292
 
 
293
                        for (; index < json.Length; index++) { var ch = json[index]; if (ch >= WhiteSpaceFlags.Length || !WhiteSpaceFlags[ch]) break; } //Whitespace inline
 
294
 
 
295
                        if (json[index] == JsonUtils.QuoteChar)
 
296
                        {
 
297
                                index++;
 
298
 
 
299
                                //MicroOp: See if we can short-circuit evaluation (to avoid StringBuilder)
 
300
                                var strEndPos = json.IndexOfAny(IsSafeJsonChars, index);
 
301
                                if (strEndPos == -1) return json.Substring(index, jsonLength - index);
 
302
                                if (json[strEndPos] == JsonUtils.QuoteChar)
 
303
                                {
 
304
                                        var potentialValue = json.Substring(index, strEndPos - index);
 
305
                                        index = strEndPos + 1;
 
306
                                        return potentialValue;
 
307
                                }
 
308
                        }
 
309
 
 
310
                        var sb = new StringBuilder(jsonLength);
 
311
                        char c;
 
312
 
 
313
                        while (true)
 
314
                        {
 
315
                                if (index == jsonLength) break;
 
316
 
 
317
                                c = json[index++];
 
318
                                if (c == JsonUtils.QuoteChar) break;
 
319
 
 
320
                                if (c == '\\')
 
321
                                {
 
322
 
 
323
                                        if (index == jsonLength)
 
324
                                        {
 
325
                                                break;
 
326
                                        }
 
327
                                        c = json[index++];
 
328
                                        switch (c)
 
329
                                        {
 
330
                                                case '"':
 
331
                                                        sb.Append('"');
 
332
                                                        break;
 
333
                                                case '\\':
 
334
                                                        sb.Append('\\');
 
335
                                                        break;
 
336
                                                case '/':
 
337
                                                        sb.Append('/');
 
338
                                                        break;
 
339
                                                case 'b':
 
340
                                                        sb.Append('\b');
 
341
                                                        break;
 
342
                                                case 'f':
 
343
                                                        sb.Append('\f');
 
344
                                                        break;
 
345
                                                case 'n':
 
346
                                                        sb.Append('\n');
 
347
                                                        break;
 
348
                                                case 'r':
 
349
                                                        sb.Append('\r');
 
350
                                                        break;
 
351
                                                case 't':
 
352
                                                        sb.Append('\t');
 
353
                                                        break;
 
354
                                                case 'u':
 
355
                                                        var remainingLength = jsonLength - index;
 
356
                                                        if (remainingLength >= 4)
 
357
                                                        {
 
358
                                                                var unicodeString = json.Substring(index, 4);
 
359
                                                                var unicodeIntVal = UInt32.Parse(unicodeString, NumberStyles.HexNumber);
 
360
                                                                sb.Append(ConvertFromUtf32((int)unicodeIntVal));
 
361
                                                                index += 4;
 
362
                                                        }
 
363
                                                        else
 
364
                                                        {
 
365
                                                                break;
 
366
                                                        }
 
367
                                                        break;
 
368
                                        }
 
369
                                }
 
370
                                else
 
371
                                {
 
372
                                        sb.Append(c);
 
373
                                }
 
374
                        }
 
375
 
 
376
                        var strValue = sb.ToString();
 
377
                        return strValue == JsonUtils.Null ? null : strValue;
 
378
                }
 
379
 
 
380
                /// <summary>
 
381
                /// Since Silverlight doesn't have char.ConvertFromUtf32() so putting Mono's implemenation inline.
 
382
                /// </summary>
 
383
                /// <param name="utf32"></param>
 
384
                /// <returns></returns>
 
385
                private static string ConvertFromUtf32(int utf32)
 
386
                {
 
387
                        if (utf32 < 0 || utf32 > 0x10FFFF)
 
388
                                throw new ArgumentOutOfRangeException("utf32", "The argument must be from 0 to 0x10FFFF.");
 
389
                        if (0xD800 <= utf32 && utf32 <= 0xDFFF)
 
390
                                throw new ArgumentOutOfRangeException("utf32", "The argument must not be in surrogate pair range.");
 
391
                        if (utf32 < 0x10000)
 
392
                                return new string((char)utf32, 1);
 
393
                        utf32 -= 0x10000;
 
394
                        return new string(new[] {(char) ((utf32 >> 10) + 0xD800),
 
395
                                (char) (utf32 % 0x0400 + 0xDC00)});
 
396
                }
 
397
 
 
398
                private static void EatWhitespace(string json, ref int index)
 
399
                {
 
400
                        int c;
 
401
                        for (; index < json.Length; index++)
 
402
                        {
 
403
                                c = json[index];
 
404
                                if (c >= WhiteSpaceFlags.Length || !WhiteSpaceFlags[c])
 
405
                                {
 
406
                                        break;
 
407
                                }
 
408
                        }
 
409
                }
 
410
 
 
411
                public string EatTypeValue(string value, ref int i)
 
412
                {
 
413
                        return EatValue(value, ref i);
 
414
                }
 
415
 
 
416
                public bool EatMapStartChar(string value, ref int i)
 
417
                {
 
418
                        for (; i < value.Length; i++) { var c = value[i]; if (c >= WhiteSpaceFlags.Length || !WhiteSpaceFlags[c]) break; } //Whitespace inline
 
419
                        return value[i++] == JsWriter.MapStartChar;
 
420
                }
 
421
 
 
422
                public string EatMapKey(string value, ref int i)
 
423
                {
 
424
                        return ParseJsonString(value, ref i);
 
425
                }
 
426
 
 
427
                public bool EatMapKeySeperator(string value, ref int i)
 
428
                {
 
429
                        for (; i < value.Length; i++) { var c = value[i]; if (c >= WhiteSpaceFlags.Length || !WhiteSpaceFlags[c]) break; } //Whitespace inline
 
430
                        if (value.Length == i) return false;
 
431
                        return value[i++] == JsWriter.MapKeySeperator;
 
432
                }
 
433
 
 
434
                public bool EatItemSeperatorOrMapEndChar(string value, ref int i)
 
435
                {
 
436
                        for (; i < value.Length; i++) { var c = value[i]; if (c >= WhiteSpaceFlags.Length || !WhiteSpaceFlags[c]) break; } //Whitespace inline
 
437
 
 
438
                        if (i == value.Length) return false;
 
439
 
 
440
                        var success = value[i] == JsWriter.ItemSeperator
 
441
                                || value[i] == JsWriter.MapEndChar;
 
442
 
 
443
                        i++;
 
444
 
 
445
                        if (success)
 
446
                        {
 
447
                                for (; i < value.Length; i++) { var c = value[i]; if (c >= WhiteSpaceFlags.Length || !WhiteSpaceFlags[c]) break; } //Whitespace inline
 
448
                        }
 
449
 
 
450
                        return success;
 
451
                }
 
452
 
 
453
                public string EatValue(string value, ref int i)
 
454
                {
 
455
                        var valueLength = value.Length;
 
456
                        if (i == valueLength) return null;
 
457
 
 
458
                        for (; i < value.Length; i++) { var c = value[i]; if (c >= WhiteSpaceFlags.Length || !WhiteSpaceFlags[c]) break; } //Whitespace inline
 
459
 
 
460
                        var tokenStartPos = i;
 
461
                        var valueChar = value[i];
 
462
                        var withinQuotes = false;
 
463
                        var endsToEat = 1;
 
464
 
 
465
                        switch (valueChar)
 
466
                        {
 
467
                                //If we are at the end, return.
 
468
                                case JsWriter.ItemSeperator:
 
469
                                case JsWriter.MapEndChar:
 
470
                                        return null;
 
471
 
 
472
                                //Is Within Quotes, i.e. "..."
 
473
                                case JsWriter.QuoteChar:
 
474
                                        return ParseJsonString(value, ref i);
 
475
 
 
476
                                //Is Type/Map, i.e. {...}
 
477
                                case JsWriter.MapStartChar:
 
478
                                        while (++i < valueLength && endsToEat > 0)
 
479
                                        {
 
480
                                                valueChar = value[i];
 
481
 
 
482
                                                if (valueChar == JsWriter.QuoteChar
 
483
                                                        && value[i - 1] != JsonUtils.EscapeChar)
 
484
                                                        withinQuotes = !withinQuotes;
 
485
 
 
486
                                                if (withinQuotes)
 
487
                                                        continue;
 
488
 
 
489
                                                if (valueChar == JsWriter.MapStartChar)
 
490
                                                        endsToEat++;
 
491
 
 
492
                                                if (valueChar == JsWriter.MapEndChar)
 
493
                                                        endsToEat--;
 
494
                                        }
 
495
                                        return value.Substring(tokenStartPos, i - tokenStartPos);
 
496
 
 
497
                                //Is List, i.e. [...]
 
498
                                case JsWriter.ListStartChar:
 
499
                                        while (++i < valueLength && endsToEat > 0)
 
500
                                        {
 
501
                                                valueChar = value[i];
 
502
 
 
503
                                                if (valueChar == JsWriter.QuoteChar
 
504
                                                        && value[i - 1] != JsonUtils.EscapeChar)
 
505
                                                        withinQuotes = !withinQuotes;
 
506
 
 
507
                                                if (withinQuotes)
 
508
                                                        continue;
 
509
 
 
510
                                                if (valueChar == JsWriter.ListStartChar)
 
511
                                                        endsToEat++;
 
512
 
 
513
                                                if (valueChar == JsWriter.ListEndChar)
 
514
                                                        endsToEat--;
 
515
                                        }
 
516
                                        return value.Substring(tokenStartPos, i - tokenStartPos);
 
517
                        }
 
518
 
 
519
                        //Is Value
 
520
                        while (++i < valueLength)
 
521
                        {
 
522
                                valueChar = value[i];
 
523
 
 
524
                                if (valueChar == JsWriter.ItemSeperator
 
525
                                        || valueChar == JsWriter.MapEndChar
 
526
                                        //If it doesn't have quotes it's either a keyword or number so also has a ws boundary
 
527
                                        || (valueChar < WhiteSpaceFlags.Length && WhiteSpaceFlags[valueChar])
 
528
                                )
 
529
                                {
 
530
                                        break;
 
531
                                }
 
532
                        }
 
533
 
 
534
                        var strValue = value.Substring(tokenStartPos, i - tokenStartPos);
 
535
                        return strValue == JsonUtils.Null ? null : strValue;
 
536
                }
 
537
        }
 
538
 
 
539
}
 
 
b'\\ No newline at end of file'