@@ -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