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

« back to all changes in this revision

Viewing changes to lib/ServiceStack.Text/src/ServiceStack.Text/Common/DeserializeArray.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.Collections.Specialized;
 
16
using System.Reflection;
 
17
using System.Threading;
 
18
 
 
19
namespace ServiceStack.Text.Common
 
20
{
 
21
        internal static class DeserializeArrayWithElements<TSerializer>
 
22
                where TSerializer : ITypeSerializer
 
23
        {
 
24
                private static Dictionary<Type, ParseArrayOfElementsDelegate> ParseDelegateCache 
 
25
                        = new Dictionary<Type, ParseArrayOfElementsDelegate>();
 
26
 
 
27
                private delegate object ParseArrayOfElementsDelegate(string value, ParseStringDelegate parseFn);
 
28
 
 
29
                public static Func<string, ParseStringDelegate, object> GetParseFn(Type type)
 
30
                {
 
31
                        ParseArrayOfElementsDelegate parseFn;
 
32
                        if (ParseDelegateCache.TryGetValue(type, out parseFn)) return parseFn.Invoke;
 
33
 
 
34
            var genericType = typeof(DeserializeArrayWithElements<,>).MakeGenericType(type, typeof(TSerializer));
 
35
            var mi = genericType.GetMethod("ParseGenericArray", BindingFlags.Public | BindingFlags.Static);
 
36
            parseFn = (ParseArrayOfElementsDelegate)Delegate.CreateDelegate(typeof(ParseArrayOfElementsDelegate), mi);
 
37
 
 
38
            Dictionary<Type, ParseArrayOfElementsDelegate> snapshot, newCache;
 
39
            do
 
40
            {
 
41
                snapshot = ParseDelegateCache;
 
42
                newCache = new Dictionary<Type, ParseArrayOfElementsDelegate>(ParseDelegateCache);
 
43
                newCache[type] = parseFn;
 
44
 
 
45
            } while (!ReferenceEquals(
 
46
                Interlocked.CompareExchange(ref ParseDelegateCache, newCache, snapshot), snapshot));
 
47
 
 
48
                        return parseFn.Invoke;
 
49
                }
 
50
        }
 
51
 
 
52
        internal static class DeserializeArrayWithElements<T, TSerializer>
 
53
                where TSerializer : ITypeSerializer
 
54
        {
 
55
                private static readonly ITypeSerializer Serializer = JsWriter.GetTypeSerializer<TSerializer>();
 
56
 
 
57
                public static T[] ParseGenericArray(string value, ParseStringDelegate elementParseFn)
 
58
                {
 
59
                        if ((value = DeserializeListWithElements<TSerializer>.StripList(value)) == null) return null;
 
60
                        if (value == string.Empty) return new T[0];
 
61
 
 
62
                        if (value[0] == JsWriter.MapStartChar)
 
63
                        {
 
64
                                var itemValues = new List<string>();
 
65
                                var i = 0;
 
66
                                do
 
67
                                {
 
68
                                        itemValues.Add(Serializer.EatTypeValue(value, ref i));
 
69
                                } while (++i < value.Length);
 
70
 
 
71
                                var results = new T[itemValues.Count];
 
72
                                for (var j=0; j < itemValues.Count; j++)
 
73
                                {
 
74
                                        results[j] = (T)elementParseFn(itemValues[j]);
 
75
                                }
 
76
                                return results;
 
77
                        }
 
78
                        else
 
79
                        {
 
80
                                var to = new List<T>();
 
81
                                var valueLength = value.Length;
 
82
 
 
83
                                var i = 0;
 
84
                                while (i < valueLength)
 
85
                                {
 
86
                                        var elementValue = Serializer.EatValue(value, ref i);
 
87
                                        var listValue = elementValue;
 
88
                                        to.Add((T)elementParseFn(listValue));
 
89
                                        Serializer.EatItemSeperatorOrMapEndChar(value, ref i);
 
90
                                }
 
91
 
 
92
                                return to.ToArray();
 
93
                        }
 
94
                }
 
95
        }
 
96
 
 
97
        internal static class DeserializeArray<TSerializer>
 
98
                where TSerializer : ITypeSerializer
 
99
        {
 
100
                private static Dictionary<Type, ParseStringDelegate> ParseDelegateCache = new Dictionary<Type, ParseStringDelegate>();
 
101
 
 
102
                public static ParseStringDelegate GetParseFn(Type type)
 
103
                {
 
104
                        ParseStringDelegate parseFn;
 
105
            if (ParseDelegateCache.TryGetValue(type, out parseFn)) return parseFn;
 
106
 
 
107
            var genericType = typeof(DeserializeArray<,>).MakeGenericType(type, typeof(TSerializer));
 
108
            var mi = genericType.GetMethod("GetParseFn", BindingFlags.Public | BindingFlags.Static);
 
109
            var parseFactoryFn = (Func<ParseStringDelegate>)Delegate.CreateDelegate(
 
110
                typeof(Func<ParseStringDelegate>), mi);
 
111
            parseFn = parseFactoryFn();
 
112
            
 
113
            Dictionary<Type, ParseStringDelegate> snapshot, newCache;
 
114
            do
 
115
            {
 
116
                snapshot = ParseDelegateCache;
 
117
                newCache = new Dictionary<Type, ParseStringDelegate>(ParseDelegateCache);
 
118
                newCache[type] = parseFn;
 
119
 
 
120
            } while (!ReferenceEquals(
 
121
                Interlocked.CompareExchange(ref ParseDelegateCache, newCache, snapshot), snapshot));
 
122
 
 
123
                        return parseFn;
 
124
                }
 
125
        }
 
126
 
 
127
        internal static class DeserializeArray<T, TSerializer>
 
128
                where TSerializer : ITypeSerializer
 
129
        {
 
130
                private static readonly ITypeSerializer Serializer = JsWriter.GetTypeSerializer<TSerializer>();
 
131
 
 
132
                private static readonly ParseStringDelegate CacheFn;
 
133
 
 
134
                static DeserializeArray()
 
135
                {
 
136
                        CacheFn = GetParseFn();
 
137
                }
 
138
 
 
139
                public static ParseStringDelegate Parse
 
140
                {
 
141
                        get { return CacheFn; }
 
142
                }
 
143
 
 
144
                public static ParseStringDelegate GetParseFn()
 
145
                {
 
146
                        var type = typeof (T);
 
147
                        if (!type.IsArray)
 
148
                                throw new ArgumentException(string.Format("Type {0} is not an Array type", type.FullName));
 
149
 
 
150
                        if (type == typeof(string[]))
 
151
                                return ParseStringArray;
 
152
                        if (type == typeof(byte[]))
 
153
                                return ParseByteArray;
 
154
 
 
155
                        var elementType = type.GetElementType();
 
156
                        var elementParseFn = Serializer.GetParseFn(elementType);
 
157
                        if (elementParseFn != null)
 
158
                        {
 
159
                                var parseFn = DeserializeArrayWithElements<TSerializer>.GetParseFn(elementType);
 
160
                                return value => parseFn(value, elementParseFn);
 
161
                        }
 
162
                        return null;
 
163
                }
 
164
 
 
165
                public static string[] ParseStringArray(string value)
 
166
                {
 
167
                        if ((value = DeserializeListWithElements<TSerializer>.StripList(value)) == null) return null;
 
168
                        return value == string.Empty
 
169
                                        ? new string[0]
 
170
                                        : DeserializeListWithElements<TSerializer>.ParseStringList(value).ToArray();
 
171
                }
 
172
                
 
173
                public static byte[] ParseByteArray(string value)
 
174
                {
 
175
                        if ((value = DeserializeListWithElements<TSerializer>.StripList(value)) == null) return null;
 
176
                        if ((value = Serializer.ParseRawString(value)) == null) return null;
 
177
                        return value == string.Empty
 
178
                                ? new byte[0]
 
179
                                : Convert.FromBase64String(value);
 
180
                }
 
181
        }
 
182
}
 
 
b'\\ No newline at end of file'