summaryrefslogtreecommitdiffstats
path: root/vendor/github.com/rs/zerolog/internal/json
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/rs/zerolog/internal/json')
-rw-r--r--vendor/github.com/rs/zerolog/internal/json/base.go19
-rw-r--r--vendor/github.com/rs/zerolog/internal/json/bytes.go85
-rw-r--r--vendor/github.com/rs/zerolog/internal/json/string.go149
-rw-r--r--vendor/github.com/rs/zerolog/internal/json/time.go113
-rw-r--r--vendor/github.com/rs/zerolog/internal/json/types.go414
5 files changed, 780 insertions, 0 deletions
diff --git a/vendor/github.com/rs/zerolog/internal/json/base.go b/vendor/github.com/rs/zerolog/internal/json/base.go
new file mode 100644
index 00000000..09ec59f4
--- /dev/null
+++ b/vendor/github.com/rs/zerolog/internal/json/base.go
@@ -0,0 +1,19 @@
+package json
+
+// JSONMarshalFunc is used to marshal interface to JSON encoded byte slice.
+// Making it package level instead of embedded in Encoder brings
+// some extra efforts at importing, but avoids value copy when the functions
+// of Encoder being invoked.
+// DO REMEMBER to set this variable at importing, or
+// you might get a nil pointer dereference panic at runtime.
+var JSONMarshalFunc func(v interface{}) ([]byte, error)
+
+type Encoder struct{}
+
+// AppendKey appends a new key to the output JSON.
+func (e Encoder) AppendKey(dst []byte, key string) []byte {
+ if dst[len(dst)-1] != '{' {
+ dst = append(dst, ',')
+ }
+ return append(e.AppendString(dst, key), ':')
+}
diff --git a/vendor/github.com/rs/zerolog/internal/json/bytes.go b/vendor/github.com/rs/zerolog/internal/json/bytes.go
new file mode 100644
index 00000000..de64120d
--- /dev/null
+++ b/vendor/github.com/rs/zerolog/internal/json/bytes.go
@@ -0,0 +1,85 @@
+package json
+
+import "unicode/utf8"
+
+// AppendBytes is a mirror of appendString with []byte arg
+func (Encoder) AppendBytes(dst, s []byte) []byte {
+ dst = append(dst, '"')
+ for i := 0; i < len(s); i++ {
+ if !noEscapeTable[s[i]] {
+ dst = appendBytesComplex(dst, s, i)
+ return append(dst, '"')
+ }
+ }
+ dst = append(dst, s...)
+ return append(dst, '"')
+}
+
+// AppendHex encodes the input bytes to a hex string and appends
+// the encoded string to the input byte slice.
+//
+// The operation loops though each byte and encodes it as hex using
+// the hex lookup table.
+func (Encoder) AppendHex(dst, s []byte) []byte {
+ dst = append(dst, '"')
+ for _, v := range s {
+ dst = append(dst, hex[v>>4], hex[v&0x0f])
+ }
+ return append(dst, '"')
+}
+
+// appendBytesComplex is a mirror of the appendStringComplex
+// with []byte arg
+func appendBytesComplex(dst, s []byte, i int) []byte {
+ start := 0
+ for i < len(s) {
+ b := s[i]
+ if b >= utf8.RuneSelf {
+ r, size := utf8.DecodeRune(s[i:])
+ if r == utf8.RuneError && size == 1 {
+ if start < i {
+ dst = append(dst, s[start:i]...)
+ }
+ dst = append(dst, `\ufffd`...)
+ i += size
+ start = i
+ continue
+ }
+ i += size
+ continue
+ }
+ if noEscapeTable[b] {
+ i++
+ continue
+ }
+ // We encountered a character that needs to be encoded.
+ // Let's append the previous simple characters to the byte slice
+ // and switch our operation to read and encode the remainder
+ // characters byte-by-byte.
+ if start < i {
+ dst = append(dst, s[start:i]...)
+ }
+ switch b {
+ case '"', '\\':
+ dst = append(dst, '\\', b)
+ case '\b':
+ dst = append(dst, '\\', 'b')
+ case '\f':
+ dst = append(dst, '\\', 'f')
+ case '\n':
+ dst = append(dst, '\\', 'n')
+ case '\r':
+ dst = append(dst, '\\', 'r')
+ case '\t':
+ dst = append(dst, '\\', 't')
+ default:
+ dst = append(dst, '\\', 'u', '0', '0', hex[b>>4], hex[b&0xF])
+ }
+ i++
+ start = i
+ }
+ if start < len(s) {
+ dst = append(dst, s[start:]...)
+ }
+ return dst
+}
diff --git a/vendor/github.com/rs/zerolog/internal/json/string.go b/vendor/github.com/rs/zerolog/internal/json/string.go
new file mode 100644
index 00000000..fd7770f2
--- /dev/null
+++ b/vendor/github.com/rs/zerolog/internal/json/string.go
@@ -0,0 +1,149 @@
+package json
+
+import (
+ "fmt"
+ "unicode/utf8"
+)
+
+const hex = "0123456789abcdef"
+
+var noEscapeTable = [256]bool{}
+
+func init() {
+ for i := 0; i <= 0x7e; i++ {
+ noEscapeTable[i] = i >= 0x20 && i != '\\' && i != '"'
+ }
+}
+
+// AppendStrings encodes the input strings to json and
+// appends the encoded string list to the input byte slice.
+func (e Encoder) AppendStrings(dst []byte, vals []string) []byte {
+ if len(vals) == 0 {
+ return append(dst, '[', ']')
+ }
+ dst = append(dst, '[')
+ dst = e.AppendString(dst, vals[0])
+ if len(vals) > 1 {
+ for _, val := range vals[1:] {
+ dst = e.AppendString(append(dst, ','), val)
+ }
+ }
+ dst = append(dst, ']')
+ return dst
+}
+
+// AppendString encodes the input string to json and appends
+// the encoded string to the input byte slice.
+//
+// The operation loops though each byte in the string looking
+// for characters that need json or utf8 encoding. If the string
+// does not need encoding, then the string is appended in its
+// entirety to the byte slice.
+// If we encounter a byte that does need encoding, switch up
+// the operation and perform a byte-by-byte read-encode-append.
+func (Encoder) AppendString(dst []byte, s string) []byte {
+ // Start with a double quote.
+ dst = append(dst, '"')
+ // Loop through each character in the string.
+ for i := 0; i < len(s); i++ {
+ // Check if the character needs encoding. Control characters, slashes,
+ // and the double quote need json encoding. Bytes above the ascii
+ // boundary needs utf8 encoding.
+ if !noEscapeTable[s[i]] {
+ // We encountered a character that needs to be encoded. Switch
+ // to complex version of the algorithm.
+ dst = appendStringComplex(dst, s, i)
+ return append(dst, '"')
+ }
+ }
+ // The string has no need for encoding and therefore is directly
+ // appended to the byte slice.
+ dst = append(dst, s...)
+ // End with a double quote
+ return append(dst, '"')
+}
+
+// AppendStringers encodes the provided Stringer list to json and
+// appends the encoded Stringer list to the input byte slice.
+func (e Encoder) AppendStringers(dst []byte, vals []fmt.Stringer) []byte {
+ if len(vals) == 0 {
+ return append(dst, '[', ']')
+ }
+ dst = append(dst, '[')
+ dst = e.AppendStringer(dst, vals[0])
+ if len(vals) > 1 {
+ for _, val := range vals[1:] {
+ dst = e.AppendStringer(append(dst, ','), val)
+ }
+ }
+ return append(dst, ']')
+}
+
+// AppendStringer encodes the input Stringer to json and appends the
+// encoded Stringer value to the input byte slice.
+func (e Encoder) AppendStringer(dst []byte, val fmt.Stringer) []byte {
+ if val == nil {
+ return e.AppendInterface(dst, nil)
+ }
+ return e.AppendString(dst, val.String())
+}
+
+//// appendStringComplex is used by appendString to take over an in
+// progress JSON string encoding that encountered a character that needs
+// to be encoded.
+func appendStringComplex(dst []byte, s string, i int) []byte {
+ start := 0
+ for i < len(s) {
+ b := s[i]
+ if b >= utf8.RuneSelf {
+ r, size := utf8.DecodeRuneInString(s[i:])
+ if r == utf8.RuneError && size == 1 {
+ // In case of error, first append previous simple characters to
+ // the byte slice if any and append a replacement character code
+ // in place of the invalid sequence.
+ if start < i {
+ dst = append(dst, s[start:i]...)
+ }
+ dst = append(dst, `\ufffd`...)
+ i += size
+ start = i
+ continue
+ }
+ i += size
+ continue
+ }
+ if noEscapeTable[b] {
+ i++
+ continue
+ }
+ // We encountered a character that needs to be encoded.
+ // Let's append the previous simple characters to the byte slice
+ // and switch our operation to read and encode the remainder
+ // characters byte-by-byte.
+ if start < i {
+ dst = append(dst, s[start:i]...)
+ }
+ switch b {
+ case '"', '\\':
+ dst = append(dst, '\\', b)
+ case '\b':
+ dst = append(dst, '\\', 'b')
+ case '\f':
+ dst = append(dst, '\\', 'f')
+ case '\n':
+ dst = append(dst, '\\', 'n')
+ case '\r':
+ dst = append(dst, '\\', 'r')
+ case '\t':
+ dst = append(dst, '\\', 't')
+ default:
+ dst = append(dst, '\\', 'u', '0', '0', hex[b>>4], hex[b&0xF])
+ }
+ i++
+ start = i
+ }
+ if start < len(s) {
+ dst = append(dst, s[start:]...)
+ }
+ return dst
+}
diff --git a/vendor/github.com/rs/zerolog/internal/json/time.go b/vendor/github.com/rs/zerolog/internal/json/time.go
new file mode 100644
index 00000000..6a8dc912
--- /dev/null
+++ b/vendor/github.com/rs/zerolog/internal/json/time.go
@@ -0,0 +1,113 @@
+package json
+
+import (
+ "strconv"
+ "time"
+)
+
+const (
+ // Import from zerolog/global.go
+ timeFormatUnix = ""
+ timeFormatUnixMs = "UNIXMS"
+ timeFormatUnixMicro = "UNIXMICRO"
+ timeFormatUnixNano = "UNIXNANO"
+)
+
+// AppendTime formats the input time with the given format
+// and appends the encoded string to the input byte slice.
+func (e Encoder) AppendTime(dst []byte, t time.Time, format string) []byte {
+ switch format {
+ case timeFormatUnix:
+ return e.AppendInt64(dst, t.Unix())
+ case timeFormatUnixMs:
+ return e.AppendInt64(dst, t.UnixNano()/1000000)
+ case timeFormatUnixMicro:
+ return e.AppendInt64(dst, t.UnixNano()/1000)
+ case timeFormatUnixNano:
+ return e.AppendInt64(dst, t.UnixNano())
+ }
+ return append(t.AppendFormat(append(dst, '"'), format), '"')
+}
+
+// AppendTimes converts the input times with the given format
+// and appends the encoded string list to the input byte slice.
+func (Encoder) AppendTimes(dst []byte, vals []time.Time, format string) []byte {
+ switch format {
+ case timeFormatUnix:
+ return appendUnixTimes(dst, vals)
+ case timeFormatUnixMs:
+ return appendUnixNanoTimes(dst, vals, 1000000)
+ case timeFormatUnixMicro:
+ return appendUnixNanoTimes(dst, vals, 1000)
+ case timeFormatUnixNano:
+ return appendUnixNanoTimes(dst, vals, 1)
+ }
+ if len(vals) == 0 {
+ return append(dst, '[', ']')
+ }
+ dst = append(dst, '[')
+ dst = append(vals[0].AppendFormat(append(dst, '"'), format), '"')
+ if len(vals) > 1 {
+ for _, t := range vals[1:] {
+ dst = append(t.AppendFormat(append(dst, ',', '"'), format), '"')
+ }
+ }
+ dst = append(dst, ']')
+ return dst
+}
+
+func appendUnixTimes(dst []byte, vals []time.Time) []byte {
+ if len(vals) == 0 {
+ return append(dst, '[', ']')
+ }
+ dst = append(dst, '[')
+ dst = strconv.AppendInt(dst, vals[0].Unix(), 10)
+ if len(vals) > 1 {
+ for _, t := range vals[1:] {
+ dst = strconv.AppendInt(append(dst, ','), t.Unix(), 10)
+ }
+ }
+ dst = append(dst, ']')
+ return dst
+}
+
+func appendUnixNanoTimes(dst []byte, vals []time.Time, div int64) []byte {
+ if len(vals) == 0 {
+ return append(dst, '[', ']')
+ }
+ dst = append(dst, '[')
+ dst = strconv.AppendInt(dst, vals[0].UnixNano()/div, 10)
+ if len(vals) > 1 {
+ for _, t := range vals[1:] {
+ dst = strconv.AppendInt(append(dst, ','), t.UnixNano()/div, 10)
+ }
+ }
+ dst = append(dst, ']')
+ return dst
+}
+
+// AppendDuration formats the input duration with the given unit & format
+// and appends the encoded string to the input byte slice.
+func (e Encoder) AppendDuration(dst []byte, d time.Duration, unit time.Duration, useInt bool) []byte {
+ if useInt {
+ return strconv.AppendInt(dst, int64(d/unit), 10)
+ }
+ return e.AppendFloat64(dst, float64(d)/float64(unit))
+}
+
+// AppendDurations formats the input durations with the given unit & format
+// and appends the encoded string list to the input byte slice.
+func (e Encoder) AppendDurations(dst []byte, vals []time.Duration, unit time.Duration, useInt bool) []byte {
+ if len(vals) == 0 {
+ return append(dst, '[', ']')
+ }
+ dst = append(dst, '[')
+ dst = e.AppendDuration(dst, vals[0], unit, useInt)
+ if len(vals) > 1 {
+ for _, d := range vals[1:] {
+ dst = e.AppendDuration(append(dst, ','), d, unit, useInt)
+ }
+ }
+ dst = append(dst, ']')
+ return dst
+}
diff --git a/vendor/github.com/rs/zerolog/internal/json/types.go b/vendor/github.com/rs/zerolog/internal/json/types.go
new file mode 100644
index 00000000..ef3a2a7a
--- /dev/null
+++ b/vendor/github.com/rs/zerolog/internal/json/types.go
@@ -0,0 +1,414 @@
+package json
+
+import (
+ "fmt"
+ "math"
+ "net"
+ "reflect"
+ "strconv"
+)
+
+// AppendNil inserts a 'Nil' object into the dst byte array.
+func (Encoder) AppendNil(dst []byte) []byte {
+ return append(dst, "null"...)
+}
+
+// AppendBeginMarker inserts a map start into the dst byte array.
+func (Encoder) AppendBeginMarker(dst []byte) []byte {
+ return append(dst, '{')
+}
+
+// AppendEndMarker inserts a map end into the dst byte array.
+func (Encoder) AppendEndMarker(dst []byte) []byte {
+ return append(dst, '}')
+}
+
+// AppendLineBreak appends a line break.
+func (Encoder) AppendLineBreak(dst []byte) []byte {
+ return append(dst, '\n')
+}
+
+// AppendArrayStart adds markers to indicate the start of an array.
+func (Encoder) AppendArrayStart(dst []byte) []byte {
+ return append(dst, '[')
+}
+
+// AppendArrayEnd adds markers to indicate the end of an array.
+func (Encoder) AppendArrayEnd(dst []byte) []byte {
+ return append(dst, ']')
+}
+
+// AppendArrayDelim adds markers to indicate end of a particular array element.
+func (Encoder) AppendArrayDelim(dst []byte) []byte {
+ if len(dst) > 0 {
+ return append(dst, ',')
+ }
+ return dst
+}
+
+// AppendBool converts the input bool to a string and
+// appends the encoded string to the input byte slice.
+func (Encoder) AppendBool(dst []byte, val bool) []byte {
+ return strconv.AppendBool(dst, val)
+}
+
+// AppendBools encodes the input bools to json and
+// appends the encoded string list to the input byte slice.
+func (Encoder) AppendBools(dst []byte, vals []bool) []byte {
+ if len(vals) == 0 {
+ return append(dst, '[', ']')
+ }
+ dst = append(dst, '[')
+ dst = strconv.AppendBool(dst, vals[0])
+ if len(vals) > 1 {
+ for _, val := range vals[1:] {
+ dst = strconv.AppendBool(append(dst, ','), val)
+ }
+ }
+ dst = append(dst, ']')
+ return dst
+}
+
+// AppendInt converts the input int to a string and
+// appends the encoded string to the input byte slice.
+func (Encoder) AppendInt(dst []byte, val int) []byte {
+ return strconv.AppendInt(dst, int64(val), 10)
+}
+
+// AppendInts encodes the input ints to json and
+// appends the encoded string list to the input byte slice.
+func (Encoder) AppendInts(dst []byte, vals []int) []byte {
+ if len(vals) == 0 {
+ return append(dst, '[', ']')
+ }
+ dst = append(dst, '[')
+ dst = strconv.AppendInt(dst, int64(vals[0]), 10)
+ if len(vals) > 1 {
+ for _, val := range vals[1:] {
+ dst = strconv.AppendInt(append(dst, ','), int64(val), 10)
+ }
+ }
+ dst = append(dst, ']')
+ return dst
+}
+
+// AppendInt8 converts the input []int8 to a string and
+// appends the encoded string to the input byte slice.
+func (Encoder) AppendInt8(dst []byte, val int8) []byte {
+ return strconv.AppendInt(dst, int64(val), 10)
+}
+
+// AppendInts8 encodes the input int8s to json and
+// appends the encoded string list to the input byte slice.
+func (Encoder) AppendInts8(dst []byte, vals []int8) []byte {
+ if len(vals) == 0 {
+ return append(dst, '[', ']')
+ }
+ dst = append(dst, '[')
+ dst = strconv.AppendInt(dst, int64(vals[0]), 10)
+ if len(vals) > 1 {
+ for _, val := range vals[1:] {
+ dst = strconv.AppendInt(append(dst, ','), int64(val), 10)
+ }
+ }
+ dst = append(dst, ']')
+ return dst
+}
+
+// AppendInt16 converts the input int16 to a string and
+// appends the encoded string to the input byte slice.
+func (Encoder) AppendInt16(dst []byte, val int16) []byte {
+ return strconv.AppendInt(dst, int64(val), 10)
+}
+
+// AppendInts16 encodes the input int16s to json and
+// appends the encoded string list to the input byte slice.
+func (Encoder) AppendInts16(dst []byte, vals []int16) []byte {
+ if len(vals) == 0 {
+ return append(dst, '[', ']')
+ }
+ dst = append(dst, '[')
+ dst = strconv.AppendInt(dst, int64(vals[0]), 10)
+ if len(vals) > 1 {
+ for _, val := range vals[1:] {
+ dst = strconv.AppendInt(append(dst, ','), int64(val), 10)
+ }
+ }
+ dst = append(dst, ']')
+ return dst
+}
+
+// AppendInt32 converts the input int32 to a string and
+// appends the encoded string to the input byte slice.
+func (Encoder) AppendInt32(dst []byte, val int32) []byte {
+ return strconv.AppendInt(dst, int64(val), 10)
+}
+
+// AppendInts32 encodes the input int32s to json and
+// appends the encoded string list to the input byte slice.
+func (Encoder) AppendInts32(dst []byte, vals []int32) []byte {
+ if len(vals) == 0 {
+ return append(dst, '[', ']')
+ }
+ dst = append(dst, '[')
+ dst = strconv.AppendInt(dst, int64(vals[0]), 10)
+ if len(vals) > 1 {
+ for _, val := range vals[1:] {
+ dst = strconv.AppendInt(append(dst, ','), int64(val), 10)
+ }
+ }
+ dst = append(dst, ']')
+ return dst
+}
+
+// AppendInt64 converts the input int64 to a string and
+// appends the encoded string to the input byte slice.
+func (Encoder) AppendInt64(dst []byte, val int64) []byte {
+ return strconv.AppendInt(dst, val, 10)
+}
+
+// AppendInts64 encodes the input int64s to json and
+// appends the encoded string list to the input byte slice.
+func (Encoder) AppendInts64(dst []byte, vals []int64) []byte {
+ if len(vals) == 0 {
+ return append(dst, '[', ']')
+ }
+ dst = append(dst, '[')
+ dst = strconv.AppendInt(dst, vals[0], 10)
+ if len(vals) > 1 {
+ for _, val := range vals[1:] {
+ dst = strconv.AppendInt(append(dst, ','), val, 10)
+ }
+ }
+ dst = append(dst, ']')
+ return dst
+}
+
+// AppendUint converts the input uint to a string and
+// appends the encoded string to the input byte slice.
+func (Encoder) AppendUint(dst []byte, val uint) []byte {
+ return strconv.AppendUint(dst, uint64(val), 10)
+}
+
+// AppendUints encodes the input uints to json and
+// appends the encoded string list to the input byte slice.
+func (Encoder) AppendUints(dst []byte, vals []uint) []byte {
+ if len(vals) == 0 {
+ return append(dst, '[', ']')
+ }
+ dst = append(dst, '[')
+ dst = strconv.AppendUint(dst, uint64(vals[0]), 10)
+ if len(vals) > 1 {
+ for _, val := range vals[1:] {
+ dst = strconv.AppendUint(append(dst, ','), uint64(val), 10)
+ }
+ }
+ dst = append(dst, ']')
+ return dst
+}
+
+// AppendUint8 converts the input uint8 to a string and
+// appends the encoded string to the input byte slice.
+func (Encoder) AppendUint8(dst []byte, val uint8) []byte {
+ return strconv.AppendUint(dst, uint64(val), 10)
+}
+
+// AppendUints8 encodes the input uint8s to json and
+// appends the encoded string list to the input byte slice.
+func (Encoder) AppendUints8(dst []byte, vals []uint8) []byte {
+ if len(vals) == 0 {
+ return append(dst, '[', ']')
+ }
+ dst = append(dst, '[')
+ dst = strconv.AppendUint(dst, uint64(vals[0]), 10)
+ if len(vals) > 1 {
+ for _, val := range vals[1:] {
+ dst = strconv.AppendUint(append(dst, ','), uint64(val), 10)
+ }
+ }
+ dst = append(dst, ']')
+ return dst
+}
+
+// AppendUint16 converts the input uint16 to a string and
+// appends the encoded string to the input byte slice.
+func (Encoder) AppendUint16(dst []byte, val uint16) []byte {
+ return strconv.AppendUint(dst, uint64(val), 10)
+}
+
+// AppendUints16 encodes the input uint16s to json and
+// appends the encoded string list to the input byte slice.
+func (Encoder) AppendUints16(dst []byte, vals []uint16) []byte {
+ if len(vals) == 0 {
+ return append(dst, '[', ']')
+ }
+ dst = append(dst, '[')
+ dst = strconv.AppendUint(dst, uint64(vals[0]), 10)
+ if len(vals) > 1 {
+ for _, val := range vals[1:] {
+ dst = strconv.AppendUint(append(dst, ','), uint64(val), 10)
+ }
+ }
+ dst = append(dst, ']')
+ return dst
+}
+
+// AppendUint32 converts the input uint32 to a string and
+// appends the encoded string to the input byte slice.
+func (Encoder) AppendUint32(dst []byte, val uint32) []byte {
+ return strconv.AppendUint(dst, uint64(val), 10)
+}
+
+// AppendUints32 encodes the input uint32s to json and
+// appends the encoded string list to the input byte slice.
+func (Encoder) AppendUints32(dst []byte, vals []uint32) []byte {
+ if len(vals) == 0 {
+ return append(dst, '[', ']')
+ }
+ dst = append(dst, '[')
+ dst = strconv.AppendUint(dst, uint64(vals[0]), 10)
+ if len(vals) > 1 {
+ for _, val := range vals[1:] {
+ dst = strconv.AppendUint(append(dst, ','), uint64(val), 10)
+ }
+ }
+ dst = append(dst, ']')
+ return dst
+}
+
+// AppendUint64 converts the input uint64 to a string and
+// appends the encoded string to the input byte slice.
+func (Encoder) AppendUint64(dst []byte, val uint64) []byte {
+ return strconv.AppendUint(dst, val, 10)
+}
+
+// AppendUints64 encodes the input uint64s to json and
+// appends the encoded string list to the input byte slice.
+func (Encoder) AppendUints64(dst []byte, vals []uint64) []byte {
+ if len(vals) == 0 {
+ return append(dst, '[', ']')
+ }
+ dst = append(dst, '[')
+ dst = strconv.AppendUint(dst, vals[0], 10)
+ if len(vals) > 1 {
+ for _, val := range vals[1:] {
+ dst = strconv.AppendUint(append(dst, ','), val, 10)
+ }
+ }
+ dst = append(dst, ']')
+ return dst
+}
+
+func appendFloat(dst []byte, val float64, bitSize int) []byte {
+ // JSON does not permit NaN or Infinity. A typical JSON encoder would fail
+ // with an error, but a logging library wants the data to get through so we
+ // make a tradeoff and store those types as string.
+ switch {
+ case math.IsNaN(val):
+ return append(dst, `"NaN"`...)
+ case math.IsInf(val, 1):
+ return append(dst, `"+Inf"`...)
+ case math.IsInf(val, -1):
+ return append(dst, `"-Inf"`...)
+ }
+ return strconv.AppendFloat(dst, val, 'f', -1, bitSize)
+}
+
+// AppendFloat32 converts the input float32 to a string and
+// appends the encoded string to the input byte slice.
+func (Encoder) AppendFloat32(dst []byte, val float32) []byte {
+ return appendFloat(dst, float64(val), 32)
+}
+
+// AppendFloats32 encodes the input float32s to json and
+// appends the encoded string list to the input byte slice.
+func (Encoder) AppendFloats32(dst []byte, vals []float32) []byte {
+ if len(vals) == 0 {
+ return append(dst, '[', ']')
+ }
+ dst = append(dst, '[')
+ dst = appendFloat(dst, float64(vals[0]), 32)
+ if len(vals) > 1 {
+ for _, val := range vals[1:] {
+ dst = appendFloat(append(dst, ','), float64(val), 32)
+ }
+ }
+ dst = append(dst, ']')
+ return dst
+}
+
+// AppendFloat64 converts the input float64 to a string and
+// appends the encoded string to the input byte slice.
+func (Encoder) AppendFloat64(dst []byte, val float64) []byte {
+ return appendFloat(dst, val, 64)
+}
+
+// AppendFloats64 encodes the input float64s to json and
+// appends the encoded string list to the input byte slice.
+func (Encoder) AppendFloats64(dst []byte, vals []float64) []byte {
+ if len(vals) == 0 {
+ return append(dst, '[', ']')
+ }
+ dst = append(dst, '[')
+ dst = appendFloat(dst, vals[0], 64)
+ if len(vals) > 1 {
+ for _, val := range vals[1:] {
+ dst = appendFloat(append(dst, ','), val, 64)
+ }
+ }
+ dst = append(dst, ']')
+ return dst
+}
+
+// AppendInterface marshals the input interface to a string and
+// appends the encoded string to the input byte slice.
+func (e Encoder) AppendInterface(dst []byte, i interface{}) []byte {
+ marshaled, err := JSONMarshalFunc(i)
+ if err != nil {
+ return e.AppendString(dst, fmt.Sprintf("marshaling error: %v", err))
+ }
+ return append(dst, marshaled...)
+}
+
+// AppendType appends the parameter type (as a string) to the input byte slice.
+func (e Encoder) AppendType(dst []byte, i interface{}) []byte {
+ if i == nil {
+ return e.AppendString(dst, "<nil>")
+ }
+ return e.AppendString(dst, reflect.TypeOf(i).String())
+}
+
+// AppendObjectData takes in an object that is already in a byte array
+// and adds it to the dst.
+func (Encoder) AppendObjectData(dst []byte, o []byte) []byte {
+ // Three conditions apply here:
+ // 1. new content starts with '{' - which should be dropped OR
+ // 2. new content starts with '{' - which should be replaced with ','
+ // to separate with existing content OR
+ // 3. existing content has already other fields
+ if o[0] == '{' {
+ if len(dst) > 1 {
+ dst = append(dst, ',')
+ }
+ o = o[1:]
+ } else if len(dst) > 1 {
+ dst = append(dst, ',')
+ }
+ return append(dst, o...)
+}
+
+// AppendIPAddr adds IPv4 or IPv6 address to dst.
+func (e Encoder) AppendIPAddr(dst []byte, ip net.IP) []byte {
+ return e.AppendString(dst, ip.String())
+}
+
+// AppendIPPrefix adds IPv4 or IPv6 Prefix (address & mask) to dst.
+func (e Encoder) AppendIPPrefix(dst []byte, pfx net.IPNet) []byte {
+ return e.AppendString(dst, pfx.String())
+
+}
+
+// AppendMACAddr adds MAC address to dst.
+func (e Encoder) AppendMACAddr(dst []byte, ha net.HardwareAddr) []byte {
+ return e.AppendString(dst, ha.String())
+}