github.com/ssgreg/logf@v1.4.1/json_encoder.go (about)

     1  package logf
     2  
     3  import (
     4  	"encoding/base64"
     5  	"encoding/json"
     6  	"time"
     7  	"unicode/utf8"
     8  	"unsafe"
     9  )
    10  
    11  // NewJSONEncoder creates the new instance of the JSON Encoder with the
    12  // given JSONEncoderConfig.
    13  var NewJSONEncoder = jsonEncoderGetter(
    14  	func(cfg JSONEncoderConfig) Encoder {
    15  		return &jsonEncoder{cfg.WithDefaults(), NewCache(100), nil, 0}
    16  	},
    17  )
    18  
    19  // NewJSONTypeEncoderFactory creates the new instance of the JSON
    20  // TypeEncoderFactory with the given JSONEncoderConfig.
    21  var NewJSONTypeEncoderFactory = jsonTypeEncoderFactoryGetter(
    22  	func(c JSONEncoderConfig) TypeEncoderFactory {
    23  		return &jsonEncoder{c.WithDefaults(), nil, nil, 0}
    24  	},
    25  )
    26  
    27  type jsonEncoderGetter func(cfg JSONEncoderConfig) Encoder
    28  
    29  func (c jsonEncoderGetter) Default() Encoder {
    30  	return c(JSONEncoderConfig{})
    31  }
    32  
    33  type jsonTypeEncoderFactoryGetter func(cfg JSONEncoderConfig) TypeEncoderFactory
    34  
    35  func (c jsonTypeEncoderFactoryGetter) Default() TypeEncoderFactory {
    36  	return c(JSONEncoderConfig{})
    37  }
    38  
    39  type jsonEncoder struct {
    40  	JSONEncoderConfig
    41  	cache *Cache
    42  
    43  	buf         *Buffer
    44  	startBufLen int
    45  }
    46  
    47  func (f *jsonEncoder) TypeEncoder(buf *Buffer) TypeEncoder {
    48  	f.buf = buf
    49  	f.startBufLen = f.buf.Len()
    50  
    51  	return f
    52  }
    53  
    54  func (f *jsonEncoder) Encode(buf *Buffer, e Entry) error {
    55  	f.buf = buf
    56  	f.startBufLen = f.buf.Len()
    57  
    58  	buf.AppendByte('{')
    59  
    60  	// Level.
    61  	if !f.DisableFieldLevel {
    62  		f.addKey(f.FieldKeyLevel)
    63  		f.EncodeLevel(e.Level, f)
    64  	}
    65  
    66  	// Time.
    67  	if !f.DisableFieldTime {
    68  		f.EncodeFieldTime(f.FieldKeyTime, e.Time)
    69  	}
    70  
    71  	// Logger name.
    72  	if !f.DisableFieldName && e.LoggerName != "" {
    73  		f.EncodeFieldString(f.FieldKeyName, e.LoggerName)
    74  	}
    75  
    76  	// Message.
    77  	if !f.DisableFieldMsg {
    78  		f.EncodeFieldString(f.FieldKeyMsg, e.Text)
    79  	}
    80  
    81  	// Caller.
    82  	if !f.DisableFieldCaller && e.Caller.Specified {
    83  		f.addKey(f.FieldKeyCaller)
    84  		f.EncodeCaller(e.Caller, f)
    85  	}
    86  
    87  	// Logger's fields.
    88  	if bytes, ok := f.cache.Get(e.LoggerID); ok {
    89  		buf.AppendBytes(bytes)
    90  	} else {
    91  		le := buf.Len()
    92  		for _, field := range e.DerivedFields {
    93  			field.Accept(f)
    94  		}
    95  
    96  		bf := make([]byte, buf.Len()-le)
    97  		copy(bf, buf.Data[le:])
    98  		f.cache.Set(e.LoggerID, bf)
    99  	}
   100  
   101  	// Entry's fields.
   102  	for _, field := range e.Fields {
   103  		field.Accept(f)
   104  	}
   105  
   106  	buf.AppendByte('}')
   107  	buf.AppendByte('\n')
   108  
   109  	return nil
   110  }
   111  
   112  func (f *jsonEncoder) EncodeFieldAny(k string, v interface{}) {
   113  	f.addKey(k)
   114  	f.EncodeTypeAny(v)
   115  }
   116  
   117  func (f *jsonEncoder) EncodeFieldBool(k string, v bool) {
   118  	f.addKey(k)
   119  	f.EncodeTypeBool(v)
   120  }
   121  
   122  func (f *jsonEncoder) EncodeFieldInt64(k string, v int64) {
   123  	f.addKey(k)
   124  	f.EncodeTypeInt64(v)
   125  }
   126  
   127  func (f *jsonEncoder) EncodeFieldInt32(k string, v int32) {
   128  	f.addKey(k)
   129  	f.EncodeTypeInt32(v)
   130  }
   131  
   132  func (f *jsonEncoder) EncodeFieldInt16(k string, v int16) {
   133  	f.addKey(k)
   134  	f.EncodeTypeInt16(v)
   135  }
   136  
   137  func (f *jsonEncoder) EncodeFieldInt8(k string, v int8) {
   138  	f.addKey(k)
   139  	f.EncodeTypeInt8(v)
   140  }
   141  
   142  func (f *jsonEncoder) EncodeFieldUint64(k string, v uint64) {
   143  	f.addKey(k)
   144  	f.EncodeTypeUint64(v)
   145  }
   146  
   147  func (f *jsonEncoder) EncodeFieldUint32(k string, v uint32) {
   148  	f.addKey(k)
   149  	f.EncodeTypeUint32(v)
   150  }
   151  
   152  func (f *jsonEncoder) EncodeFieldUint16(k string, v uint16) {
   153  	f.addKey(k)
   154  	f.EncodeTypeUint16(v)
   155  }
   156  
   157  func (f *jsonEncoder) EncodeFieldUint8(k string, v uint8) {
   158  	f.addKey(k)
   159  	f.EncodeTypeUint8(v)
   160  }
   161  
   162  func (f *jsonEncoder) EncodeFieldFloat64(k string, v float64) {
   163  	f.addKey(k)
   164  	f.EncodeTypeFloat64(v)
   165  }
   166  
   167  func (f *jsonEncoder) EncodeFieldFloat32(k string, v float32) {
   168  	f.addKey(k)
   169  	f.EncodeTypeFloat32(v)
   170  }
   171  
   172  func (f *jsonEncoder) EncodeFieldString(k string, v string) {
   173  	f.addKey(k)
   174  	f.EncodeTypeString(v)
   175  }
   176  
   177  func (f *jsonEncoder) EncodeFieldStrings(k string, v []string) {
   178  	f.addKey(k)
   179  	f.EncodeTypeStrings(v)
   180  }
   181  
   182  func (f *jsonEncoder) EncodeFieldDuration(k string, v time.Duration) {
   183  	f.addKey(k)
   184  	f.EncodeTypeDuration(v)
   185  }
   186  
   187  func (f *jsonEncoder) EncodeFieldError(k string, v error) {
   188  	// The only exception that has no EncodeX function. EncodeError can add
   189  	// new fields by itself.
   190  	f.EncodeError(k, v, f)
   191  }
   192  
   193  func (f *jsonEncoder) EncodeFieldTime(k string, v time.Time) {
   194  	f.addKey(k)
   195  	f.EncodeTypeTime(v)
   196  }
   197  
   198  func (f *jsonEncoder) EncodeFieldArray(k string, v ArrayEncoder) {
   199  	f.addKey(k)
   200  	f.EncodeTypeArray(v)
   201  }
   202  
   203  func (f *jsonEncoder) EncodeFieldObject(k string, v ObjectEncoder) {
   204  	f.addKey(k)
   205  	f.EncodeTypeObject(v)
   206  }
   207  
   208  func (f *jsonEncoder) EncodeFieldBytes(k string, v []byte) {
   209  	f.addKey(k)
   210  	f.EncodeTypeBytes(v)
   211  }
   212  
   213  func (f *jsonEncoder) EncodeFieldBools(k string, v []bool) {
   214  	f.addKey(k)
   215  	f.EncodeTypeBools(v)
   216  }
   217  
   218  func (f *jsonEncoder) EncodeFieldInts64(k string, v []int64) {
   219  	f.addKey(k)
   220  	f.EncodeTypeInts64(v)
   221  }
   222  
   223  func (f *jsonEncoder) EncodeFieldInts32(k string, v []int32) {
   224  	f.addKey(k)
   225  	f.EncodeTypeInts32(v)
   226  }
   227  
   228  func (f *jsonEncoder) EncodeFieldInts16(k string, v []int16) {
   229  	f.addKey(k)
   230  	f.EncodeTypeInts16(v)
   231  }
   232  
   233  func (f *jsonEncoder) EncodeFieldInts8(k string, v []int8) {
   234  	f.addKey(k)
   235  	f.EncodeTypeInts8(v)
   236  }
   237  
   238  func (f *jsonEncoder) EncodeFieldUints64(k string, v []uint64) {
   239  	f.addKey(k)
   240  	f.EncodeTypeUints64(v)
   241  }
   242  
   243  func (f *jsonEncoder) EncodeFieldUints32(k string, v []uint32) {
   244  	f.addKey(k)
   245  	f.EncodeTypeUints32(v)
   246  }
   247  
   248  func (f *jsonEncoder) EncodeFieldUints16(k string, v []uint16) {
   249  	f.addKey(k)
   250  	f.EncodeTypeUints16(v)
   251  }
   252  
   253  func (f *jsonEncoder) EncodeFieldUints8(k string, v []uint8) {
   254  	f.addKey(k)
   255  	f.EncodeTypeUints8(v)
   256  }
   257  
   258  func (f *jsonEncoder) EncodeFieldFloats64(k string, v []float64) {
   259  	f.addKey(k)
   260  	f.EncodeTypeFloats64(v)
   261  }
   262  
   263  func (f *jsonEncoder) EncodeFieldFloats32(k string, v []float32) {
   264  	f.addKey(k)
   265  	f.EncodeTypeFloats32(v)
   266  }
   267  
   268  func (f *jsonEncoder) EncodeFieldDurations(k string, v []time.Duration) {
   269  	f.addKey(k)
   270  	f.EncodeTypeDurations(v)
   271  }
   272  
   273  func (f *jsonEncoder) EncodeTypeAny(v interface{}) {
   274  	e := json.NewEncoder(f.buf)
   275  	e.Encode(v)
   276  
   277  	if !f.empty() && f.buf.Back() == '\n' {
   278  		f.buf.Data = f.buf.Data[0 : f.buf.Len()-1]
   279  	}
   280  }
   281  
   282  func (f *jsonEncoder) EncodeTypeUnsafeBytes(v unsafe.Pointer) {
   283  	f.appendSeparator()
   284  	f.buf.AppendByte('"')
   285  	EscapeByteString(f.buf, *(*[]byte)(v))
   286  	f.buf.AppendByte('"')
   287  }
   288  
   289  func (f *jsonEncoder) EncodeTypeBool(v bool) {
   290  	f.appendSeparator()
   291  	AppendBool(f.buf, v)
   292  }
   293  
   294  func (f *jsonEncoder) EncodeTypeString(v string) {
   295  	f.appendSeparator()
   296  	f.buf.AppendByte('"')
   297  	EscapeString(f.buf, v)
   298  	f.buf.AppendByte('"')
   299  }
   300  
   301  func (f *jsonEncoder) EncodeTypeInt64(v int64) {
   302  	f.appendSeparator()
   303  	AppendInt(f.buf, v)
   304  }
   305  
   306  func (f *jsonEncoder) EncodeTypeInt32(v int32) {
   307  	f.appendSeparator()
   308  	AppendInt(f.buf, int64(v))
   309  }
   310  
   311  func (f *jsonEncoder) EncodeTypeInt16(v int16) {
   312  	f.appendSeparator()
   313  	AppendInt(f.buf, int64(v))
   314  }
   315  
   316  func (f *jsonEncoder) EncodeTypeInt8(v int8) {
   317  	f.appendSeparator()
   318  	AppendInt(f.buf, int64(v))
   319  }
   320  
   321  func (f *jsonEncoder) EncodeTypeUint64(v uint64) {
   322  	f.appendSeparator()
   323  	AppendUint(f.buf, uint64(v))
   324  }
   325  
   326  func (f *jsonEncoder) EncodeTypeUint32(v uint32) {
   327  	f.appendSeparator()
   328  	AppendUint(f.buf, uint64(v))
   329  }
   330  
   331  func (f *jsonEncoder) EncodeTypeUint16(v uint16) {
   332  	f.appendSeparator()
   333  	AppendUint(f.buf, uint64(v))
   334  }
   335  
   336  func (f *jsonEncoder) EncodeTypeUint8(v uint8) {
   337  	f.appendSeparator()
   338  	AppendUint(f.buf, uint64(v))
   339  }
   340  
   341  func (f *jsonEncoder) EncodeTypeFloat64(v float64) {
   342  	f.appendSeparator()
   343  	AppendFloat64(f.buf, v)
   344  }
   345  
   346  func (f *jsonEncoder) EncodeTypeFloat32(v float32) {
   347  	f.appendSeparator()
   348  	AppendFloat32(f.buf, v)
   349  }
   350  
   351  func (f *jsonEncoder) EncodeTypeDuration(v time.Duration) {
   352  	f.appendSeparator()
   353  	f.EncodeDuration(v, f)
   354  }
   355  
   356  func (f *jsonEncoder) EncodeTypeTime(v time.Time) {
   357  	f.appendSeparator()
   358  	f.EncodeTime(v, f)
   359  }
   360  
   361  func (f *jsonEncoder) EncodeTypeBytes(v []byte) {
   362  	f.appendSeparator()
   363  	f.buf.AppendByte('"')
   364  	base64.StdEncoding.Encode(f.buf.ExtendBytes(base64.StdEncoding.EncodedLen(len(v))), v)
   365  	f.buf.AppendByte('"')
   366  }
   367  
   368  func (f *jsonEncoder) EncodeTypeBools(v []bool) {
   369  	f.appendSeparator()
   370  	f.buf.AppendByte('[')
   371  	for i := range v {
   372  		f.EncodeTypeBool(v[i])
   373  	}
   374  	f.buf.AppendByte(']')
   375  }
   376  
   377  func (f *jsonEncoder) EncodeTypeStrings(v []string) {
   378  	f.appendSeparator()
   379  	f.buf.AppendByte('[')
   380  	for i := range v {
   381  		f.EncodeTypeString(v[i])
   382  	}
   383  	f.buf.AppendByte(']')
   384  }
   385  
   386  func (f *jsonEncoder) EncodeTypeInts64(v []int64) {
   387  	f.appendSeparator()
   388  	f.buf.AppendByte('[')
   389  	for i := range v {
   390  		f.EncodeTypeInt64(v[i])
   391  	}
   392  	f.buf.AppendByte(']')
   393  }
   394  
   395  func (f *jsonEncoder) EncodeTypeInts32(v []int32) {
   396  	f.appendSeparator()
   397  	f.buf.AppendByte('[')
   398  	for i := range v {
   399  		f.EncodeTypeInt32(v[i])
   400  	}
   401  	f.buf.AppendByte(']')
   402  }
   403  
   404  func (f *jsonEncoder) EncodeTypeInts16(v []int16) {
   405  	f.appendSeparator()
   406  	f.buf.AppendByte('[')
   407  	for i := range v {
   408  		f.EncodeTypeInt16(v[i])
   409  	}
   410  	f.buf.AppendByte(']')
   411  }
   412  
   413  func (f *jsonEncoder) EncodeTypeInts8(v []int8) {
   414  	f.appendSeparator()
   415  	f.buf.AppendByte('[')
   416  	for i := range v {
   417  		f.EncodeTypeInt8(v[i])
   418  	}
   419  	f.buf.AppendByte(']')
   420  }
   421  
   422  func (f *jsonEncoder) EncodeTypeUints64(v []uint64) {
   423  	f.appendSeparator()
   424  	f.buf.AppendByte('[')
   425  	for i := range v {
   426  		f.EncodeTypeUint64(v[i])
   427  	}
   428  	f.buf.AppendByte(']')
   429  }
   430  
   431  func (f *jsonEncoder) EncodeTypeUints32(v []uint32) {
   432  	f.appendSeparator()
   433  	f.buf.AppendByte('[')
   434  	for i := range v {
   435  		f.EncodeTypeUint32(v[i])
   436  	}
   437  	f.buf.AppendByte(']')
   438  }
   439  
   440  func (f *jsonEncoder) EncodeTypeUints16(v []uint16) {
   441  	f.appendSeparator()
   442  	f.buf.AppendByte('[')
   443  	for i := range v {
   444  		f.EncodeTypeUint16(v[i])
   445  	}
   446  	f.buf.AppendByte(']')
   447  }
   448  
   449  func (f *jsonEncoder) EncodeTypeUints8(v []uint8) {
   450  	f.appendSeparator()
   451  	f.buf.AppendByte('[')
   452  	for i := range v {
   453  		f.EncodeTypeUint8(v[i])
   454  	}
   455  	f.buf.AppendByte(']')
   456  }
   457  
   458  func (f *jsonEncoder) EncodeTypeFloats64(v []float64) {
   459  	f.appendSeparator()
   460  	f.buf.AppendByte('[')
   461  	for i := range v {
   462  		f.EncodeTypeFloat64(v[i])
   463  	}
   464  	f.buf.AppendByte(']')
   465  }
   466  
   467  func (f *jsonEncoder) EncodeTypeFloats32(v []float32) {
   468  	f.appendSeparator()
   469  	f.buf.AppendByte('[')
   470  	for i := range v {
   471  		f.EncodeTypeFloat32(v[i])
   472  	}
   473  	f.buf.AppendByte(']')
   474  }
   475  
   476  func (f *jsonEncoder) EncodeTypeDurations(v []time.Duration) {
   477  	f.appendSeparator()
   478  	f.buf.AppendByte('[')
   479  	for i := range v {
   480  		f.EncodeTypeDuration(v[i])
   481  	}
   482  	f.buf.AppendByte(']')
   483  }
   484  
   485  func (f *jsonEncoder) EncodeTypeArray(v ArrayEncoder) {
   486  	f.appendSeparator()
   487  	f.buf.AppendByte('[')
   488  	v.EncodeLogfArray(f)
   489  	f.buf.AppendByte(']')
   490  }
   491  
   492  func (f *jsonEncoder) EncodeTypeObject(v ObjectEncoder) {
   493  	f.appendSeparator()
   494  	f.buf.AppendByte('{')
   495  	v.EncodeLogfObject(f)
   496  	f.buf.AppendByte('}')
   497  }
   498  
   499  func (f *jsonEncoder) appendSeparator() {
   500  	if f.empty() {
   501  		return
   502  	}
   503  
   504  	switch f.buf.Back() {
   505  	case '{', '[', ':', ',':
   506  		return
   507  	}
   508  	f.buf.AppendByte(',')
   509  }
   510  
   511  func (f *jsonEncoder) empty() bool {
   512  	return f.buf.Len() == f.startBufLen
   513  }
   514  
   515  func (f *jsonEncoder) addKey(k string) {
   516  	f.appendSeparator()
   517  	f.buf.AppendByte('"')
   518  	EscapeString(f.buf, k)
   519  	f.buf.AppendByte('"')
   520  	f.buf.AppendByte(':')
   521  }
   522  
   523  const hex = "0123456789abcdef"
   524  
   525  // EscapeString processes a single escape sequence to the given Buffer.
   526  func EscapeString(buf *Buffer, s string) error {
   527  	p := 0
   528  	for i := 0; i < len(s); {
   529  		c := s[i]
   530  		switch {
   531  		case c < utf8.RuneSelf && c >= 0x20 && c != '\\' && c != '"':
   532  			i++
   533  
   534  			continue
   535  
   536  		case c < utf8.RuneSelf:
   537  			buf.AppendString(s[p:i])
   538  			switch c {
   539  			case '\t':
   540  				buf.AppendString(`\t`)
   541  			case '\r':
   542  				buf.AppendString(`\r`)
   543  			case '\n':
   544  				buf.AppendString(`\n`)
   545  			case '\\':
   546  				buf.AppendString(`\\`)
   547  			case '"':
   548  				buf.AppendString(`\"`)
   549  			default:
   550  				buf.AppendString(`\u00`)
   551  				buf.AppendByte(hex[c>>4])
   552  				buf.AppendByte(hex[c&0xf])
   553  			}
   554  			i++
   555  			p = i
   556  
   557  			continue
   558  		}
   559  		v, wd := utf8.DecodeRuneInString(s[i:])
   560  		if v == utf8.RuneError && wd == 1 {
   561  			buf.AppendString(s[p:i])
   562  			buf.AppendString(`\ufffd`)
   563  			i++
   564  			p = i
   565  
   566  			continue
   567  		} else {
   568  			i += wd
   569  		}
   570  	}
   571  	buf.AppendString(s[p:])
   572  
   573  	return nil
   574  }
   575  
   576  // EscapeByteString processes a single escape sequence to the given Buffer.
   577  func EscapeByteString(buf *Buffer, s []byte) error {
   578  	p := 0
   579  	for i := 0; i < len(s); {
   580  		c := s[i]
   581  		switch {
   582  		case c >= 0x20 && c != '\\' && c != '"':
   583  			i++
   584  
   585  			continue
   586  
   587  		default:
   588  			buf.AppendBytes(s[p:i])
   589  			switch c {
   590  			case '\t':
   591  				buf.AppendString(`\t`)
   592  			case '\r':
   593  				buf.AppendString(`\r`)
   594  			case '\n':
   595  				buf.AppendString(`\n`)
   596  			case '\\':
   597  				buf.AppendString(`\\`)
   598  			case '"':
   599  				buf.AppendString(`\"`)
   600  			default:
   601  				buf.AppendString(`\u00`)
   602  				buf.AppendByte(hex[c>>4])
   603  				buf.AppendByte(hex[c&0xf])
   604  			}
   605  			i++
   606  			p = i
   607  
   608  			continue
   609  		}
   610  	}
   611  	buf.AppendBytes(s[p:])
   612  
   613  	return nil
   614  }