-
Notifications
You must be signed in to change notification settings - Fork 18
/
Copy pathoption.go
634 lines (534 loc) · 22 KB
/
option.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
package jsonvalue
import "github.com/Andrew-M-C/go.jsonvalue/internal/buffer"
const (
initialArrayCapacity = 32
asciiSize = 128
)
// Deprecated: Opt is the option of jsonvalue in marshaling. This type is deprecated,
// please use OptXxxx() functions instead.
//
// Opt 表示序列化当前 jsonvalue 类型时的参数。这个类型后续可能不再迭代新字段了,请改用 OptXxxx() 函数进行配置。
type Opt struct {
// OmitNull tells how to handle null json value. The default value is false.
// If OmitNull is true, null value will be omitted when marshaling.
//
// OmitNull 表示是否忽略 JSON 中的 null 类型值。默认为 false.
OmitNull bool
// ignoreJsonOmitempty ignore json tag "omitempty", which means that every data
// would be parsed into *jsonvalue.V
ignoreJsonOmitempty bool
// MarshalLessFunc is used to handle sequences of marshaling. Since object is
// implemented by hash map, the sequence of keys is unexpectable. For situations
// those need settled JSON key-value sequence, please use MarshalLessFunc.
//
// Note: Elements in an array value would NOT trigger this function as they are
// already sorted.
//
// We provides a example DefaultStringSequence. It is quite useful when calculating
// idempotence of a JSON text, as key-value sequences should be fixed.
//
// MarshalLessFunc 用于处理序列化 JSON 对象类型时,键值对的顺序。由于 object 类型是采用 go
// 原生的 map 类型,采用哈希算法实现,
// 因此其键值对的顺序是不可控的。而为了提高效率,jsonvalue 的内部实现中并不会刻意保存键值对的顺序。
// 如果有必要在序列化时固定键值对顺序的话,
// 可以使用这个函数。
//
// 注意:array 类型中键值对的顺序不受这个函数的影响
//
// 此外,我们提供了一个例子: DefaultStringSequence。当需要计算 JSON 文本的幂等值时,
// 由于需要不变的键值对顺序,因此这个函数是非常有用的。
MarshalLessFunc MarshalLessFunc
// MarshalKeySequence is used to handle sequance of marshaling. This is much simpler
// than MarshalLessFunc, just pass a string slice identifying key sequence. For keys
// those are not in this slice, they would be appended in the end according to result
// of Go string comparing. Therefore this parameter is useful for ensure idempotence.
//
// MarshalKeySequence 也用于处理序列化时的键值对顺序。与 MarshalLessFunc 不同,这个只需要用字符串
// 切片的形式指定键的顺序即可,实现上更为简易和直观。对于那些不在指定切片中的键,那么将会统一放在结尾,
// 并且按照 go 字符串对比的结果排序。也可以保证幂等。
MarshalKeySequence []string
keySequence map[string]int // generated from MarshalKeySequence
// marshalBySetSequence enables object key sequence by when it is set.
//
// 按照 key 被设置的顺序处理序列化时的 marshal 顺序
marshalBySetSequence bool
// FloatNaNHandleType tells what to deal with float NaN.
//
// FloatNaNHandleType 表示当处理 float 的时候,如果遇到了 NaN 的话,要如何处理。
FloatNaNHandleType FloatNaNHandleType
// FloatNaNToString works with FloatNaNHandleType = FloatNaNConvertToString. It tells
// what string to replace to with NaN. If not specified, NaN will be set as string "NaN".
//
// FloatNaNToString 搭配 FloatNaNHandleType = FloatNaNConvertToString 使用,表示将 NaN
// 映射为哪个字符串。这个值如果不指定,则默认会被设置为字符串 "NaN"
FloatNaNToString string
// FloatNaNToFloat works with FloatNaNHandleType = FloatNaNConvertToFloat. It tells
// what float number will be mapped to as for NaN. NaN, +Inf or -Inf are not allowed
// for this option.
//
// FloatNaNToFloat 搭配 FloatNaNHandleType = FloatNaNConvertToFloat 使用,表示将 NaN
// 映射为哪个 float64 值。不允许指定为 NaN, +Inf 或 -Inf。如果不指定,则映射为 0。
FloatNaNToFloat float64
// FloatInfHandleType tells what to deal with float +Inf and -Inf.
//
// FloatInfHandleType 表示当处理 float 的时候,如果遇到了 +Inf 和 -Inf 的话,要如何处理。
FloatInfHandleType FloatInfHandleType
// FloatInfPositiveToString works with FloatInfHandleType = FloatInfConvertToFloat.
// It tells what float number will be mapped to as for +Inf. If not specified, +Inf
// will be set as string "+Inf".
//
// FloatInfPositiveToString 搭配 FloatInfHandleType = FloatInfConvertToFloat 使用,
// 表示将 NaN 映射为哪个字符串。
// 这个值如果不指定,则默认会被设置为字符串 "+Inf"
FloatInfPositiveToString string
// FloatInfNegativeToString works with FloatInfHandleType = FloatInfConvertToFloat.
// It tells what float number will be mapped to as for -Inf. If not specified, -Inf
// will be set as string "-" + strings.TrimLeft(FloatInfPositiveToString, "+").
//
// FloatInfNegativeToString 搭配 FloatInfHandleType = FloatInfConvertToFloat 使用,
// 表示将 NaN 映射为哪个字符串。这个值如果不指定,则默认会被设置为字符串 "-" + strings.TrimLeft(FloatInfPositiveToString, "+")
FloatInfNegativeToString string
// FloatInfToFloat works with FloatInfHandleType = FloatInfConvertToFloat. It tells
// what float numbers will be mapped to as for +Inf. And -Inf will be specified as
// the negative value of this option. +Inf or -Inf are not allowed for this option.
//
// FloatInfToFloat 搭配 FloatInfHandleType = FloatInfConvertToFloat 使用,表示将 +Inf
// 映射为哪个 float64 值。而 -Inf 则会被映射为这个值的负数。不允许指定为 NaN, +Inf 或 -Inf。
// 如果不指定,则映射为 0
FloatInfToFloat float64
// unicodeEscapingFunc defines how to escaping a unicode greater than 0x7F to buffer.
unicodeEscapingFunc func(r rune, buf buffer.Buffer)
// asciiCharEscapingFunc defines how to marshal bytes lower than 0x80.
asciiCharEscapingFunc [asciiSize]func(b byte, buf buffer.Buffer)
// escProperties
escProperties escapingProperties
// indent
indent struct {
enabled bool
prefix string
indent string
cnt int
}
}
type FloatNaNHandleType uint8
const (
// FloatNaNTreatAsError indicates that error will be returned when a float number
// is NaN when marshaling.
//
// FloatNaNTreatAsError 表示当 marshal 遇到 NaN 时,返回错误。这是默认选项。
FloatNaNTreatAsError FloatNaNHandleType = 0
// FloatNaNConvertToFloat indicates that NaN will be replaced as another float
// number when marshaling. This option works with option FloatNaNToFloat.
//
// FloatNaNConvertToFloat 表示当 marshal 遇到 NaN 时,将值置为另一个数。搭配 FloatNaNToFloat
// 选项使用。
FloatNaNConvertToFloat FloatNaNHandleType = 1
// FloatNaNNull indicates that NaN key-value pair will be set as null when marshaling.
//
// FloatNaNNull 表示当 marshal 遇到 NaN 时,则将值设置为 null
FloatNaNNull FloatNaNHandleType = 2
// FloatNaNConvertToString indicates that NaN will be replaced as a string when
// marshaling. This option works with option FloatNaNToString.
//
// FloatNaNConvertToString 表示当 marshal 遇到 NaN 时,将值设置为一个字符串。搭配
// FloatNaNToString 选项使用。
FloatNaNConvertToString FloatNaNHandleType = 3
)
type FloatInfHandleType uint8
const (
// FloatInfTreatAsError indicates that error will be returned when a float number
// is Inf or -Inf when marshaling.
//
// FloatInfTreatAsError 表示当 marshal 遇到 Inf 或 -Inf 时,返回错误。这是默认选项。
FloatInfTreatAsError FloatInfHandleType = 0
// FloatInfConvertToFloat indicates that Inf and -Inf will be replaced as another
// float number when marshaling. This option works with option FloatInfToFloat.
//
// FloatInfConvertToFloat 表示当 marshal 遇到 Inf 或 -Inf 时,将值置为另一个数。搭配
// FloatInfToFloat 选项使用。
FloatInfConvertToFloat FloatInfHandleType = 1
// FloatInfNull indicates that Inf or -Inf key-value pair will be set as null
// when marshaling.
//
// FloatInfNull 表示当 marshal 遇到 Inf 和 -Inf 时,则将值设置为 null
FloatInfNull FloatInfHandleType = 2
// FloatInfConvertToString indicates that Inf anf -Inf will be replaced as a
// string when marshaling. This option works with option FloatInfPositiveToString
// and FloatInfNegativeToString.
//
// FloatInfConvertToString 表示当 marshal 遇到 Inf 和 -Inf 时,将值设置为一个字符串。
// 搭配 FloatInfPositiveToString FloatInfNegativeToString 选项使用。
FloatInfConvertToString FloatInfHandleType = 3
)
// Option is used for additional options when marshaling. Can be either a Opt{}
// (not pointer to it) or other options generated by jsonvalue.OptXxxx() functions.
//
// Option 表示用于序列化的额外选项。可以是一个 Opt{} 结构体值(而不是它的指针),或者是使用
// jsonvalue.OptXxxx() 函数生成的选项。
type Option interface {
mergeTo(*Opt)
}
func (o Opt) mergeTo(tgt *Opt) {
*tgt = o
}
// SetDefaultMarshalOptions set default option for marshaling. It is quite
// useful to invoke this function once in certern init funciton. Or you can
// invoke it after main entry. It is goroutine-safe.
//
// Please keep in mind that it takes effect globally and affects ALL marshaling
// behaviors in the future until the process ends. Please ensure that these
// options are acceptable for ALL future marshaling.
//
// However, you can still add additional options in later marshaling.
//
// SetDefaultMarshalOptions 设置序列化时的默认参数。使用方可以在 init 函数阶段,或者是
// main 函数启动后立刻调用该函数,以调整序列化时的默认行为。这个函数是协程安全的。
//
// 请记住,这个函数影响的是后续所有的序列化行为,请确保这个配置对后续的其他操作是可行的。
//
// 当然,你也可以在后续的操作中,基于原先配置的默认选项基础上,添加其他附加选项。
func SetDefaultMarshalOptions(opts ...Option) {
opt := emptyOptions()
opt.combineOptionsFrom(opts)
internal.defaultMarshalOption = opt
}
// ResetDefaultMarshalOptions reset default marshaling options to system default.
//
// ResetDefaultMarshalOptions 重设序列化时的默认选项为系统最原始的版本。
func ResetDefaultMarshalOptions() {
internal.defaultMarshalOption = emptyOptions()
}
func emptyOptions() *Opt {
return &Opt{}
}
func getDefaultOptions() *Opt {
res := *internal.defaultMarshalOption
return &res
}
func combineOptions(opts []Option) *Opt {
opt := getDefaultOptions()
opt.combineOptionsFrom(opts)
return opt
}
func (opt *Opt) combineOptionsFrom(opts []Option) {
for _, o := range opts {
o.mergeTo(opt)
}
opt.parseEscapingFuncs()
}
// ==== OmitNull ====
// OptOmitNull configures OmitNull field in Opt{}, identifying whether null values
// should be omitted when marshaling.
//
// OptOmitNull 配置 Opt{} 中的 OmitNull 字段,表示是否忽略 null 值。
func OptOmitNull(b bool) Option {
return &optOmitNull{b: b}
}
type optOmitNull struct {
b bool
}
func (o *optOmitNull) mergeTo(opt *Opt) {
opt.OmitNull = o.b
}
// ==== IgnoreOmitempty ====
// OptIgnoreOmitempty is used in Import() and New() function. This option tells
// jsonvalue to ignore json tag "omitempty", which means that every field would
// be parsed into *jsonvalue.V.
//
// OptIgnoreOmitempty 用在 Import 和 New() 函数中。这个选项将会忽略 json 标签中的
// "omitempty" 参数。换句话说, 所有的字段都会被解析并包装到 *jsonvalue.V 值中。
func OptIgnoreOmitempty() Option {
return optIgnoreOmitempty{}
}
type optIgnoreOmitempty struct{}
func (optIgnoreOmitempty) mergeTo(opt *Opt) {
opt.ignoreJsonOmitempty = true
}
// ==== MarshalLessFunc ===
// OptKeySequenceWithLessFunc configures MarshalLessFunc field in Opt{}, which defines
// key sequence when marshaling.
//
// OptKeySequenceWithLessFunc 配置 Opt{} 中的 MarshalLessFunc 字段,配置序列化时的键顺序。
func OptKeySequenceWithLessFunc(f MarshalLessFunc) Option {
return &optMarshalLessFunc{f: f}
}
// OptDefaultStringSequence configures MarshalLessFunc field in Opt{} as jsonvalue.DefaultStringSequence,
// which is dictionary sequence.
//
// OptDefaultStringSequence 配置 Opt{} 中的 MarshalLessFunc 字段为 jsonvalue.DefaultStringSequence,也就是字典序。
func OptDefaultStringSequence() Option {
return &optMarshalLessFunc{f: DefaultStringSequence}
}
type optMarshalLessFunc struct {
f MarshalLessFunc
}
func (o *optMarshalLessFunc) mergeTo(opt *Opt) {
if o.f != nil {
opt.MarshalLessFunc = o.f
opt.MarshalKeySequence = nil
opt.keySequence = nil
opt.marshalBySetSequence = false
}
}
// ==== MarshalKeySequence ====
// OptKeySequence configures MarshalKeySequence field in Opt{}.
//
// OptKeySequence 配置 Opt{} 中的 MarshalKeySequence 字段。
func OptKeySequence(seq []string) Option {
return &optMarshalKeySequence{seq: seq}
}
type optMarshalKeySequence struct {
seq []string
}
func (o *optMarshalKeySequence) mergeTo(opt *Opt) {
opt.MarshalLessFunc = nil
opt.MarshalKeySequence = o.seq
opt.keySequence = nil
opt.marshalBySetSequence = false
}
// ==== marshalBySetSequence ====
// OptSetSequence tells that when marshaling an object, the key will be sorted by
// the time they are added into or refreshed in its parent object. The later a key
//
// is set or updated, the later it and its value will be marshaled.
//
// OptSetSequence 指定在序列化 object 时,按照一个 key 被设置时的顺序进行序列化。如果一个
// key 越晚添加到 object 类型,则在序列化的时候越靠后。
func OptSetSequence() Option {
return optSetSequence{}
}
type optSetSequence struct{}
func (optSetSequence) mergeTo(opt *Opt) {
opt.MarshalLessFunc = nil
opt.MarshalKeySequence = nil
opt.keySequence = nil
opt.marshalBySetSequence = true
}
// ==== FloatNaNConvertToFloat ====
// OptFloatNaNToFloat tells that when marshaling float NaN, replace it as another
// valid float number.
//
// OptFloatNaNToFloat 指定当遇到 NaN 时,将值替换成一个有效的 float 值。
func OptFloatNaNToFloat(f float64) Option {
return &optFloatNaNConvertToFloat{f: f}
}
type optFloatNaNConvertToFloat struct {
f float64
}
func (o *optFloatNaNConvertToFloat) mergeTo(opt *Opt) {
opt.FloatNaNHandleType = FloatNaNConvertToFloat
opt.FloatNaNToFloat = o.f
}
// ==== FloatNaNNull ====
// OptFloatNaNToNull will replace a float value to null if it is NaN.
//
// OptFloatNaNToNull 表示当遇到 NaN 时,将值替换成 null
func OptFloatNaNToNull() Option {
return optFloatNaNNull{}
}
type optFloatNaNNull struct{}
func (optFloatNaNNull) mergeTo(opt *Opt) {
opt.FloatNaNHandleType = FloatNaNNull
}
// ==== FloatNaNConvertToString ====
// OptFloatNaNToStringNaN will replace a float value to string "NaN" if it is NaN.
//
// OptFloatNaNToStringNaN 表示遇到 NaN 时,将其替换成字符串 "NaN"
func OptFloatNaNToStringNaN() Option {
return &optFloatNaNConvertToString{s: "NaN"}
}
// OptFloatNaNToString will replace a float value to specified string if it is NaN.
// If empty string is given, will replace as "NaN".
//
// OptFloatNaNToString 表示当遇到 NaN 时,将其替换成指定的字符串。如果指定空字符串,则替换成 "NaN"
func OptFloatNaNToString(s string) Option {
return &optFloatNaNConvertToString{s: s}
}
type optFloatNaNConvertToString struct {
s string
}
func (o *optFloatNaNConvertToString) mergeTo(opt *Opt) {
opt.FloatNaNHandleType = FloatNaNConvertToString
opt.FloatNaNToString = o.s
}
// ==== FloatInfConvertToFloat ====
// OptFloatInfToFloat will replace a +Inf float value to specified f, while -f if
// the value is -Inf.
//
// OptFloatInfToFloat 表示当遇到 +Inf 时,将其替换成另一个 float 值;如果是 -Inf,则会替换成其取负数。
func OptFloatInfToFloat(f float64) Option {
return &optFloatInfConvertToFloat{f: f}
}
type optFloatInfConvertToFloat struct {
f float64
}
func (o *optFloatInfConvertToFloat) mergeTo(opt *Opt) {
opt.FloatInfHandleType = FloatInfConvertToFloat
opt.FloatInfToFloat = o.f
}
// ==== FloatInfNull ====
// OptFloatInfToNull will replace a float value to null if it is +/-Inf.
//
// OptFloatInfToNull 表示当遇到 +/-Inf 时,将值替换成 null
func OptFloatInfToNull() Option {
return optFloatInfNull{}
}
type optFloatInfNull struct{}
func (optFloatInfNull) mergeTo(opt *Opt) {
opt.FloatInfHandleType = FloatInfNull
}
// ==== FloatInfConvertToString ====
// OptFloatInfToStringInf will replace a +Inf value to string "+Inf", while -Inf to "-Inf"
//
// OptFloatInfToStringInf 表示遇到 +/-Inf 时,相应地将其替换成字符串 "+Inf" 和 "-Inf"
func OptFloatInfToStringInf() Option {
return &optFloatInfConvertToString{}
}
// OptFloatInfToString tells what string to replace when marshaling +Inf and -Inf numbers.
//
// OptFloatInfToString 表示遇到 +/-Inf 时,将其替换成什么字符串。
func OptFloatInfToString(positiveInf, negativeInf string) Option {
return &optFloatInfConvertToString{
positive: positiveInf,
negative: negativeInf,
}
}
type optFloatInfConvertToString struct {
positive string
negative string
}
func (o *optFloatInfConvertToString) mergeTo(opt *Opt) {
opt.FloatInfHandleType = FloatInfConvertToString
opt.FloatInfPositiveToString = o.positive
opt.FloatInfNegativeToString = o.negative
}
// ==== escapeHTML ====
// OptEscapeHTML specifies whether problematic HTML characters should be escaped
// inside JSON quoted strings. The default behavior is to escape &, <, and > to
// \u0026, \u003c, and \u003e to avoid certain safety problems that can arise when
// embedding JSON in HTML. If not specified, HTML symbols above will be escaped by
// default.
//
// OptEscapeHTML 指定部分 HTML 符号是否会被转义。相关的 HTML 符号为 &, <, > 三个。如无指定,
// 则默认会被转义
func OptEscapeHTML(on bool) Option {
return optEscapeHTML(on)
}
type optEscapeHTML bool
func (o optEscapeHTML) mergeTo(opt *Opt) {
if o {
opt.escProperties = opt.escProperties.clear(escapeWithoutHTML)
} else {
opt.escProperties = opt.escProperties.set(escapeWithoutHTML)
}
}
// ==== do or do not not use ASCII escaping ====
// OptUTF8 specifies that all unicodes greater than 0x7F, will NOT be escaped by
// \uXXXX format but UTF-8.
//
// OptUTF8 指定使用 UTF-8 编码。也就是说针对大于 0x7F 的 unicode 字符,将不会使用默认的 \uXXXX
// 格式进行编码,而是直接使用 UTF-8。
func OptUTF8() Option {
return optUTF8(true)
}
type optUTF8 bool
func (o optUTF8) mergeTo(opt *Opt) {
opt.escProperties = opt.escProperties.set(escapeUTF8)
}
// ==== ignore slash ====
// OptEscapeSlash specifies whether we should escape slash (/) symbol. In JSON standard,
// this character should be escaped as '\/'. But non-escaping will not affect anything.
// If not specfied, slash will be escaped by default.
//
// OptEscapeSlash 指定是否需要转移斜杠 (/) 符号。在 JSON 标准中这个符号是需要被转移为 '\/' 的,
//
// 但是不转义这个符号也不会带来什么问题。如无明确指定,如无指定,默认情况下,斜杠是会被转义的。
func OptEscapeSlash(on bool) Option {
return optEscSlash(on)
}
type optEscSlash bool
func (o optEscSlash) mergeTo(opt *Opt) {
if o {
opt.escProperties = opt.escProperties.clear(escapeIgnoreSlash)
} else {
opt.escProperties = opt.escProperties.set(escapeIgnoreSlash)
}
}
// escapingProperties is a bit mask, showing the option for escaping
// characters.
//
// escapingProperties 是一个位掩码,表明转义特殊字符的方法
type escapingProperties uint8
const (
escapeUTF8 = 0
escapeWithoutHTML = 1
escapeIgnoreSlash = 2
)
func (esc escapingProperties) set(mask escapingProperties) escapingProperties {
return esc | (1 << mask)
}
func (esc escapingProperties) clear(mask escapingProperties) escapingProperties {
return esc & ^(1 << mask)
}
func (esc escapingProperties) has(mask escapingProperties) bool {
return esc == esc.set(mask)
}
// parseEscapingFuncs parse escaping functions by escapingProperties.
func (o *Opt) parseEscapingFuncs() {
// init bytes lower than 0x80
for i := range o.asciiCharEscapingFunc {
o.asciiCharEscapingFunc[i] = escapeNothing
}
iterate := func(from, to int, fu func(b byte, buf buffer.Buffer)) {
for i := from; i <= to; i++ {
o.asciiCharEscapingFunc[i] = fu
}
}
// ASCII control bytes should always escaped
iterate(0x00, 0x07, escAsciiControlChar)
// 0x08 is \b, encoding/json marshal as \u0008, but according to JSON standard, it should be "\b"
iterate(0x0E, 0x1F, escAsciiControlChar)
o.asciiCharEscapingFunc[0x7F] = escAsciiControlChar // encoding/json does not escape DEL
// ASCII characters always to be escaped
o.asciiCharEscapingFunc['"'] = escDoubleQuote
o.asciiCharEscapingFunc['/'] = escSlash
o.asciiCharEscapingFunc['\\'] = escBackslash
o.asciiCharEscapingFunc['\b'] = escBackspace
o.asciiCharEscapingFunc['\f'] = escVertTab
o.asciiCharEscapingFunc['\t'] = escTab
o.asciiCharEscapingFunc['\n'] = escNewLine
o.asciiCharEscapingFunc['\r'] = escReturn
o.asciiCharEscapingFunc['<'] = escLeftAngle
o.asciiCharEscapingFunc['>'] = escRightAngle
o.asciiCharEscapingFunc['&'] = escAnd
// o.asciiCharEscapingFunc['%'] = escPercent
// unicodes >= 0x80
if o.escProperties.has(escapeUTF8) {
o.unicodeEscapingFunc = escapeGreaterUnicodeToBuffByUTF8
} else {
o.unicodeEscapingFunc = escapeGreaterUnicodeToBuffByUTF16
}
// ignore slash?
if o.escProperties.has(escapeIgnoreSlash) {
o.asciiCharEscapingFunc['/'] = escapeNothing
}
// without HTML?
if o.escProperties.has(escapeWithoutHTML) {
o.asciiCharEscapingFunc['<'] = escapeNothing
o.asciiCharEscapingFunc['>'] = escapeNothing
o.asciiCharEscapingFunc['&'] = escapeNothing
}
}
// ==== indent ====
// OptIndent appliesiIndent to format the output.
//
// OptIndent 指定序列化时的缩进。
func OptIndent(prefix, indent string) Option {
return optionIndent{prefix, indent}
}
type optionIndent [2]string
func (o optionIndent) mergeTo(opt *Opt) {
opt.indent.enabled = true
opt.indent.prefix = o[0]
opt.indent.indent = o[1]
}