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

« back to all changes in this revision

Viewing changes to lib/ServiceStack.Text/src/ServiceStack.Text/CsvSerializer.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.Generic;
 
3
using System.Globalization;
 
4
using System.IO;
 
5
using System.Reflection;
 
6
using System.Text;
 
7
using System.Threading;
 
8
using ServiceStack.Text.Common;
 
9
using ServiceStack.Text.Jsv;
 
10
using ServiceStack.Text.Reflection;
 
11
 
 
12
namespace ServiceStack.Text
 
13
{
 
14
        public class CsvSerializer
 
15
        {
 
16
                private static readonly UTF8Encoding UTF8EncodingWithoutBom = new UTF8Encoding(false);
 
17
 
 
18
                private static Dictionary<Type, WriteObjectDelegate> WriteFnCache = new Dictionary<Type, WriteObjectDelegate>();
 
19
 
 
20
                internal static WriteObjectDelegate GetWriteFn(Type type)
 
21
                {
 
22
                        try
 
23
                        {
 
24
                                WriteObjectDelegate writeFn;
 
25
                if (WriteFnCache.TryGetValue(type, out writeFn)) return writeFn;
 
26
 
 
27
                var genericType = typeof(CsvSerializer<>).MakeGenericType(type);
 
28
                var mi = genericType.GetMethod("WriteFn", BindingFlags.Public | BindingFlags.Static);
 
29
                var writeFactoryFn = (Func<WriteObjectDelegate>)Delegate.CreateDelegate(
 
30
                    typeof(Func<WriteObjectDelegate>), mi);
 
31
                writeFn = writeFactoryFn();
 
32
 
 
33
                Dictionary<Type, WriteObjectDelegate> snapshot, newCache;
 
34
                do
 
35
                {
 
36
                    snapshot = WriteFnCache;
 
37
                    newCache = new Dictionary<Type, WriteObjectDelegate>(WriteFnCache);
 
38
                    newCache[type] = writeFn;
 
39
 
 
40
                } while (!ReferenceEquals(
 
41
                    Interlocked.CompareExchange(ref WriteFnCache, newCache, snapshot), snapshot));
 
42
                
 
43
                return writeFn;
 
44
                        }
 
45
                        catch (Exception ex)
 
46
                        {
 
47
                                Tracer.Instance.WriteError(ex);
 
48
                                throw;
 
49
                        }
 
50
                }
 
51
 
 
52
                public static string SerializeToCsv<T>(IEnumerable<T> records)
 
53
                {
 
54
                        var sb = new StringBuilder();
 
55
                        using (var writer = new StringWriter(sb, CultureInfo.InvariantCulture))
 
56
                        {
 
57
                                writer.WriteCsv(records);
 
58
                                return sb.ToString();
 
59
                        }
 
60
                }
 
61
 
 
62
                public static string SerializeToString<T>(T value)
 
63
                {
 
64
                        if (value == null) return null;
 
65
                        if (typeof(T) == typeof(string)) return value as string;
 
66
 
 
67
                        var sb = new StringBuilder();
 
68
                        using (var writer = new StringWriter(sb, CultureInfo.InvariantCulture))
 
69
                        {
 
70
                                CsvSerializer<T>.WriteObject(writer, value);
 
71
                        }
 
72
                        return sb.ToString();
 
73
                }
 
74
 
 
75
                public static void SerializeToWriter<T>(T value, TextWriter writer)
 
76
                {
 
77
                        if (value == null) return;
 
78
                        if (typeof(T) == typeof(string))
 
79
                        {
 
80
                                writer.Write(value);
 
81
                                return;
 
82
                        }
 
83
                        CsvSerializer<T>.WriteObject(writer, value);
 
84
                }
 
85
 
 
86
                public static void SerializeToStream<T>(T value, Stream stream)
 
87
                {
 
88
                        if (value == null) return;
 
89
                        using (var writer = new StreamWriter(stream, UTF8EncodingWithoutBom))
 
90
                        {
 
91
                                CsvSerializer<T>.WriteObject(writer, value);
 
92
                        }
 
93
                }
 
94
 
 
95
                public static void SerializeToStream(object obj, Stream stream)
 
96
                {
 
97
                        if (obj == null) return;
 
98
                        using (var writer = new StreamWriter(stream, UTF8EncodingWithoutBom))
 
99
                        {
 
100
                                var writeFn = GetWriteFn(obj.GetType());
 
101
                                writeFn(writer, obj);
 
102
                        }
 
103
                }
 
104
 
 
105
                public static T DeserializeFromStream<T>(Stream stream)
 
106
                {
 
107
            throw new NotImplementedException();
 
108
                }
 
109
 
 
110
                public static object DeserializeFromStream(Type type, Stream stream)
 
111
                {
 
112
            throw new NotImplementedException();
 
113
                }
 
114
 
 
115
                public static void WriteLateBoundObject(TextWriter writer, object value)
 
116
                {
 
117
                        if (value == null) return;
 
118
                        var writeFn = GetWriteFn(value.GetType());
 
119
                        writeFn(writer, value);
 
120
                }
 
121
        }
 
122
 
 
123
        internal static class CsvSerializer<T>
 
124
        {
 
125
                private static readonly WriteObjectDelegate CacheFn;
 
126
 
 
127
                public static WriteObjectDelegate WriteFn()
 
128
                {
 
129
                        return CacheFn;
 
130
                }
 
131
 
 
132
                private const string IgnoreResponseStatus = "ResponseStatus";
 
133
 
 
134
                private static Func<object, object> valueGetter = null;
 
135
                private static WriteObjectDelegate writeElementFn = null;
 
136
 
 
137
                private static WriteObjectDelegate GetWriteFn()
 
138
                {
 
139
                        PropertyInfo firstCandidate = null;
 
140
                        Type bestCandidateEnumerableType = null;
 
141
                        PropertyInfo bestCandidate = null;
 
142
 
 
143
                        if (typeof(T).IsValueType)
 
144
                        {
 
145
                                return JsvWriter<T>.WriteObject;
 
146
                        }
 
147
 
 
148
                        //If type is an enumerable property itself write that
 
149
                        bestCandidateEnumerableType = typeof(T).GetTypeWithGenericTypeDefinitionOf(typeof(IEnumerable<>));
 
150
                        if (bestCandidateEnumerableType != null)
 
151
                        {
 
152
                                var elementType = bestCandidateEnumerableType.GetGenericArguments()[0];
 
153
                                writeElementFn = CreateWriteFn(elementType);
 
154
 
 
155
                                return WriteEnumerableType;
 
156
                        }
 
157
 
 
158
                        //Look for best candidate property if DTO
 
159
                        if (typeof(T).IsDto())
 
160
                        {
 
161
                                var properties = TypeConfig<T>.Properties;
 
162
                                foreach (var propertyInfo in properties)
 
163
                                {
 
164
                                        if (propertyInfo.Name == IgnoreResponseStatus) continue;
 
165
 
 
166
                                        if (propertyInfo.PropertyType == typeof(string)
 
167
                                                || propertyInfo.PropertyType.IsValueType
 
168
                                                || propertyInfo.PropertyType == typeof(byte[])) continue;
 
169
 
 
170
                                        if (firstCandidate == null)
 
171
                                        {
 
172
                                                firstCandidate = propertyInfo;
 
173
                                        }
 
174
 
 
175
                                        var enumProperty = propertyInfo.PropertyType
 
176
                                                .GetTypeWithGenericTypeDefinitionOf(typeof(IEnumerable<>));
 
177
 
 
178
                                        if (enumProperty != null)
 
179
                                        {
 
180
                                                bestCandidateEnumerableType = enumProperty;
 
181
                                                bestCandidate = propertyInfo;
 
182
                                                break;
 
183
                                        }
 
184
                                }
 
185
                        }
 
186
 
 
187
                        //If is not DTO or no candidates exist, write self
 
188
                        var noCandidatesExist = bestCandidate == null && firstCandidate == null;
 
189
                        if (noCandidatesExist)
 
190
                        {
 
191
                                return WriteSelf;
 
192
                        }
 
193
 
 
194
                        //If is DTO and has an enumerable property serialize that
 
195
                        if (bestCandidateEnumerableType != null)
 
196
                        {
 
197
                                valueGetter = bestCandidate.GetValueGetter(typeof(T));
 
198
 
 
199
                                var elementType = bestCandidateEnumerableType.GetGenericArguments()[0];
 
200
                                writeElementFn = CreateWriteFn(elementType);
 
201
 
 
202
                                return WriteEnumerableProperty;
 
203
                        }
 
204
 
 
205
                        //If is DTO and has non-enumerable, reference type property serialize that
 
206
                        valueGetter = firstCandidate.GetValueGetter(typeof(T));
 
207
                        writeElementFn = CreateWriteRowFn(firstCandidate.PropertyType);
 
208
 
 
209
                        return WriteNonEnumerableType;
 
210
                }
 
211
 
 
212
                private static WriteObjectDelegate CreateWriteFn(Type elementType)
 
213
                {
 
214
                        return CreateCsvWriterFn(elementType, "WriteObject");
 
215
                }
 
216
 
 
217
                private static WriteObjectDelegate CreateWriteRowFn(Type elementType)
 
218
                {
 
219
                        return CreateCsvWriterFn(elementType, "WriteObjectRow");
 
220
                }
 
221
 
 
222
                private static WriteObjectDelegate CreateCsvWriterFn(Type elementType, string methodName)
 
223
                {
 
224
                        var genericType = typeof(CsvWriter<>).MakeGenericType(elementType);
 
225
                        var mi = genericType.GetMethod(methodName, 
 
226
                                BindingFlags.Static | BindingFlags.Public);
 
227
 
 
228
                        var writeFn = (WriteObjectDelegate)Delegate.CreateDelegate(typeof(WriteObjectDelegate), mi);
 
229
 
 
230
                        return writeFn;
 
231
                }
 
232
 
 
233
                public static void WriteEnumerableType(TextWriter writer, object obj)
 
234
                {
 
235
                        writeElementFn(writer, obj);
 
236
                }
 
237
 
 
238
                public static void WriteSelf(TextWriter writer, object obj)
 
239
                {
 
240
                        CsvWriter<T>.WriteRow(writer, (T)obj);
 
241
                }
 
242
 
 
243
                public static void WriteEnumerableProperty(TextWriter writer, object obj)
 
244
                {
 
245
                        if (obj == null) return; //AOT
 
246
 
 
247
                        var enumerableProperty = valueGetter(obj);
 
248
                        writeElementFn(writer, enumerableProperty);
 
249
                }
 
250
 
 
251
                public static void WriteNonEnumerableType(TextWriter writer, object obj)
 
252
                {
 
253
                        var nonEnumerableType = valueGetter(obj);
 
254
                        writeElementFn(writer, nonEnumerableType);
 
255
                }
 
256
 
 
257
                static CsvSerializer()
 
258
                {
 
259
                        if (typeof(T) == typeof(object))
 
260
                        {
 
261
                                CacheFn = CsvSerializer.WriteLateBoundObject;
 
262
                        }
 
263
                        else
 
264
                        {
 
265
                                CacheFn = GetWriteFn();
 
266
                        }
 
267
                }
 
268
 
 
269
                public static void WriteObject(TextWriter writer, object value)
 
270
                {
 
271
                        CacheFn(writer, value);
 
272
                }
 
273
        }
 
274
}
 
 
b'\\ No newline at end of file'