2
using System.Collections.Generic;
4
using ServiceStack.Text.Common;
5
using ServiceStack.Text.Reflection;
7
namespace ServiceStack.Text
9
internal class CsvWriter<T>
11
public const char DelimiterChar = ',';
13
public static List<string> Headers { get; set; }
15
internal static List<Func<T, object>> PropertyGetters;
17
private static readonly WriteObjectDelegate OptimizedWriter;
21
if (typeof(T) == typeof(string))
23
OptimizedWriter = (w, o) => WriteRow(w, (IEnumerable<string>)o);
30
internal static void Reset()
32
Headers = new List<string>();
34
PropertyGetters = new List<Func<T, object>>();
35
foreach (var propertyInfo in TypeConfig<T>.Properties)
37
if (!propertyInfo.CanRead || propertyInfo.GetGetMethod() == null) continue;
38
if (!TypeSerializer.CanCreateFromString(propertyInfo.PropertyType)) continue;
40
PropertyGetters.Add(propertyInfo.GetValueGetter<T>());
41
Headers.Add(propertyInfo.Name);
45
internal static void ConfigureCustomHeaders(Dictionary<string, string> customHeadersMap)
49
for (var i = Headers.Count - 1; i >= 0; i--)
51
var oldHeader = Headers[i];
52
string newHeaderValue;
53
if (!customHeadersMap.TryGetValue(oldHeader, out newHeaderValue))
56
PropertyGetters.RemoveAt(i);
60
Headers[i] = newHeaderValue.EncodeJsv();
65
private static List<string> GetSingleRow(IEnumerable<T> records, Type recordType)
67
var row = new List<string>();
68
foreach (var value in records)
70
var strValue = recordType == typeof(string)
72
: TypeSerializer.SerializeToString(value);
79
public static List<List<string>> GetRows(IEnumerable<T> records)
81
var rows = new List<List<string>>();
83
if (records == null) return rows;
85
if (typeof(T).IsValueType || typeof(T) == typeof(string))
87
rows.Add(GetSingleRow(records, typeof(T)));
91
foreach (var record in records)
93
var row = new List<string>();
94
foreach (var propertyGetter in PropertyGetters)
96
var value = propertyGetter(record) ?? "";
98
var strValue = value.GetType() == typeof(string)
100
: TypeSerializer.SerializeToString(value);
110
public static void WriteObject(TextWriter writer, object records)
112
Write(writer, (IEnumerable<T>)records);
115
public static void WriteObjectRow(TextWriter writer, object record)
117
WriteRow(writer, (T)record);
120
public static void Write(TextWriter writer, IEnumerable<T> records)
122
if (records == null) return; //AOT
124
if (OptimizedWriter != null)
126
OptimizedWriter(writer, records);
130
if (!CsvConfig<T>.OmitHeaders && Headers.Count > 0)
133
foreach (var header in Headers)
135
JsWriter.WriteItemSeperatorIfRanOnce(writer, ref ranOnce);
137
writer.Write(header);
142
if (records == null) return;
144
if (typeof(T).IsValueType || typeof(T) == typeof(string))
146
var singleRow = GetSingleRow(records, typeof(T));
147
WriteRow(writer, singleRow);
151
var row = new string[Headers.Count];
152
foreach (var record in records)
154
for (var i = 0; i < PropertyGetters.Count; i++)
156
var propertyGetter = PropertyGetters[i];
157
var value = propertyGetter(record) ?? "";
159
var strValue = value.GetType() == typeof(string)
161
: TypeSerializer.SerializeToString(value);
165
WriteRow(writer, row);
169
public static void WriteRow(TextWriter writer, T row)
171
if (row == null) return; //AOT
173
Write(writer, new[] { row });
176
public static void WriteRow(TextWriter writer, IEnumerable<string> row)
179
foreach (var field in row)
181
JsWriter.WriteItemSeperatorIfRanOnce(writer, ref ranOnce);
183
writer.Write(field.ToCsvField());
188
public static void Write(TextWriter writer, IEnumerable<List<string>> rows)
190
if (Headers.Count > 0)
193
foreach (var header in Headers)
195
JsWriter.WriteItemSeperatorIfRanOnce(writer, ref ranOnce);
197
writer.Write(header);
202
foreach (var row in rows)
204
WriteRow(writer, row);
b'\\ No newline at end of file'