@@ -22,6 +22,7 @@ type Encoder struct {
22
22
enabledIndent bool
23
23
enabledHTMLEscape bool
24
24
unorderedMap bool
25
+ baseIndent int
25
26
prefix []byte
26
27
indentStr []byte
27
28
}
@@ -112,6 +113,7 @@ func (e *Encoder) EncodeWithOption(v interface{}, opts ...EncodeOption) error {
112
113
}
113
114
}
114
115
header := (* interfaceHeader )(unsafe .Pointer (& v ))
116
+ e .ptr = header .ptr
115
117
buf , err := e .encode (header , v == nil )
116
118
if err != nil {
117
119
return err
@@ -155,6 +157,7 @@ func (e *Encoder) release() {
155
157
}
156
158
157
159
func (e * Encoder ) reset () {
160
+ e .baseIndent = 0
158
161
e .enabledHTMLEscape = true
159
162
e .enabledIndent = false
160
163
e .unorderedMap = false
@@ -192,23 +195,31 @@ func (e *Encoder) encode(header *interfaceHeader, isNil bool) ([]byte, error) {
192
195
typ := header .typ
193
196
194
197
typeptr := uintptr (unsafe .Pointer (typ ))
195
- opcodeMap := loadOpcodeMap ()
196
- if codeSet , exists := opcodeMap [typeptr ]; exists {
197
- ctx := e .ctx
198
- p := uintptr (header .ptr )
199
- ctx .init (p , codeSet .codeLength )
198
+ codeSet , err := e .compileToGetCodeSet (typeptr )
199
+ if err != nil {
200
+ return nil , err
201
+ }
200
202
201
- if e .enabledIndent {
202
- if e .enabledHTMLEscape {
203
- return e .runEscapedIndent (ctx , b , codeSet .code )
204
- } else {
205
- return e .runIndent (ctx , b , codeSet .code )
206
- }
207
- }
203
+ ctx := e .ctx
204
+ p := uintptr (header .ptr )
205
+ ctx .init (p , codeSet .codeLength )
206
+ if e .enabledIndent {
208
207
if e .enabledHTMLEscape {
209
- return e .runEscaped (ctx , b , codeSet .code )
208
+ return e .runEscapedIndent (ctx , b , codeSet )
209
+ } else {
210
+ return e .runIndent (ctx , b , codeSet )
210
211
}
211
- return e .run (ctx , b , codeSet .code )
212
+ }
213
+ if e .enabledHTMLEscape {
214
+ return e .runEscaped (ctx , b , codeSet )
215
+ }
216
+ return e .run (ctx , b , codeSet )
217
+ }
218
+
219
+ func (e * Encoder ) compileToGetCodeSet (typeptr uintptr ) (* opcodeSet , error ) {
220
+ opcodeMap := loadOpcodeMap ()
221
+ if codeSet , exists := opcodeMap [typeptr ]; exists {
222
+ return codeSet , nil
212
223
}
213
224
214
225
// noescape trick for header.typ ( reflect.*rtype )
@@ -230,21 +241,7 @@ func (e *Encoder) encode(header *interfaceHeader, isNil bool) ([]byte, error) {
230
241
}
231
242
232
243
storeOpcodeSet (typeptr , codeSet , opcodeMap )
233
- p := uintptr (header .ptr )
234
- ctx := e .ctx
235
- ctx .init (p , codeLength )
236
-
237
- if e .enabledIndent {
238
- if e .enabledHTMLEscape {
239
- return e .runEscapedIndent (ctx , b , codeSet .code )
240
- } else {
241
- return e .runIndent (ctx , b , codeSet .code )
242
- }
243
- }
244
- if e .enabledHTMLEscape {
245
- return e .runEscaped (ctx , b , codeSet .code )
246
- }
247
- return e .run (ctx , b , codeSet .code )
244
+ return codeSet , nil
248
245
}
249
246
250
247
func encodeFloat32 (b []byte , v float32 ) []byte {
@@ -303,7 +300,7 @@ func appendStructEnd(b []byte) []byte {
303
300
func (e * Encoder ) appendStructEndIndent (b []byte , indent int ) []byte {
304
301
b = append (b , '\n' )
305
302
b = append (b , e .prefix ... )
306
- b = append (b , bytes .Repeat (e .indentStr , indent )... )
303
+ b = append (b , bytes .Repeat (e .indentStr , e . baseIndent + indent )... )
307
304
return append (b , '}' , ',' , '\n' )
308
305
}
309
306
@@ -324,5 +321,5 @@ func encodeByteSlice(b []byte, src []byte) []byte {
324
321
325
322
func (e * Encoder ) encodeIndent (b []byte , indent int ) []byte {
326
323
b = append (b , e .prefix ... )
327
- return append (b , bytes .Repeat (e .indentStr , indent )... )
324
+ return append (b , bytes .Repeat (e .indentStr , e . baseIndent + indent )... )
328
325
}
0 commit comments