github.com/influx6/npkg@v0.8.8/njson/json.go (about) 1 package njson 2 3 import ( 4 "fmt" 5 "io" 6 "strconv" 7 "sync" 8 "sync/atomic" 9 "unsafe" 10 11 "github.com/influx6/npkg" 12 ) 13 14 var ( 15 comma = []byte(",") 16 colon = []byte(":") 17 space = []byte(" ") 18 openBlock = []byte("{") 19 closingBlock = []byte("}") 20 openBlockList = []byte("[") 21 closingBlockList = []byte("]") 22 doubleQuote = []byte("\"") 23 logEventPool = sync.Pool{ 24 New: func() interface{} { 25 return &JSON{content: make([]byte, 0, 512), r: 1} 26 }, 27 } 28 ) 29 30 var _ npkg.Error = (*JSON)(nil) 31 var _ npkg.ObjectEncoder = (*JSON)(nil) 32 var _ npkg.ListEncoder = (*JSON)(nil) 33 34 // JSONL creates a json list. 35 func JSONL(inherits ...func(event npkg.Encoder)) *JSON { 36 event := logEventPool.Get().(*JSON) 37 event.l = 1 38 event.reset() 39 40 for _, op := range inherits { 41 op(event) 42 if event.err != nil { 43 return event 44 } 45 } 46 return event 47 } 48 49 // JSONB creates a json hash. 50 func JSONB(inherits ...func(event npkg.Encoder)) *JSON { 51 event := logEventPool.Get().(*JSON) 52 event.l = 0 53 event.reset() 54 55 for _, op := range inherits { 56 op(event) 57 if event.err != nil { 58 return event 59 } 60 } 61 return event 62 } 63 64 // MJSON creates a json object with a message field with provided message. 65 func MJSON(message string, inherits ...func(event npkg.Encoder)) *JSON { 66 event := logEventPool.Get().(*JSON) 67 event.l = 0 68 69 event.reset() 70 event.addQuotedString("message", message) 71 event.endEntry() 72 73 for _, op := range inherits { 74 op(event) 75 if event.err != nil { 76 return event 77 } 78 } 79 return event 80 } 81 82 //************************************************************ 83 // JSON 84 //************************************************************ 85 86 var ( 87 _ npkg.Encoder = (*JSON)(nil) 88 ) 89 90 // JSON implements a efficient zero or near zero-allocation as much as possible, 91 // using a underline non-strict json format to transform log key-value pairs into 92 // a LogMessage. 93 // 94 // Each JSON iss retrieved from a logPool and will panic if after release/write it is used. 95 type JSON struct { 96 err error 97 l int8 98 r uint32 99 content []byte 100 onRelease func([]byte) []byte 101 } 102 103 func (l *JSON) AddFormatted(format string, m interface{}) { 104 l.AddString(fmt.Sprintf(format, m)) 105 } 106 107 func (l *JSON) Formatted(k string, format string, m interface{}) { 108 l.String(k, fmt.Sprintf(format, m)) 109 } 110 111 func (l *JSON) AddStringMap(m map[string]string) { 112 l.AddObjectWith(func(event npkg.ObjectEncoder) { 113 npkg.EncodableStringMap(m).EncodeObject(event) 114 }) 115 } 116 117 func (l *JSON) AddMap(m map[string]interface{}) { 118 l.AddObjectWith(func(event npkg.ObjectEncoder) { 119 npkg.EncodableMap(m).EncodeObject(event) 120 }) 121 } 122 123 func (l *JSON) StringMap(key string, m map[string]string) { 124 l.ObjectFor(key, func(event npkg.ObjectEncoder) { 125 npkg.EncodableStringMap(m).EncodeObject(event) 126 }) 127 } 128 129 func (l *JSON) Map(k string, m map[string]interface{}) { 130 l.ObjectFor(k, func(event npkg.ObjectEncoder) { 131 npkg.EncodableMap(m).EncodeObject(event) 132 }) 133 } 134 135 func (l *JSON) AddList(list npkg.EncodableList) { 136 l.AddListWith(list.EncodeList) 137 } 138 139 func (l *JSON) AddObject(object npkg.EncodableObject) { 140 l.AddObjectWith(object.EncodeObject) 141 } 142 143 func (l *JSON) List(k string, list npkg.EncodableList) { 144 l.ListFor(k, list.EncodeList) 145 } 146 147 func (l *JSON) Object(k string, object npkg.EncodableObject) { 148 l.ObjectFor(k, object.EncodeObject) 149 } 150 151 func (l *JSON) Err() error { 152 return l.err 153 } 154 155 // Message returns the generated JSON of giving *JSON. 156 func (l *JSON) Message() string { 157 if l.released() { 158 panic("Re-using released *JSON") 159 } 160 161 // remove last comma and space 162 total := len(comma) + len(space) 163 l.reduce(total) 164 l.end() 165 166 if l.onRelease != nil { 167 l.content = l.onRelease(l.content) 168 l.onRelease = nil 169 } 170 171 cn := make([]byte, len(l.content)) 172 copy(cn, l.content) 173 174 l.resetContent() 175 l.release() 176 return bytes2String(cn) 177 } 178 179 // Release releases the JSON object back into the logPool. 180 func (l *JSON) Release() { 181 l.resetContent() 182 l.release() 183 } 184 185 // WriteTo implements io.WriterTo interface. 186 func (l *JSON) WriteTo(w io.Writer) (int64, error) { 187 if l.released() { 188 panic("Re-using released *JSON") 189 } 190 191 // if there is an error then talk about it. 192 if l.err != nil { 193 return -1, l.err 194 } 195 196 // remove last comma and space 197 total := len(comma) + len(space) 198 l.reduce(total) 199 l.end() 200 201 if l.onRelease != nil { 202 l.content = l.onRelease(l.content) 203 l.onRelease = nil 204 } 205 206 var n, err = w.Write(l.content) 207 l.err = err 208 l.resetContent() 209 l.release() 210 return int64(n), err 211 } 212 213 // ObjectFor adds a field name with object value. 214 func (l *JSON) ObjectFor(name string, handler func(event npkg.ObjectEncoder)) { 215 l.panicIfList() 216 217 newEvent := logEventPool.Get().(*JSON) 218 newEvent.l = 0 219 newEvent.reset() 220 221 lastLen := len(newEvent.Buf()) 222 handler(newEvent) 223 afterLen := len(newEvent.Buf()) 224 225 if afterLen > lastLen { 226 total := len(comma) + len(space) 227 newEvent.reduce(total) 228 } 229 newEvent.end() 230 231 l.appendBytes(name, newEvent.Buf()) 232 l.endEntry() 233 234 newEvent.resetContent() 235 newEvent.release() 236 if newEvent.err != nil { 237 l.err = newEvent.err 238 } 239 } 240 241 // ListFor adds a field name with list value. 242 func (l *JSON) ListFor(name string, handler func(event npkg.ListEncoder)) { 243 l.panicIfList() 244 245 // stop if error 246 if l.err != nil { 247 return 248 } 249 250 newEvent := logEventPool.Get().(*JSON) 251 newEvent.l = 1 252 newEvent.reset() 253 254 lastLen := len(newEvent.Buf()) 255 handler(newEvent) 256 afterLen := len(newEvent.Buf()) 257 258 if afterLen > lastLen { 259 total := len(comma) + len(space) 260 newEvent.reduce(total) 261 } 262 newEvent.end() 263 264 l.appendBytes(name, newEvent.Buf()) 265 l.endEntry() 266 267 newEvent.resetContent() 268 newEvent.release() 269 if newEvent.err != nil { 270 l.err = newEvent.err 271 } 272 } 273 274 // AddList adds new list object with provided properties from provided function into 275 // a new json list format. It will panic if you use it for a object format call. 276 func (l *JSON) AddListWith(handler func(event npkg.ListEncoder)) { 277 l.panicIfObject() 278 // stop if error 279 if l.err != nil { 280 return 281 } 282 283 newEvent := logEventPool.Get().(*JSON) 284 newEvent.l = 1 285 newEvent.reset() 286 287 lastLen := len(newEvent.Buf()) 288 handler(newEvent) 289 afterLen := len(newEvent.Buf()) 290 291 if afterLen > lastLen { 292 total := len(comma) + len(space) 293 newEvent.reduce(total) 294 } 295 newEvent.end() 296 297 l.appendBytesList(newEvent.Buf()) 298 l.endEntry() 299 300 newEvent.resetContent() 301 newEvent.release() 302 303 if newEvent.err != nil { 304 l.err = newEvent.err 305 } 306 } 307 308 // AddObject adds new object with provided properties from provided function into 309 // a new json list format. It will panic if you use it for a object format call. 310 func (l *JSON) AddObjectWith(handler func(event npkg.ObjectEncoder)) { 311 l.panicIfObject() 312 // stop if error 313 if l.err != nil { 314 return 315 } 316 317 newEvent := logEventPool.Get().(*JSON) 318 newEvent.l = 0 319 newEvent.reset() 320 321 lastLen := len(newEvent.Buf()) 322 handler(newEvent) 323 afterLen := len(newEvent.Buf()) 324 325 if afterLen > lastLen { 326 total := len(comma) + len(space) 327 newEvent.reduce(total) 328 } 329 newEvent.end() 330 331 l.appendBytesList(newEvent.Buf()) 332 l.endEntry() 333 334 newEvent.resetContent() 335 newEvent.release() 336 337 if newEvent.err != nil { 338 l.err = newEvent.err 339 } 340 } 341 342 // AddError adds a string list item into encoding. 343 func (l *JSON) AddError(value error) { 344 l.AddString(value.Error()) 345 } 346 347 // AddString adds a string list item into encoding. 348 func (l *JSON) AddString(value string) { 349 // stop if error 350 if l.err != nil { 351 return 352 } 353 354 l.panicIfObject() 355 l.addQuotedBytesListItem(string2Bytes(value)) 356 l.endEntry() 357 } 358 359 // AddHex adds a hexed string list item into encoding. 360 func (l *JSON) AddHex(value string) { 361 // stop if error 362 if l.err != nil { 363 return 364 } 365 366 l.panicIfObject() 367 l.addQuotedBytesListItem(string2Bytes(value)) 368 l.endEntry() 369 } 370 371 // AddBool adds a bool value. 372 func (l *JSON) AddBool(value bool) { 373 // stop if error 374 if l.err != nil { 375 return 376 } 377 378 l.panicIfObject() 379 l.appendItem(func(content []byte) []byte { 380 return strconv.AppendBool(content, value) 381 }) 382 l.endEntry() 383 } 384 385 // AddInt adds a int value. 386 func (l *JSON) AddInt(value int) { 387 // stop if error 388 if l.err != nil { 389 return 390 } 391 392 l.panicIfObject() 393 l.appendItem(func(content []byte) []byte { 394 return convertIntToString(content, int64(value), 10) 395 }) 396 l.endEntry() 397 } 398 399 // AddInt8 adds a int8 value. 400 func (l *JSON) AddInt8(value int8) { 401 // stop if error 402 if l.err != nil { 403 return 404 } 405 406 l.panicIfObject() 407 l.appendItem(func(content []byte) []byte { 408 return convertIntToString(content, int64(value), 10) 409 }) 410 l.endEntry() 411 } 412 413 // AddInt16 adds a int16 value. 414 func (l *JSON) AddInt16(value int16) { 415 // stop if error 416 if l.err != nil { 417 return 418 } 419 420 l.panicIfObject() 421 l.appendItem(func(content []byte) []byte { 422 return convertIntToString(content, int64(value), 10) 423 }) 424 l.endEntry() 425 } 426 427 // AddInt32 adds a int32 value. 428 func (l *JSON) AddInt32(value int32) { 429 // stop if error 430 if l.err != nil { 431 return 432 } 433 434 l.panicIfObject() 435 l.appendItem(func(content []byte) []byte { 436 return convertIntToString(content, int64(value), 10) 437 }) 438 l.endEntry() 439 } 440 441 // AddInt64 adds a int64 value. 442 func (l *JSON) AddInt64(value int64) { 443 // stop if error 444 if l.err != nil { 445 return 446 } 447 448 l.panicIfObject() 449 l.appendItem(func(content []byte) []byte { 450 return convertIntToString(content, value, 10) 451 }) 452 l.endEntry() 453 } 454 455 // AddUInt adds a int value. 456 func (l *JSON) AddUInt(value uint) { 457 // stop if error 458 if l.err != nil { 459 return 460 } 461 462 l.panicIfObject() 463 l.appendItem(func(content []byte) []byte { 464 return convertUIntToString(content, uint64(value), 10) 465 }) 466 l.endEntry() 467 } 468 469 // AddUInt8 adds a int8 value. 470 func (l *JSON) AddUInt8(value uint8) { 471 // stop if error 472 if l.err != nil { 473 return 474 } 475 476 l.panicIfObject() 477 l.appendItem(func(content []byte) []byte { 478 return convertUIntToString(content, uint64(value), 10) 479 }) 480 l.endEntry() 481 } 482 483 // AddUInt16 adds a int16 value. 484 func (l *JSON) AddUInt16(value uint16) { 485 // stop if error 486 if l.err != nil { 487 return 488 } 489 490 l.panicIfObject() 491 l.appendItem(func(content []byte) []byte { 492 return convertUIntToString(content, uint64(value), 10) 493 }) 494 l.endEntry() 495 } 496 497 // AddUInt32 adds a int32 value. 498 func (l *JSON) AddUInt32(value uint32) { 499 // stop if error 500 if l.err != nil { 501 return 502 } 503 504 l.panicIfObject() 505 l.appendItem(func(content []byte) []byte { 506 return convertUIntToString(content, uint64(value), 10) 507 }) 508 l.endEntry() 509 } 510 511 // AddUInt64 adds a int64 value. 512 func (l *JSON) AddUInt64(value uint64) { 513 // stop if error 514 if l.err != nil { 515 return 516 } 517 518 l.panicIfObject() 519 l.appendItem(func(content []byte) []byte { 520 return convertUIntToString(content, value, 10) 521 }) 522 l.endEntry() 523 } 524 525 // AddBase64 adds a int64 value. 526 func (l *JSON) AddBase64(value int64, base int) { 527 // stop if error 528 if l.err != nil { 529 return 530 } 531 532 l.panicIfObject() 533 l.appendItem(func(content []byte) []byte { 534 return convertIntToString(content, value, base) 535 }) 536 l.endEntry() 537 } 538 539 // AddFloat64 adds a float64 value. 540 func (l *JSON) AddFloat64(value float64) { 541 // stop if error 542 if l.err != nil { 543 return 544 } 545 546 l.panicIfObject() 547 l.appendItem(func(content []byte) []byte { 548 return convertFloatToString(content, value, 32) 549 }) 550 l.endEntry() 551 } 552 553 // AddFloat32 adds a float32 value. 554 func (l *JSON) AddFloat32(value float32) { 555 // stop if error 556 if l.err != nil { 557 return 558 } 559 560 l.panicIfObject() 561 l.appendItem(func(content []byte) []byte { 562 return convertFloatToString(content, float64(value), 32) 563 }) 564 l.endEntry() 565 } 566 567 // AddBytes adds a bytes list value. The byte is expected to be 568 // valid JSON, no checks are made to ensure this, you can mess up your JSON 569 // if you do not use this correctly. 570 func (l *JSON) AddBytes(value []byte) { 571 // stop if error 572 if l.err != nil { 573 return 574 } 575 576 l.panicIfObject() 577 l.appendBytesList(value) 578 l.endEntry() 579 } 580 581 func (l *JSON) AppendBytes(value []byte) { 582 // stop if error 583 if l.err != nil { 584 return 585 } 586 587 l.panicIfObject() 588 l.appendBytesList(value) 589 l.endEntry() 590 } 591 592 // AddQBytes adds a bytes value. The byte is expected to be 593 // will be wrapped with quotation. 594 func (l *JSON) AddQBytes(value []byte) { 595 // stop if error 596 if l.err != nil { 597 return 598 } 599 600 l.panicIfObject() 601 l.addQuotedBytesListItem(value) 602 l.endEntry() 603 } 604 605 // Error adds a field name with error value. 606 func (l *JSON) Error(name string, value error) { 607 l.String(name, value.Error()) 608 } 609 610 // String adds a field name with string value. 611 func (l *JSON) String(name string, value string) { 612 // stop if error 613 if l.err != nil { 614 return 615 } 616 617 l.panicIfList() 618 l.addQuotedBytes(name, string2Bytes(value)) 619 l.endEntry() 620 } 621 622 // Hex adds a field name with hex converted string value. 623 func (l *JSON) Hex(name string, value string) { 624 // stop if error 625 if l.err != nil { 626 return 627 } 628 629 l.panicIfList() 630 l.addQuotedBytes(name, string2Bytes(value)) 631 l.endEntry() 632 633 } 634 635 // Bytes adds a field name with bytes value. The byte is expected to be 636 // valid JSON, no checks are made to ensure this, you can mess up your JSON 637 // if you do not use this correctly. 638 func (l *JSON) Bytes(name string, value []byte) { 639 // stop if error 640 if l.err != nil { 641 return 642 } 643 644 l.panicIfList() 645 l.appendListBytesKV(name, value) 646 l.endEntry() 647 } 648 649 // QBytes adds a field name with bytes value. The byte is expected to be 650 // will be wrapped with quotation. 651 func (l *JSON) QBytes(name string, value []byte) { 652 // stop if error 653 if l.err != nil { 654 return 655 } 656 657 l.panicIfList() 658 l.addQuotedBytes(name, value) 659 l.endEntry() 660 661 } 662 663 // Bool adds a field name with bool value. 664 func (l *JSON) Bool(name string, value bool) { 665 // stop if error 666 if l.err != nil { 667 return 668 } 669 670 l.panicIfList() 671 l.appendItem(func(content []byte) []byte { 672 content = append(content, doubleQuote...) 673 content = append(content, name...) 674 content = append(content, doubleQuote...) 675 content = append(content, colon...) 676 content = append(content, space...) 677 content = strconv.AppendBool(content, value) 678 return content 679 }) 680 l.endEntry() 681 } 682 683 // Base64 adds a field name with int value formatted to base n. 684 func (l *JSON) Base64(name string, value int64, base int) { 685 // stop if error 686 if l.err != nil { 687 return 688 } 689 690 l.panicIfList() 691 l.appendItem(func(content []byte) []byte { 692 content = append(content, doubleQuote...) 693 content = append(content, name...) 694 content = append(content, doubleQuote...) 695 content = append(content, colon...) 696 content = append(content, space...) 697 content = convertIntToString(content, value, base) 698 return content 699 }) 700 l.endEntry() 701 702 } 703 704 // Int adds a field name with int value. 705 func (l *JSON) Int(name string, value int) { 706 // stop if error 707 if l.err != nil { 708 return 709 } 710 711 l.panicIfList() 712 l.appendItem(func(content []byte) []byte { 713 content = append(content, doubleQuote...) 714 content = append(content, name...) 715 content = append(content, doubleQuote...) 716 content = append(content, colon...) 717 content = append(content, space...) 718 content = convertIntToString(content, int64(value), 10) 719 return content 720 }) 721 l.endEntry() 722 723 } 724 725 // UInt adds a field name with int value. 726 func (l *JSON) UInt(name string, value uint) { 727 // stop if error 728 if l.err != nil { 729 return 730 } 731 732 l.panicIfList() 733 l.appendItem(func(content []byte) []byte { 734 content = append(content, doubleQuote...) 735 content = append(content, name...) 736 content = append(content, doubleQuote...) 737 content = append(content, colon...) 738 content = append(content, space...) 739 content = convertUIntToString(content, uint64(value), 10) 740 return content 741 }) 742 l.endEntry() 743 744 } 745 746 // Int8 adds a field name with int8 value. 747 func (l *JSON) Int8(name string, value int8) { 748 // stop if error 749 if l.err != nil { 750 return 751 } 752 753 l.panicIfList() 754 l.appendItem(func(content []byte) []byte { 755 content = append(content, doubleQuote...) 756 content = append(content, name...) 757 content = append(content, doubleQuote...) 758 content = append(content, colon...) 759 content = append(content, space...) 760 content = convertIntToString(content, int64(value), 10) 761 return content 762 }) 763 l.endEntry() 764 765 } 766 767 // Int16 adds a field name with int16 value. 768 func (l *JSON) Int16(name string, value int16) { 769 // stop if error 770 if l.err != nil { 771 return 772 } 773 774 l.panicIfList() 775 l.appendItem(func(content []byte) []byte { 776 content = append(content, doubleQuote...) 777 content = append(content, name...) 778 content = append(content, doubleQuote...) 779 content = append(content, colon...) 780 content = append(content, space...) 781 content = convertIntToString(content, int64(value), 10) 782 return content 783 }) 784 l.endEntry() 785 786 } 787 788 // Int32 adds a field name with int32 value. 789 func (l *JSON) Int32(name string, value int32) { 790 // stop if error 791 if l.err != nil { 792 return 793 } 794 795 l.panicIfList() 796 l.appendItem(func(content []byte) []byte { 797 content = append(content, doubleQuote...) 798 content = append(content, name...) 799 content = append(content, doubleQuote...) 800 content = append(content, colon...) 801 content = append(content, space...) 802 content = convertIntToString(content, int64(value), 10) 803 return content 804 }) 805 l.endEntry() 806 807 } 808 809 // Int64 adds a field name with int64 value. 810 func (l *JSON) Int64(name string, value int64) { 811 // stop if error 812 if l.err != nil { 813 return 814 } 815 816 l.panicIfList() 817 l.appendItem(func(content []byte) []byte { 818 content = append(content, doubleQuote...) 819 content = append(content, name...) 820 content = append(content, doubleQuote...) 821 content = append(content, colon...) 822 content = append(content, space...) 823 content = convertIntToString(content, int64(value), 10) 824 return content 825 }) 826 l.endEntry() 827 } 828 829 // UInt8 adds a field name with uint8 value. 830 func (l *JSON) UInt8(name string, value uint8) { 831 // stop if error 832 if l.err != nil { 833 return 834 } 835 836 l.panicIfList() 837 l.appendItem(func(content []byte) []byte { 838 content = append(content, doubleQuote...) 839 content = append(content, name...) 840 content = append(content, doubleQuote...) 841 content = append(content, colon...) 842 content = append(content, space...) 843 content = convertUIntToString(content, uint64(value), 10) 844 return content 845 }) 846 l.endEntry() 847 848 } 849 850 // UInt16 adds a field name with uint16 value. 851 func (l *JSON) UInt16(name string, value uint16) { 852 // stop if error 853 if l.err != nil { 854 return 855 } 856 857 l.panicIfList() 858 l.appendItem(func(content []byte) []byte { 859 content = append(content, doubleQuote...) 860 content = append(content, name...) 861 content = append(content, doubleQuote...) 862 content = append(content, colon...) 863 content = append(content, space...) 864 content = convertUIntToString(content, uint64(value), 10) 865 return content 866 }) 867 l.endEntry() 868 869 } 870 871 func (l *JSON) Byte(name string, value byte) { 872 l.panicIfList() 873 874 l.appendItem(func(content []byte) []byte { 875 content = append(content, doubleQuote...) 876 content = append(content, name...) 877 content = append(content, doubleQuote...) 878 content = append(content, colon...) 879 content = append(content, space...) 880 content = append(content, value) 881 return content 882 }) 883 l.endEntry() 884 } 885 886 func (l *JSON) AddByte(value byte) { 887 l.panicIfList() 888 889 l.appendItem(func(content []byte) []byte { 890 content = append(content, value) 891 return content 892 }) 893 l.endEntry() 894 } 895 896 // UInt32 adds a field name with uint32 value. 897 func (l *JSON) UInt32(name string, value uint32) { 898 // stop if error 899 if l.err != nil { 900 return 901 } 902 903 l.panicIfList() 904 905 l.appendItem(func(content []byte) []byte { 906 content = append(content, doubleQuote...) 907 content = append(content, name...) 908 content = append(content, doubleQuote...) 909 content = append(content, colon...) 910 content = append(content, space...) 911 content = convertUIntToString(content, uint64(value), 10) 912 return content 913 }) 914 l.endEntry() 915 916 } 917 918 // UInt64 adds a field name with uint64 value. 919 func (l *JSON) UInt64(name string, value uint64) { 920 // stop if error 921 if l.err != nil { 922 return 923 } 924 925 l.panicIfList() 926 l.appendItem(func(content []byte) []byte { 927 content = append(content, doubleQuote...) 928 content = append(content, name...) 929 content = append(content, doubleQuote...) 930 content = append(content, colon...) 931 content = append(content, space...) 932 content = convertUIntToString(content, value, 10) 933 return content 934 }) 935 l.endEntry() 936 937 } 938 939 // Float64 adds a field name with float64 value. 940 func (l *JSON) Float64(name string, value float64) { 941 // stop if error 942 if l.err != nil { 943 return 944 } 945 946 l.panicIfList() 947 l.appendItem(func(content []byte) []byte { 948 content = append(content, doubleQuote...) 949 content = append(content, name...) 950 content = append(content, doubleQuote...) 951 content = append(content, colon...) 952 content = append(content, space...) 953 content = convertFloatToString(content, value, 64) 954 return content 955 }) 956 l.endEntry() 957 958 } 959 960 // Float32 adds a field name with float32 value. 961 func (l *JSON) Float32(name string, value float32) { 962 // stop if error 963 if l.err != nil { 964 return 965 } 966 967 l.panicIfList() 968 l.appendItem(func(content []byte) []byte { 969 content = append(content, doubleQuote...) 970 content = append(content, name...) 971 content = append(content, doubleQuote...) 972 content = append(content, colon...) 973 content = append(content, space...) 974 content = convertFloatToString(content, float64(value), 32) 975 return content 976 }) 977 l.endEntry() 978 979 } 980 981 // Buf returns the current content of the *JSON. 982 func (l *JSON) Buf() []byte { 983 return l.content 984 } 985 986 func (l *JSON) reset() { 987 atomic.StoreUint32(&l.r, 1) 988 l.begin() 989 } 990 991 func (l *JSON) reduce(d int) { 992 available := len(l.content) 993 rem := available - d 994 if rem < 0 { 995 rem = 0 996 } 997 l.content = l.content[:rem] 998 } 999 1000 func (l *JSON) resetContent() { 1001 l.content = l.content[:0] 1002 } 1003 1004 func (l *JSON) released() bool { 1005 return atomic.LoadUint32(&l.r) == 0 1006 } 1007 1008 func (l *JSON) release() { 1009 atomic.StoreUint32(&l.r, 0) 1010 logEventPool.Put(l) 1011 } 1012 1013 func (l *JSON) begin() { 1014 l.appendItem(func(content []byte) []byte { 1015 if l.l == 1 { 1016 content = append(content, openBlockList...) 1017 return content 1018 } 1019 content = append(content, openBlock...) 1020 return content 1021 }) 1022 } 1023 1024 func (l *JSON) panicIfObject() { 1025 if l.l == 0 { 1026 panic("unable to use for a json object format") 1027 } 1028 } 1029 1030 func (l *JSON) panicIfList() { 1031 if l.l == 1 { 1032 panic("unable to use for a json list format") 1033 } 1034 } 1035 1036 func (l *JSON) addQuotedString(k string, v string) { 1037 if l.released() { 1038 panic("Re-using released *JSON") 1039 } 1040 1041 l.appendItem(func(content []byte) []byte { 1042 content = append(content, doubleQuote...) 1043 content = append(content, k...) 1044 content = append(content, doubleQuote...) 1045 content = append(content, colon...) 1046 content = append(content, space...) 1047 content = append(content, doubleQuote...) 1048 content = append(content, v...) 1049 content = append(content, doubleQuote...) 1050 return content 1051 }) 1052 } 1053 1054 func (l *JSON) addQuotedStringListItem(k string, v string) { 1055 if l.released() { 1056 panic("Re-using released *JSON") 1057 } 1058 1059 l.appendItem(func(content []byte) []byte { 1060 content = append(content, doubleQuote...) 1061 content = append(content, v...) 1062 content = append(content, doubleQuote...) 1063 return content 1064 }) 1065 } 1066 1067 func (l *JSON) addString(k string, v string) { 1068 if l.released() { 1069 panic("Re-using released *JSON") 1070 } 1071 1072 l.appendItem(func(content []byte) []byte { 1073 content = append(content, doubleQuote...) 1074 content = append(content, k...) 1075 content = append(content, doubleQuote...) 1076 content = append(content, colon...) 1077 content = append(content, space...) 1078 content = append(content, v...) 1079 return content 1080 }) 1081 } 1082 1083 func (l *JSON) addStringListItem(v string) { 1084 if l.released() { 1085 panic("Re-using released *JSON") 1086 } 1087 1088 l.appendItem(func(content []byte) []byte { 1089 content = append(content, v...) 1090 return content 1091 }) 1092 } 1093 1094 func (l *JSON) addListBytes(v []byte) { 1095 if l.released() { 1096 panic("Re-using released *JSON") 1097 } 1098 1099 l.appendItem(func(content []byte) []byte { 1100 content = append(content, '[') 1101 content = append(content, v...) 1102 content = append(content, ']') 1103 return content 1104 }) 1105 } 1106 1107 func (l *JSON) appendListBytesKV(k string, v []byte) { 1108 if l.released() { 1109 panic("Re-using released *JSON") 1110 } 1111 1112 l.appendItem(func(content []byte) []byte { 1113 content = append(content, doubleQuote...) 1114 content = append(content, k...) 1115 content = append(content, doubleQuote...) 1116 content = append(content, colon...) 1117 content = append(content, space...) 1118 content = append(content, v...) 1119 return content 1120 }) 1121 } 1122 1123 func (l *JSON) addListBytesKV(k string, v []byte) { 1124 if l.released() { 1125 panic("Re-using released *JSON") 1126 } 1127 1128 l.appendItem(func(content []byte) []byte { 1129 content = append(content, doubleQuote...) 1130 content = append(content, k...) 1131 content = append(content, doubleQuote...) 1132 content = append(content, colon...) 1133 content = append(content, space...) 1134 content = append(content, '[') 1135 content = append(content, v...) 1136 content = append(content, ']') 1137 return content 1138 }) 1139 } 1140 1141 func (l *JSON) addQuotedBytes(k string, v []byte) { 1142 if l.released() { 1143 panic("Re-using released *JSON") 1144 } 1145 1146 l.appendItem(func(content []byte) []byte { 1147 content = append(content, doubleQuote...) 1148 content = append(content, k...) 1149 content = append(content, doubleQuote...) 1150 content = append(content, colon...) 1151 content = append(content, space...) 1152 content = append(content, doubleQuote...) 1153 content = append(content, v...) 1154 content = append(content, doubleQuote...) 1155 return content 1156 }) 1157 } 1158 1159 func (l *JSON) addQuotedBytesListItem(v []byte) { 1160 if l.released() { 1161 panic("Re-using released *JSON") 1162 } 1163 1164 l.appendItem(func(content []byte) []byte { 1165 content = append(content, doubleQuote...) 1166 content = append(content, v...) 1167 content = append(content, doubleQuote...) 1168 return content 1169 }) 1170 } 1171 1172 func (l *JSON) appendBytes(k string, v []byte) { 1173 if l.released() { 1174 panic("Re-using released *JSON") 1175 } 1176 1177 l.appendItem(func(content []byte) []byte { 1178 content = append(content, doubleQuote...) 1179 content = append(content, k...) 1180 content = append(content, doubleQuote...) 1181 content = append(content, colon...) 1182 content = append(content, space...) 1183 content = append(content, v...) 1184 return content 1185 }) 1186 } 1187 1188 func (l *JSON) appendBytesList(v []byte) { 1189 if l.released() { 1190 panic("Re-using released *JSON") 1191 } 1192 1193 l.appendItem(func(content []byte) []byte { 1194 content = append(content, v...) 1195 return content 1196 }) 1197 } 1198 1199 func (l *JSON) endEntry() { 1200 l.appendItem(func(content []byte) []byte { 1201 content = append(content, comma...) 1202 content = append(content, space...) 1203 return content 1204 }) 1205 } 1206 1207 func (l *JSON) end() { 1208 if l.l == 1 { 1209 l.appendItem(func(content []byte) []byte { 1210 return append(content, closingBlockList...) 1211 }) 1212 return 1213 } 1214 1215 l.appendItem(func(content []byte) []byte { 1216 return append(content, closingBlock...) 1217 }) 1218 } 1219 1220 func (l *JSON) appendItem(cb func([]byte) []byte) { 1221 l.content = cb(l.content) 1222 } 1223 1224 func convertIntToString(in []byte, v int64, b int) []byte { 1225 if v == 0 { 1226 return append(in, "0"...) 1227 } 1228 1229 return strconv.AppendInt(in, v, b) 1230 } 1231 1232 func convertFloatToString(in []byte, v float64, pre int) []byte { 1233 if v == 0 { 1234 return append(in, "0"...) 1235 } 1236 1237 return strconv.AppendFloat(in, v, 'E', -1, pre) 1238 } 1239 1240 func convertUIntToString(in []byte, v uint64, b int) []byte { 1241 if v == 0 { 1242 return append(in, "0"...) 1243 } 1244 1245 return strconv.AppendUint(in, v, b) 1246 } 1247 1248 //***************************************************** 1249 // unsafe methods 1250 //***************************************************** 1251 1252 func bytes2String(bc []byte) string { 1253 return *(*string)(unsafe.Pointer(&bc)) 1254 } 1255 1256 func string2Bytes(bc string) []byte { 1257 return *(*[]byte)(unsafe.Pointer(&bc)) 1258 }