Skip to content
This repository was archived by the owner on Dec 24, 2022. It is now read-only.

Commit 153b334

Browse files
committed
Refactor JSV TypeSerializer to match JsonSerializer + support JsConfig.ReuseStringBuffer
1 parent 2ee8405 commit 153b334

File tree

1 file changed

+98
-36
lines changed

1 file changed

+98
-36
lines changed

src/ServiceStack.Text/TypeSerializer.cs

Lines changed: 98 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -76,37 +76,90 @@ public static object DeserializeFromReader(TextReader reader, Type type)
7676
return DeserializeFromString(reader.ReadToEnd(), type);
7777
}
7878

79+
[ThreadStatic] //Reuse the thread static StringBuilder when serializing to strings
80+
private static StringBuilderWriter LastWriter;
81+
82+
internal class StringBuilderWriter : IDisposable
83+
{
84+
protected StringBuilder sb;
85+
protected StringWriter writer;
86+
87+
public StringWriter Writer
88+
{
89+
get { return writer; }
90+
}
91+
92+
public StringBuilderWriter()
93+
{
94+
this.sb = new StringBuilder();
95+
this.writer = new StringWriter(sb, CultureInfo.InvariantCulture);
96+
}
97+
98+
public static StringBuilderWriter Create()
99+
{
100+
var ret = LastWriter;
101+
if (JsConfig.ReuseStringBuffer && ret != null)
102+
{
103+
LastWriter = null;
104+
ret.sb.Clear();
105+
return ret;
106+
}
107+
108+
return new StringBuilderWriter();
109+
}
110+
111+
public override string ToString()
112+
{
113+
return sb.ToString();
114+
}
115+
116+
public void Dispose()
117+
{
118+
if (JsConfig.ReuseStringBuffer)
119+
{
120+
LastWriter = this;
121+
}
122+
else
123+
{
124+
Writer.Dispose();
125+
}
126+
}
127+
}
128+
79129
public static string SerializeToString<T>(T value)
80130
{
81-
if (value == null || value is Delegate) return null;
82-
if (typeof(T) == typeof(string)) return value as string;
83-
if (typeof(T) == typeof(object) || typeof(T).IsAbstract() || typeof(T).IsInterface())
131+
if (value == null || value is Delegate) return null;
132+
if (typeof(T) == typeof(object))
84133
{
85-
if (typeof(T).IsAbstract() || typeof(T).IsInterface()) JsState.IsWritingDynamic = true;
134+
return SerializeToString(value, value.GetType());
135+
}
136+
if (typeof(T).IsAbstract() || typeof(T).IsInterface())
137+
{
138+
JsState.IsWritingDynamic = true;
86139
var result = SerializeToString(value, value.GetType());
87-
if (typeof(T).IsAbstract() || typeof(T).IsInterface()) JsState.IsWritingDynamic = false;
140+
JsState.IsWritingDynamic = false;
88141
return result;
89142
}
90143

91-
var sb = new StringBuilder();
92-
using (var writer = new StringWriter(sb, CultureInfo.InvariantCulture))
93-
{
94-
JsvWriter<T>.WriteRootObject(writer, value);
95-
}
96-
return sb.ToString();
144+
using (var sb = StringBuilderWriter.Create())
145+
{
146+
JsvWriter<T>.WriteRootObject(sb.Writer, value);
147+
148+
return sb.ToString();
149+
}
97150
}
98151

99152
public static string SerializeToString(object value, Type type)
100153
{
101154
if (value == null) return null;
102155
if (type == typeof(string)) return value as string;
103156

104-
var sb = new StringBuilder();
105-
using (var writer = new StringWriter(sb, CultureInfo.InvariantCulture))
106-
{
107-
JsvWriter.GetWriteFn(type)(writer, value);
108-
}
109-
return sb.ToString();
157+
using (var sb = StringBuilderWriter.Create())
158+
{
159+
JsvWriter.GetWriteFn(type)(sb.Writer, value);
160+
161+
return sb.ToString();
162+
}
110163
}
111164

112165
public static void SerializeToWriter<T>(T value, TextWriter writer)
@@ -115,17 +168,21 @@ public static void SerializeToWriter<T>(T value, TextWriter writer)
115168
if (typeof(T) == typeof(string))
116169
{
117170
writer.Write(value);
118-
return;
119171
}
120-
if (typeof(T) == typeof(object))
121-
{
122-
if (typeof(T).IsAbstract() || typeof(T).IsInterface()) JsState.IsWritingDynamic = true;
172+
else if (typeof(T) == typeof(object))
173+
{
123174
SerializeToWriter(value, value.GetType(), writer);
124-
if (typeof(T).IsAbstract() || typeof(T).IsInterface()) JsState.IsWritingDynamic = false;
125-
return;
126-
}
127-
128-
JsvWriter<T>.WriteRootObject(writer, value);
175+
}
176+
else if (typeof(T).IsAbstract() || typeof(T).IsInterface())
177+
{
178+
JsState.IsWritingDynamic = false;
179+
SerializeToWriter(value, value.GetType(), writer);
180+
JsState.IsWritingDynamic = true;
181+
}
182+
else
183+
{
184+
JsvWriter<T>.WriteRootObject(writer, value);
185+
}
129186
}
130187

131188
public static void SerializeToWriter(object value, Type type, TextWriter writer)
@@ -143,17 +200,22 @@ public static void SerializeToWriter(object value, Type type, TextWriter writer)
143200
public static void SerializeToStream<T>(T value, Stream stream)
144201
{
145202
if (value == null) return;
146-
if (typeof(T) == typeof(object))
147-
{
148-
if (typeof(T).IsAbstract() || typeof(T).IsInterface()) JsState.IsWritingDynamic = true;
203+
if (typeof(T) == typeof(object))
204+
{
149205
SerializeToStream(value, value.GetType(), stream);
150-
if (typeof(T).IsAbstract() || typeof(T).IsInterface()) JsState.IsWritingDynamic = false;
151-
return;
152-
}
153-
154-
var writer = new StreamWriter(stream, UTF8EncodingWithoutBom);
155-
JsvWriter<T>.WriteRootObject(writer, value);
156-
writer.Flush();
206+
}
207+
else if (typeof(T).IsAbstract() || typeof(T).IsInterface())
208+
{
209+
JsState.IsWritingDynamic = false;
210+
SerializeToStream(value, value.GetType(), stream);
211+
JsState.IsWritingDynamic = true;
212+
}
213+
else
214+
{
215+
var writer = new StreamWriter(stream, UTF8EncodingWithoutBom);
216+
JsvWriter<T>.WriteRootObject(writer, value);
217+
writer.Flush();
218+
}
157219
}
158220

159221
public static void SerializeToStream(object value, Type type, Stream stream)

0 commit comments

Comments
 (0)