1package jsoncolor
   2
   3import (
   4	"bytes"
   5	"encoding"
   6	"encoding/base64"
   7	"math"
   8	"reflect"
   9	"sort"
  10	"strconv"
  11	"sync"
  12	"time"
  13	"unicode/utf8"
  14	"unsafe"
  15)
  16
  17const hex = "0123456789abcdef"
  18
  19func (e encoder) encodeNull(b []byte, p unsafe.Pointer) ([]byte, error) {
  20	return e.clrs.appendNull(b), nil
  21}
  22
  23func (e encoder) encodeBool(b []byte, p unsafe.Pointer) ([]byte, error) {
  24	return e.clrs.appendBool(b, *(*bool)(p)), nil
  25}
  26
  27func (e encoder) encodeInt(b []byte, p unsafe.Pointer) ([]byte, error) {
  28	return e.clrs.appendInt64(b, int64(*(*int)(p))), nil
  29}
  30
  31func (e encoder) encodeInt8(b []byte, p unsafe.Pointer) ([]byte, error) {
  32	return e.clrs.appendInt64(b, int64(*(*int8)(p))), nil
  33}
  34
  35func (e encoder) encodeInt16(b []byte, p unsafe.Pointer) ([]byte, error) {
  36	return e.clrs.appendInt64(b, int64(*(*int16)(p))), nil
  37}
  38
  39func (e encoder) encodeInt32(b []byte, p unsafe.Pointer) ([]byte, error) {
  40	return e.clrs.appendInt64(b, int64(*(*int32)(p))), nil
  41}
  42
  43func (e encoder) encodeInt64(b []byte, p unsafe.Pointer) ([]byte, error) {
  44	return e.clrs.appendInt64(b, *(*int64)(p)), nil
  45}
  46
  47func (e encoder) encodeUint(b []byte, p unsafe.Pointer) ([]byte, error) {
  48	return e.clrs.appendUint64(b, uint64(*(*uint)(p))), nil
  49}
  50
  51func (e encoder) encodeUintptr(b []byte, p unsafe.Pointer) ([]byte, error) {
  52	return e.clrs.appendUint64(b, uint64(*(*uintptr)(p))), nil
  53}
  54
  55func (e encoder) encodeUint8(b []byte, p unsafe.Pointer) ([]byte, error) {
  56	return e.clrs.appendUint64(b, uint64(*(*uint8)(p))), nil
  57}
  58
  59func (e encoder) encodeUint16(b []byte, p unsafe.Pointer) ([]byte, error) {
  60	return e.clrs.appendUint64(b, uint64(*(*uint16)(p))), nil
  61}
  62
  63func (e encoder) encodeUint32(b []byte, p unsafe.Pointer) ([]byte, error) {
  64	return e.clrs.appendUint64(b, uint64(*(*uint32)(p))), nil
  65}
  66
  67func (e encoder) encodeUint64(b []byte, p unsafe.Pointer) ([]byte, error) {
  68	return e.clrs.appendUint64(b, *(*uint64)(p)), nil
  69}
  70
  71func (e encoder) encodeFloat32(b []byte, p unsafe.Pointer) ([]byte, error) {
  72	if e.clrs == nil {
  73		return e.encodeFloat(b, float64(*(*float32)(p)), 32)
  74	}
  75
  76	b = append(b, e.clrs.Number...)
  77	var err error
  78	b, err = e.encodeFloat(b, float64(*(*float32)(p)), 32)
  79	b = append(b, ansiReset...)
  80	return b, err
  81}
  82
  83func (e encoder) encodeFloat64(b []byte, p unsafe.Pointer) ([]byte, error) {
  84	if e.clrs == nil {
  85		return e.encodeFloat(b, *(*float64)(p), 64)
  86	}
  87
  88	b = append(b, e.clrs.Number...)
  89	var err error
  90	b, err = e.encodeFloat(b, *(*float64)(p), 64)
  91	b = append(b, ansiReset...)
  92	return b, err
  93}
  94
  95func (e encoder) encodeFloat(b []byte, f float64, bits int) ([]byte, error) {
  96	switch {
  97	case math.IsNaN(f):
  98		return b, &UnsupportedValueError{Value: reflect.ValueOf(f), Str: "NaN"}
  99	case math.IsInf(f, 0):
 100		return b, &UnsupportedValueError{Value: reflect.ValueOf(f), Str: "inf"}
 101	}
 102
 103	// Convert as if by ES6 number to string conversion.
 104	// This matches most other JSON generators.
 105	// See golang.org/issue/6384 and golang.org/issue/14135.
 106	// Like fmt %g, but the exponent cutoffs are different
 107	// and exponents themselves are not padded to two digits.
 108	abs := math.Abs(f)
 109	fmt := byte('f')
 110	// Note: Must use float32 comparisons for underlying float32 value to get precise cutoffs right.
 111	if abs != 0 {
 112		if bits == 64 && (abs < 1e-6 || abs >= 1e21) || bits == 32 && (float32(abs) < 1e-6 || float32(abs) >= 1e21) {
 113			fmt = 'e'
 114		}
 115	}
 116
 117	b = strconv.AppendFloat(b, f, fmt, -1, int(bits))
 118
 119	if fmt == 'e' {
 120		// clean up e-09 to e-9
 121		n := len(b)
 122		if n >= 4 && b[n-4] == 'e' && b[n-3] == '-' && b[n-2] == '0' {
 123			b[n-2] = b[n-1]
 124			b = b[:n-1]
 125		}
 126	}
 127
 128	return b, nil
 129}
 130
 131func (e encoder) encodeNumber(b []byte, p unsafe.Pointer) ([]byte, error) {
 132	n := *(*Number)(p)
 133	if n == "" {
 134		n = "0"
 135	}
 136
 137	_, _, err := parseNumber(stringToBytes(string(n)))
 138	if err != nil {
 139		return b, err
 140	}
 141
 142	if e.clrs == nil {
 143		return append(b, n...), nil
 144	}
 145
 146	b = append(b, e.clrs.Number...)
 147	b = append(b, n...)
 148	b = append(b, ansiReset...)
 149	return b, nil
 150}
 151
 152func (e encoder) encodeKey(b []byte, p unsafe.Pointer) ([]byte, error) {
 153	if e.clrs == nil {
 154		return e.doEncodeString(b, p)
 155	}
 156
 157	b = append(b, e.clrs.Key...)
 158	var err error
 159	b, err = e.doEncodeString(b, p)
 160	b = append(b, ansiReset...)
 161	return b, err
 162}
 163
 164func (e encoder) encodeString(b []byte, p unsafe.Pointer) ([]byte, error) {
 165	if e.clrs == nil {
 166		return e.doEncodeString(b, p)
 167	}
 168
 169	b = append(b, e.clrs.String...)
 170	var err error
 171	b, err = e.doEncodeString(b, p)
 172	b = append(b, ansiReset...)
 173	return b, err
 174}
 175
 176func (e encoder) doEncodeString(b []byte, p unsafe.Pointer) ([]byte, error) {
 177	s := *(*string)(p)
 178	i := 0
 179	j := 0
 180	escapeHTML := (e.flags & EscapeHTML) != 0
 181
 182	b = append(b, '"')
 183
 184	for j < len(s) {
 185		c := s[j]
 186
 187		if c >= 0x20 && c <= 0x7f && c != '\\' && c != '"' && (!escapeHTML || (c != '<' && c != '>' && c != '&')) {
 188			// fast path: most of the time, printable ascii characters are used
 189			j++
 190			continue
 191		}
 192
 193		switch c {
 194		case '\\', '"':
 195			b = append(b, s[i:j]...)
 196			b = append(b, '\\', c)
 197			i = j + 1
 198			j = j + 1
 199			continue
 200
 201		case '\n':
 202			b = append(b, s[i:j]...)
 203			b = append(b, '\\', 'n')
 204			i = j + 1
 205			j = j + 1
 206			continue
 207
 208		case '\r':
 209			b = append(b, s[i:j]...)
 210			b = append(b, '\\', 'r')
 211			i = j + 1
 212			j = j + 1
 213			continue
 214
 215		case '\t':
 216			b = append(b, s[i:j]...)
 217			b = append(b, '\\', 't')
 218			i = j + 1
 219			j = j + 1
 220			continue
 221
 222		case '<', '>', '&':
 223			b = append(b, s[i:j]...)
 224			b = append(b, `\u00`...)
 225			b = append(b, hex[c>>4], hex[c&0xF])
 226			i = j + 1
 227			j = j + 1
 228			continue
 229		}
 230
 231		// This encodes bytes < 0x20 except for \t, \n and \r.
 232		if c < 0x20 {
 233			b = append(b, s[i:j]...)
 234			b = append(b, `\u00`...)
 235			b = append(b, hex[c>>4], hex[c&0xF])
 236			i = j + 1
 237			j = j + 1
 238			continue
 239		}
 240
 241		r, size := utf8.DecodeRuneInString(s[j:])
 242
 243		if r == utf8.RuneError && size == 1 {
 244			b = append(b, s[i:j]...)
 245			b = append(b, `\ufffd`...)
 246			i = j + size
 247			j = j + size
 248			continue
 249		}
 250
 251		switch r {
 252		case '\u2028', '\u2029':
 253			// U+2028 is LINE SEPARATOR.
 254			// U+2029 is PARAGRAPH SEPARATOR.
 255			// They are both technically valid characters in JSON strings,
 256			// but don't work in JSONP, which has to be evaluated as JavaScript,
 257			// and can lead to security holes there. It is valid JSON to
 258			// escape them, so we do so unconditionally.
 259			// See http://timelessrepo.com/json-isnt-a-javascript-subset for discussion.
 260			b = append(b, s[i:j]...)
 261			b = append(b, `\u202`...)
 262			b = append(b, hex[r&0xF])
 263			i = j + size
 264			j = j + size
 265			continue
 266		}
 267
 268		j += size
 269	}
 270
 271	b = append(b, s[i:]...)
 272	b = append(b, '"')
 273	return b, nil
 274}
 275
 276func (e encoder) encodeToString(b []byte, p unsafe.Pointer, encode encodeFunc) ([]byte, error) {
 277	i := len(b)
 278
 279	b, err := encode(e, b, p)
 280	if err != nil {
 281		return b, err
 282	}
 283
 284	j := len(b)
 285	s := b[i:]
 286
 287	if b, err = e.doEncodeString(b, unsafe.Pointer(&s)); err != nil {
 288		return b, err
 289	}
 290
 291	n := copy(b[i:], b[j:])
 292	return b[:i+n], nil
 293}
 294
 295func (e encoder) encodeBytes(b []byte, p unsafe.Pointer) ([]byte, error) {
 296	if e.clrs == nil {
 297		return e.doEncodeBytes(b, p)
 298	}
 299
 300	b = append(b, e.clrs.Bytes...)
 301	var err error
 302	b, err = e.doEncodeBytes(b, p)
 303	return append(b, ansiReset...), err
 304}
 305
 306func (e encoder) doEncodeBytes(b []byte, p unsafe.Pointer) ([]byte, error) {
 307	v := *(*[]byte)(p)
 308	if v == nil {
 309		return e.clrs.appendNull(b), nil
 310	}
 311
 312	n := base64.StdEncoding.EncodedLen(len(v)) + 2
 313
 314	if avail := cap(b) - len(b); avail < n {
 315		newB := make([]byte, cap(b)+(n-avail))
 316		copy(newB, b)
 317		b = newB[:len(b)]
 318	}
 319
 320	i := len(b)
 321	j := len(b) + n
 322
 323	b = b[:j]
 324	b[i] = '"'
 325	base64.StdEncoding.Encode(b[i+1:j-1], v)
 326	b[j-1] = '"'
 327	return b, nil
 328}
 329
 330func (e encoder) encodeDuration(b []byte, p unsafe.Pointer) ([]byte, error) {
 331	// NOTE: The segmentj encoder does special handling for time.Duration (converts to string).
 332	//  The stdlib encoder does not. It just outputs the int64 value.
 333	//  We choose to follow the stdlib pattern, for fuller compatibility.
 334
 335	b = e.clrs.appendInt64(b, int64(*(*time.Duration)(p)))
 336	return b, nil
 337
 338	// NOTE: if we were to follow the segmentj pattern, we'd execute the code below.
 339	//if e.clrs == nil {
 340	//	b = append(b, '"')
 341	//
 342	//	b = appendDuration(b, *(*time.Duration)(p))
 343	//	b = append(b, '"')
 344	//	return b, nil
 345	//}
 346	//
 347	//b = append(b, e.clrs.Time...)
 348	//b = append(b, '"')
 349	//b = appendDuration(b, *(*time.Duration)(p))
 350	//b = append(b, '"')
 351	//b = append(b, ansiReset...)
 352	//return b, nil
 353}
 354
 355func (e encoder) encodeTime(b []byte, p unsafe.Pointer) ([]byte, error) {
 356	if e.clrs == nil {
 357		t := *(*time.Time)(p)
 358		b = append(b, '"')
 359		b = t.AppendFormat(b, time.RFC3339Nano)
 360		b = append(b, '"')
 361		return b, nil
 362	}
 363
 364	t := *(*time.Time)(p)
 365	b = append(b, e.clrs.Time...)
 366	b = append(b, '"')
 367	b = t.AppendFormat(b, time.RFC3339Nano)
 368	b = append(b, '"')
 369	b = append(b, ansiReset...)
 370	return b, nil
 371}
 372
 373func (e encoder) encodeArray(b []byte, p unsafe.Pointer, n int, size uintptr, t reflect.Type, encode encodeFunc) ([]byte, error) {
 374	var start = len(b)
 375	var err error
 376
 377	b = e.clrs.appendPunc(b, '[')
 378
 379	if n > 0 {
 380		e.indentr.push()
 381		for i := 0; i < n; i++ {
 382			if i != 0 {
 383				b = e.clrs.appendPunc(b, ',')
 384			}
 385
 386			b = e.indentr.appendByte(b, '\n')
 387			b = e.indentr.appendIndent(b)
 388
 389			if b, err = encode(e, b, unsafe.Pointer(uintptr(p)+(uintptr(i)*size))); err != nil {
 390				return b[:start], err
 391			}
 392		}
 393		e.indentr.pop()
 394		b = e.indentr.appendByte(b, '\n')
 395		b = e.indentr.appendIndent(b)
 396	}
 397
 398	b = e.clrs.appendPunc(b, ']')
 399
 400	return b, nil
 401}
 402
 403func (e encoder) encodeSlice(b []byte, p unsafe.Pointer, size uintptr, t reflect.Type, encode encodeFunc) ([]byte, error) {
 404	s := (*slice)(p)
 405
 406	if s.data == nil && s.len == 0 && s.cap == 0 {
 407		return e.clrs.appendNull(b), nil
 408	}
 409
 410	return e.encodeArray(b, s.data, s.len, size, t, encode)
 411}
 412
 413func (e encoder) encodeMap(b []byte, p unsafe.Pointer, t reflect.Type, encodeKey, encodeValue encodeFunc, sortKeys sortFunc) ([]byte, error) {
 414	m := reflect.NewAt(t, p).Elem()
 415	if m.IsNil() {
 416		return e.clrs.appendNull(b), nil
 417	}
 418
 419	keys := m.MapKeys()
 420	if sortKeys != nil && (e.flags&SortMapKeys) != 0 {
 421		sortKeys(keys)
 422	}
 423
 424	var start = len(b)
 425	var err error
 426	b = e.clrs.appendPunc(b, '{')
 427
 428	if len(keys) != 0 {
 429		b = e.indentr.appendByte(b, '\n')
 430
 431		e.indentr.push()
 432		for i, k := range keys {
 433			v := m.MapIndex(k)
 434
 435			if i != 0 {
 436				b = e.clrs.appendPunc(b, ',')
 437				b = e.indentr.appendByte(b, '\n')
 438			}
 439
 440			b = e.indentr.appendIndent(b)
 441			if b, err = encodeKey(e, b, (*iface)(unsafe.Pointer(&k)).ptr); err != nil {
 442				return b[:start], err
 443			}
 444
 445			b = e.clrs.appendPunc(b, ':')
 446			b = e.indentr.appendByte(b, ' ')
 447
 448			if b, err = encodeValue(e, b, (*iface)(unsafe.Pointer(&v)).ptr); err != nil {
 449				return b[:start], err
 450			}
 451		}
 452		b = e.indentr.appendByte(b, '\n')
 453		e.indentr.pop()
 454		b = e.indentr.appendIndent(b)
 455	}
 456
 457	b = e.clrs.appendPunc(b, '}')
 458	return b, nil
 459}
 460
 461type element struct {
 462	key string
 463	val interface{}
 464	raw RawMessage
 465}
 466
 467type mapslice struct {
 468	elements []element
 469}
 470
 471func (m *mapslice) Len() int           { return len(m.elements) }
 472func (m *mapslice) Less(i, j int) bool { return m.elements[i].key < m.elements[j].key }
 473func (m *mapslice) Swap(i, j int)      { m.elements[i], m.elements[j] = m.elements[j], m.elements[i] }
 474
 475var mapslicePool = sync.Pool{
 476	New: func() interface{} { return new(mapslice) },
 477}
 478
 479func (e encoder) encodeMapStringInterface(b []byte, p unsafe.Pointer) ([]byte, error) {
 480	m := *(*map[string]interface{})(p)
 481	if m == nil {
 482		return e.clrs.appendNull(b), nil
 483	}
 484
 485	if (e.flags & SortMapKeys) == 0 {
 486		// Optimized code path when the program does not need the map keys to be
 487		// sorted.
 488		b = e.clrs.appendPunc(b, '{')
 489
 490		if len(m) != 0 {
 491			b = e.indentr.appendByte(b, '\n')
 492
 493			var err error
 494			var i = 0
 495
 496			e.indentr.push()
 497			for k, v := range m {
 498				if i != 0 {
 499					b = e.clrs.appendPunc(b, ',')
 500					b = e.indentr.appendByte(b, '\n')
 501				}
 502
 503				b = e.indentr.appendIndent(b)
 504
 505				b, err = e.encodeKey(b, unsafe.Pointer(&k))
 506				if err != nil {
 507					return b, err
 508				}
 509
 510				b = e.clrs.appendPunc(b, ':')
 511				b = e.indentr.appendByte(b, ' ')
 512
 513				b, err = Append(b, v, e.flags, e.clrs, e.indentr)
 514				if err != nil {
 515					return b, err
 516				}
 517
 518				i++
 519			}
 520			b = e.indentr.appendByte(b, '\n')
 521			e.indentr.pop()
 522			b = e.indentr.appendIndent(b)
 523		}
 524
 525		b = e.clrs.appendPunc(b, '}')
 526		return b, nil
 527	}
 528
 529	s := mapslicePool.Get().(*mapslice)
 530	if cap(s.elements) < len(m) {
 531		s.elements = make([]element, 0, align(10, uintptr(len(m))))
 532	}
 533	for key, val := range m {
 534		s.elements = append(s.elements, element{key: key, val: val})
 535	}
 536	sort.Sort(s)
 537
 538	var start = len(b)
 539	var err error
 540	b = e.clrs.appendPunc(b, '{')
 541
 542	if len(s.elements) > 0 {
 543		b = e.indentr.appendByte(b, '\n')
 544
 545		e.indentr.push()
 546		for i, elem := range s.elements {
 547			if i != 0 {
 548				b = e.clrs.appendPunc(b, ',')
 549				b = e.indentr.appendByte(b, '\n')
 550			}
 551
 552			b = e.indentr.appendIndent(b)
 553
 554			b, _ = e.encodeKey(b, unsafe.Pointer(&elem.key))
 555			b = e.clrs.appendPunc(b, ':')
 556			b = e.indentr.appendByte(b, ' ')
 557
 558			b, err = Append(b, elem.val, e.flags, e.clrs, e.indentr)
 559			if err != nil {
 560				break
 561			}
 562		}
 563		b = e.indentr.appendByte(b, '\n')
 564		e.indentr.pop()
 565		b = e.indentr.appendIndent(b)
 566	}
 567
 568	for i := range s.elements {
 569		s.elements[i] = element{}
 570	}
 571
 572	s.elements = s.elements[:0]
 573	mapslicePool.Put(s)
 574
 575	if err != nil {
 576		return b[:start], err
 577	}
 578
 579	b = e.clrs.appendPunc(b, '}')
 580	return b, nil
 581}
 582
 583func (e encoder) encodeMapStringRawMessage(b []byte, p unsafe.Pointer) ([]byte, error) {
 584	m := *(*map[string]RawMessage)(p)
 585	if m == nil {
 586		return e.clrs.appendNull(b), nil
 587	}
 588
 589	if (e.flags & SortMapKeys) == 0 {
 590		// Optimized code path when the program does not need the map keys to be
 591		// sorted.
 592		b = e.clrs.appendPunc(b, '{')
 593
 594		if len(m) != 0 {
 595			b = e.indentr.appendByte(b, '\n')
 596
 597			var err error
 598			var i = 0
 599
 600			e.indentr.push()
 601			for k, v := range m {
 602				if i != 0 {
 603					b = e.clrs.appendPunc(b, ',')
 604					b = e.indentr.appendByte(b, '\n')
 605				}
 606
 607				b = e.indentr.appendIndent(b)
 608
 609				b, _ = e.encodeKey(b, unsafe.Pointer(&k))
 610
 611				b = e.clrs.appendPunc(b, ':')
 612				b = e.indentr.appendByte(b, ' ')
 613
 614				b, err = e.encodeRawMessage(b, unsafe.Pointer(&v))
 615				if err != nil {
 616					break
 617				}
 618
 619				i++
 620			}
 621			b = e.indentr.appendByte(b, '\n')
 622			e.indentr.pop()
 623			b = e.indentr.appendIndent(b)
 624		}
 625
 626		b = e.clrs.appendPunc(b, '}')
 627		return b, nil
 628	}
 629
 630	s := mapslicePool.Get().(*mapslice)
 631	if cap(s.elements) < len(m) {
 632		s.elements = make([]element, 0, align(10, uintptr(len(m))))
 633	}
 634	for key, raw := range m {
 635		s.elements = append(s.elements, element{key: key, raw: raw})
 636	}
 637	sort.Sort(s)
 638
 639	var start = len(b)
 640	var err error
 641	b = e.clrs.appendPunc(b, '{')
 642
 643	if len(s.elements) > 0 {
 644		b = e.indentr.appendByte(b, '\n')
 645
 646		e.indentr.push()
 647
 648		for i, elem := range s.elements {
 649			if i != 0 {
 650				b = e.clrs.appendPunc(b, ',')
 651				b = e.indentr.appendByte(b, '\n')
 652			}
 653
 654			b = e.indentr.appendIndent(b)
 655
 656			b, _ = e.encodeKey(b, unsafe.Pointer(&elem.key))
 657			b = e.clrs.appendPunc(b, ':')
 658			b = e.indentr.appendByte(b, ' ')
 659
 660			b, err = e.encodeRawMessage(b, unsafe.Pointer(&elem.raw))
 661			if err != nil {
 662				break
 663			}
 664		}
 665		b = e.indentr.appendByte(b, '\n')
 666		e.indentr.pop()
 667		b = e.indentr.appendIndent(b)
 668	}
 669
 670	for i := range s.elements {
 671		s.elements[i] = element{}
 672	}
 673
 674	s.elements = s.elements[:0]
 675	mapslicePool.Put(s)
 676
 677	if err != nil {
 678		return b[:start], err
 679	}
 680
 681	b = e.clrs.appendPunc(b, '}')
 682	return b, nil
 683}
 684
 685func (e encoder) encodeStruct(b []byte, p unsafe.Pointer, st *structType) ([]byte, error) {
 686	var start = len(b)
 687	var err error
 688	var k string
 689	var n int
 690
 691	b = e.clrs.appendPunc(b, '{')
 692
 693	if len(st.fields) > 0 {
 694		b = e.indentr.appendByte(b, '\n')
 695	}
 696
 697	e.indentr.push()
 698
 699	for i := range st.fields {
 700		f := &st.fields[i]
 701		v := unsafe.Pointer(uintptr(p) + f.offset)
 702
 703		if f.omitempty && f.empty(v) {
 704			continue
 705		}
 706
 707		if n != 0 {
 708			b = e.clrs.appendPunc(b, ',')
 709			b = e.indentr.appendByte(b, '\n')
 710		}
 711
 712		if (e.flags & EscapeHTML) != 0 {
 713			k = f.html
 714		} else {
 715			k = f.json
 716		}
 717
 718		lengthBeforeKey := len(b)
 719		b = e.indentr.appendIndent(b)
 720
 721		if e.clrs == nil {
 722			b = append(b, k...)
 723		} else {
 724			b = append(b, e.clrs.Key...)
 725			b = append(b, k...)
 726			b = append(b, ansiReset...)
 727		}
 728
 729		b = e.clrs.appendPunc(b, ':')
 730
 731		b = e.indentr.appendByte(b, ' ')
 732
 733		if b, err = f.codec.encode(e, b, v); err != nil {
 734			if err == (rollback{}) {
 735				b = b[:lengthBeforeKey]
 736				continue
 737			}
 738			return b[:start], err
 739		}
 740
 741		n++
 742	}
 743
 744	if n > 0 {
 745		b = e.indentr.appendByte(b, '\n')
 746	}
 747
 748	e.indentr.pop()
 749	b = e.indentr.appendIndent(b)
 750
 751	b = e.clrs.appendPunc(b, '}')
 752	return b, nil
 753}
 754
 755type rollback struct{}
 756
 757func (rollback) Error() string { return "rollback" }
 758
 759func (e encoder) encodeEmbeddedStructPointer(b []byte, p unsafe.Pointer, t reflect.Type, unexported bool, offset uintptr, encode encodeFunc) ([]byte, error) {
 760	p = *(*unsafe.Pointer)(p)
 761	if p == nil {
 762		return b, rollback{}
 763	}
 764	return encode(e, b, unsafe.Pointer(uintptr(p)+offset))
 765}
 766
 767func (e encoder) encodePointer(b []byte, p unsafe.Pointer, t reflect.Type, encode encodeFunc) ([]byte, error) {
 768	if p = *(*unsafe.Pointer)(p); p != nil {
 769		return encode(e, b, p)
 770	}
 771	return e.encodeNull(b, nil)
 772}
 773
 774func (e encoder) encodeInterface(b []byte, p unsafe.Pointer) ([]byte, error) {
 775	return Append(b, *(*interface{})(p), e.flags, e.clrs, e.indentr)
 776}
 777
 778func (e encoder) encodeMaybeEmptyInterface(b []byte, p unsafe.Pointer, t reflect.Type) ([]byte, error) {
 779	return Append(b, reflect.NewAt(t, p).Elem().Interface(), e.flags, e.clrs, e.indentr)
 780}
 781
 782func (e encoder) encodeUnsupportedTypeError(b []byte, p unsafe.Pointer, t reflect.Type) ([]byte, error) {
 783	return b, &UnsupportedTypeError{Type: t}
 784}
 785
 786// encodeRawMessage encodes a RawMessage to bytes. Unfortunately, this
 787// implementation has a deficiency: it uses Unmarshal to build an
 788// object from the RawMessage, which in the case of a struct, results
 789// in a map being constructed, and thus the order of the keys is not
 790// guaranteed to be maintained. A superior implementation would decode and
 791// then re-encode (with color/indentation) the basic JSON tokens on the fly.
 792// Note also that if TrustRawMessage is set, and the RawMessage is
 793// invalid JSON (cannot be parsed by Unmarshal), then this function
 794// falls back to encodeRawMessageNoParseTrusted, which seems to exhibit the
 795// correct behavior. It's a bit of a mess, but seems to do the trick.
 796func (e encoder) encodeRawMessage(b []byte, p unsafe.Pointer) ([]byte, error) {
 797	v := *(*RawMessage)(p)
 798
 799	if v == nil {
 800		return e.clrs.appendNull(b), nil
 801	}
 802
 803	var s []byte
 804
 805	if (e.flags & TrustRawMessage) != 0 {
 806		s = v
 807	} else {
 808		var err error
 809		s, _, err = parseValue(v)
 810		if err != nil {
 811			return b, &UnsupportedValueError{Value: reflect.ValueOf(v), Str: err.Error()}
 812		}
 813	}
 814
 815	var x interface{}
 816	if err := Unmarshal(s, &x); err != nil {
 817		return e.encodeRawMessageNoParseTrusted(b, p)
 818	}
 819
 820	return Append(b, x, e.flags, e.clrs, e.indentr)
 821}
 822
 823// encodeRawMessageNoParseTrusted is a fallback method that is
 824// used by encodeRawMessage if it fails to parse a trusted RawMessage.
 825// The (invalid) JSON produced by this method is not colorized.
 826// This method may have wonky logic or even bugs in it; little effort
 827// has been expended on it because it's a rarely visited edge case.
 828func (e encoder) encodeRawMessageNoParseTrusted(b []byte, p unsafe.Pointer) ([]byte, error) {
 829	v := *(*RawMessage)(p)
 830
 831	if v == nil {
 832		return e.clrs.appendNull(b), nil
 833	}
 834
 835	var s []byte
 836
 837	if (e.flags & TrustRawMessage) != 0 {
 838		s = v
 839	} else {
 840		var err error
 841		s, _, err = parseValue(v)
 842		if err != nil {
 843			return b, &UnsupportedValueError{Value: reflect.ValueOf(v), Str: err.Error()}
 844		}
 845	}
 846
 847	if e.indentr == nil {
 848		if (e.flags & EscapeHTML) != 0 {
 849			return appendCompactEscapeHTML(b, s), nil
 850		}
 851
 852		return append(b, s...), nil
 853	}
 854
 855	// In order to get the tests inherited from the original segmentio
 856	// encoder to work, we need to support indentation.
 857
 858	// This below is sloppy, but seems to work.
 859	if (e.flags & EscapeHTML) != 0 {
 860		s = appendCompactEscapeHTML(nil, s)
 861	}
 862
 863	// The "prefix" arg to Indent is the current indentation.
 864	pre := e.indentr.appendIndent(nil)
 865
 866	buf := &bytes.Buffer{}
 867	// And now we just make use of the existing Indent function.
 868	err := Indent(buf, s, string(pre), e.indentr.indent)
 869	if err != nil {
 870		return b, err
 871	}
 872
 873	s = buf.Bytes()
 874
 875	return append(b, s...), nil
 876}
 877
 878
 879// encodeJSONMarshaler suffers from the same defect as encodeRawMessage; it
 880// can result in keys being reordered.
 881func (e encoder) encodeJSONMarshaler(b []byte, p unsafe.Pointer, t reflect.Type, pointer bool) ([]byte, error) {
 882	v := reflect.NewAt(t, p)
 883
 884	if !pointer {
 885		v = v.Elem()
 886	}
 887
 888	switch v.Kind() {
 889	case reflect.Ptr, reflect.Interface:
 890		if v.IsNil() {
 891			return e.clrs.appendNull(b), nil
 892		}
 893	}
 894
 895	j, err := v.Interface().(Marshaler).MarshalJSON()
 896	if err != nil {
 897		return b, err
 898	}
 899
 900	// We effectively delegate to the encodeRawMessage method.
 901	return Append(b, RawMessage(j), e.flags, e.clrs, e.indentr)
 902}
 903
 904func (e encoder) encodeTextMarshaler(b []byte, p unsafe.Pointer, t reflect.Type, pointer bool) ([]byte, error) {
 905	v := reflect.NewAt(t, p)
 906
 907	if !pointer {
 908		v = v.Elem()
 909	}
 910
 911	switch v.Kind() {
 912	case reflect.Ptr, reflect.Interface:
 913		if v.IsNil() {
 914			return e.clrs.appendNull(b), nil
 915		}
 916	}
 917
 918	s, err := v.Interface().(encoding.TextMarshaler).MarshalText()
 919	if err != nil {
 920		return b, err
 921	}
 922
 923	if e.clrs == nil {
 924		return e.doEncodeString(b, unsafe.Pointer(&s))
 925	}
 926
 927	b = append(b, e.clrs.TextMarshaler...)
 928	b, err = e.doEncodeString(b, unsafe.Pointer(&s))
 929	b = append(b, ansiReset...)
 930	return b, err
 931}
 932
 933func appendCompactEscapeHTML(dst []byte, src []byte) []byte {
 934	start := 0
 935	escape := false
 936	inString := false
 937
 938	for i, c := range src {
 939		if !inString {
 940			switch c {
 941			case '"': // enter string
 942				inString = true
 943			case ' ', '\n', '\r', '\t': // skip space
 944				if start < i {
 945					dst = append(dst, src[start:i]...)
 946				}
 947				start = i + 1
 948			}
 949			continue
 950		}
 951
 952		if escape {
 953			escape = false
 954			continue
 955		}
 956
 957		if c == '\\' {
 958			escape = true
 959			continue
 960		}
 961
 962		if c == '"' {
 963			inString = false
 964			continue
 965		}
 966
 967		if c == '<' || c == '>' || c == '&' {
 968			if start < i {
 969				dst = append(dst, src[start:i]...)
 970			}
 971			dst = append(dst, `\u00`...)
 972			dst = append(dst, hex[c>>4], hex[c&0xF])
 973			start = i + 1
 974			continue
 975		}
 976
 977		// Convert U+2028 and U+2029 (E2 80 A8 and E2 80 A9).
 978		if c == 0xE2 && i+2 < len(src) && src[i+1] == 0x80 && src[i+2]&^1 == 0xA8 {
 979			if start < i {
 980				dst = append(dst, src[start:i]...)
 981			}
 982			dst = append(dst, `\u202`...)
 983			dst = append(dst, hex[src[i+2]&0xF])
 984			start = i + 3
 985			continue
 986		}
 987	}
 988
 989	if start < len(src) {
 990		dst = append(dst, src[start:]...)
 991	}
 992
 993	return dst
 994}
 995
 996// indenter is used to indent JSON. The push and pop methods
 997// change indentation level. The appendIndent method appends the
 998// computed indentation. The appendByte method appends a byte. All
 999// methods are safe to use with a nil receiver.
