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

« back to all changes in this revision

Viewing changes to lib/ServiceStack.Text/src/ServiceStack.Text/Common/DeserializeCollection.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.Generic;
 
15
using System.Reflection;
 
16
using System.Threading;
 
17
 
 
18
namespace ServiceStack.Text.Common
 
19
{
 
20
        internal static class DeserializeCollection<TSerializer>
 
21
                where TSerializer : ITypeSerializer
 
22
        {
 
23
                private static readonly ITypeSerializer Serializer = JsWriter.GetTypeSerializer<TSerializer>();
 
24
 
 
25
                public static ParseStringDelegate GetParseMethod(Type type)
 
26
                {
 
27
                        var collectionInterface = type.GetTypeWithGenericInterfaceOf(typeof(ICollection<>));
 
28
                        if (collectionInterface == null)
 
29
                                throw new ArgumentException(string.Format("Type {0} is not of type ICollection<>", type.FullName));
 
30
 
 
31
                        //optimized access for regularly used types
 
32
                        if (type.HasInterface(typeof(ICollection<string>)))
 
33
                                return value => ParseStringCollection(value, type);
 
34
 
 
35
                        if (type.HasInterface(typeof(ICollection<int>)))
 
36
                                return value => ParseIntCollection(value, type);
 
37
 
 
38
                        var elementType =  collectionInterface.GetGenericArguments()[0];
 
39
 
 
40
                        var supportedTypeParseMethod = Serializer.GetParseFn(elementType);
 
41
                        if (supportedTypeParseMethod != null)
 
42
                        {
 
43
                                var createCollectionType = type.HasAnyTypeDefinitionsOf(typeof(ICollection<>))
 
44
                                        ? null : type;
 
45
 
 
46
                                return value => ParseCollectionType(value, createCollectionType, elementType, supportedTypeParseMethod);
 
47
                        }
 
48
 
 
49
                        return null;
 
50
                }
 
51
 
 
52
                public static ICollection<string> ParseStringCollection(string value, Type createType)
 
53
                {
 
54
                        var items = DeserializeArrayWithElements<string, TSerializer>.ParseGenericArray(value, Serializer.ParseString);
 
55
                        return CreateAndPopulate(createType, items);
 
56
                }
 
57
 
 
58
                public static ICollection<int> ParseIntCollection(string value, Type createType)
 
59
                {
 
60
                        var items = DeserializeArrayWithElements<int, TSerializer>.ParseGenericArray(value, x => int.Parse(x));
 
61
                        return CreateAndPopulate(createType, items);
 
62
                }
 
63
 
 
64
                public static ICollection<T> ParseCollection<T>(string value, Type createType, ParseStringDelegate parseFn)
 
65
                {
 
66
                        if (value == null) return null;
 
67
 
 
68
                        var items = DeserializeArrayWithElements<T, TSerializer>.ParseGenericArray(value, parseFn);
 
69
                        return CreateAndPopulate(createType, items);
 
70
                }
 
71
 
 
72
                private static ICollection<T> CreateAndPopulate<T>(Type ofCollectionType, T[] withItems)
 
73
                {
 
74
                        if (ofCollectionType == null) return new List<T>(withItems);
 
75
 
 
76
                        var genericTypeDefinition = ofCollectionType.IsGenericType()
 
77
                                ? ofCollectionType.GetGenericTypeDefinition()
 
78
                                : null;
 
79
#if !XBOX
 
80
                        if (genericTypeDefinition == typeof(HashSet<T>))
 
81
                                return new HashSet<T>(withItems);
 
82
#endif
 
83
                        if (genericTypeDefinition == typeof(LinkedList<T>))
 
84
                                return new LinkedList<T>(withItems);
 
85
 
 
86
                        var collection = (ICollection<T>)ofCollectionType.CreateInstance();
 
87
                        foreach (var item in withItems)
 
88
                        {
 
89
                                collection.Add(item);
 
90
                        }
 
91
                        return collection;
 
92
                }
 
93
 
 
94
                private static Dictionary<Type, ParseCollectionDelegate> ParseDelegateCache 
 
95
                        = new Dictionary<Type, ParseCollectionDelegate>();
 
96
 
 
97
                private delegate object ParseCollectionDelegate(string value, Type createType, ParseStringDelegate parseFn);
 
98
 
 
99
                public static object ParseCollectionType(string value, Type createType, Type elementType, ParseStringDelegate parseFn)
 
100
                {
 
101
                        ParseCollectionDelegate parseDelegate;
 
102
                        if (ParseDelegateCache.TryGetValue(elementType, out parseDelegate))
 
103
                return parseDelegate(value, createType, parseFn);
 
104
 
 
105
            var mi = typeof(DeserializeCollection<TSerializer>).GetMethod("ParseCollection", BindingFlags.Static | BindingFlags.Public);
 
106
            var genericMi = mi.MakeGenericMethod(new[] { elementType });
 
107
            parseDelegate = (ParseCollectionDelegate)Delegate.CreateDelegate(typeof(ParseCollectionDelegate), genericMi);
 
108
 
 
109
            Dictionary<Type, ParseCollectionDelegate> snapshot, newCache;
 
110
            do
 
111
            {
 
112
                snapshot = ParseDelegateCache;
 
113
                newCache = new Dictionary<Type, ParseCollectionDelegate>(ParseDelegateCache);
 
114
                newCache[elementType] = parseDelegate;
 
115
 
 
116
            } while (!ReferenceEquals(
 
117
                Interlocked.CompareExchange(ref ParseDelegateCache, newCache, snapshot), snapshot));
 
118
            
 
119
            return parseDelegate(value, createType, parseFn);
 
120
                }
 
121
        }
 
122
}
 
 
b'\\ No newline at end of file'