1000type indenter struct {
1001	disabled bool
1002	prefix   string
1003	indent   string
1004	depth    int
1005}
1006
1007// newIndenter returns a new indenter instance. If prefix and
1008// indent are both empty, the indenter is effectively disabled,
1009// and the appendIndent and appendByte methods are no-op.
1010func newIndenter(prefix, indent string) *indenter {
1011	return &indenter{
1012		disabled: prefix == "" && indent == "",
1013		prefix:   prefix,
1014		indent:   indent,
1015	}
1016}
1017
1018// push increases the indentation level.
1019func (in *indenter) push() {
1020	if in != nil {
1021		in.depth++
1022	}
1023}
1024
1025// pop decreases the indentation level.
1026func (in *indenter) pop() {
1027	if in != nil {
1028		in.depth--
1029	}
1030}
1031
1032// appendByte appends a to b if the indenter is non-nil and enabled.
1033// Otherwise b is returned unmodified.
1034func (in *indenter) appendByte(b []byte, a byte) []byte {
1035	if in == nil || in.disabled {
1036		return b
1037	}
1038
1039	return append(b, a)
1040}
1041
1042// appendIndent writes indentation to b, returning the resulting slice.
1043// If the indenter is nil or disabled b is returned unchanged.
1044func (in *indenter) appendIndent(b []byte) []byte {
1045	if in == nil || in.disabled {
1046		return b
1047	}
1048
1049	b = append(b, in.prefix...)
1050	for i := 0; i < in.depth; i++ {
1051		b = append(b, in.indent...)
1052	}
1053	return b
1054}