//go:build launchdarkly_easyjson // +build launchdarkly_easyjson package jwriter // This file defines the easyjson-based implementation of the low-level JSON writer, which is used instead // of token_writer_default.go if the launchdarkly_easyjson build tag is enabled. // // For the contract governing the behavior of the exported methods in this type, see the comments on the // corresponding methods in token_writer_default.go. import ( "encoding/json" "io" ejwriter "github.com/mailru/easyjson/jwriter" ) var nullToken = []byte("null") type tokenWriter struct { // We might be initialized either with a pointer to an existing Writer, in which case we'll use that. pWriter *ejwriter.Writer // Or, we might be initialized from scratch so we must create our own Writer. We'd like to avoid // allocating that on the heap, so we'll store it here. inlineWriter ejwriter.Writer targetIOWriter io.Writer targetBufferSize int } func newTokenWriter() tokenWriter { return tokenWriter{} } func newTokenWriterFromEasyjsonWriter(writer *ejwriter.Writer) tokenWriter { return tokenWriter{pWriter: writer} } func newStreamingTokenWriter(dest io.Writer, bufferSize int) tokenWriter { tw := tokenWriter{targetIOWriter: dest, targetBufferSize: bufferSize} tw.inlineWriter.Buffer.EnsureSpace(bufferSize) return tw } func (tw *tokenWriter) Bytes() []byte { pWriter := tw.pWriter if pWriter == nil { pWriter = &tw.inlineWriter } bytes, _ := pWriter.BuildBytes(nil) return bytes } func (tw *tokenWriter) Grow(n int) { pWriter := tw.pWriter if pWriter == nil { pWriter = &tw.inlineWriter } pWriter.Buffer.EnsureSpace(n) } func (tw *tokenWriter) Flush() error { if tw.targetIOWriter == nil { return nil } _, err := tw.inlineWriter.DumpTo(tw.targetIOWriter) return err } func (tw *tokenWriter) Null() error { pWriter := tw.pWriter if pWriter == nil { pWriter = &tw.inlineWriter } pWriter.Raw(nullToken, nil) return tw.maybeFlush() } func (tw *tokenWriter) Bool(value bool) error { pWriter := tw.pWriter if pWriter == nil { pWriter = &tw.inlineWriter } pWriter.Bool(value) return tw.maybeFlush() } func (tw *tokenWriter) Int(value int) error { pWriter := tw.pWriter if pWriter == nil { pWriter = &tw.inlineWriter } pWriter.Int(value) return tw.maybeFlush() } func (tw *tokenWriter) Float64(value float64) error { i := int(value) if float64(i) == value { return tw.Int(i) } pWriter := tw.pWriter if pWriter == nil { pWriter = &tw.inlineWriter } pWriter.Float64(value) return tw.maybeFlush() } func (tw *tokenWriter) String(value string) error { pWriter := tw.pWriter if pWriter == nil { pWriter = &tw.inlineWriter } pWriter.String(value) return tw.maybeFlush() } func (tw *tokenWriter) Raw(value json.RawMessage) error { pWriter := tw.pWriter if pWriter == nil { pWriter = &tw.inlineWriter } pWriter.Raw(value, nil) return tw.maybeFlush() } func (tw *tokenWriter) PropertyName(name string) error { pWriter := tw.pWriter if pWriter == nil { pWriter = &tw.inlineWriter } pWriter.String(name) pWriter.RawByte(':') return tw.maybeFlush() } func (tw *tokenWriter) Delimiter(delimiter byte) error { pWriter := tw.pWriter if pWriter == nil { pWriter = &tw.inlineWriter } pWriter.RawByte(delimiter) return tw.maybeFlush() } func (tw *tokenWriter) maybeFlush() error { pWriter := tw.pWriter if pWriter == nil { pWriter = &tw.inlineWriter } if pWriter.Error != nil { return pWriter.Error } if tw.targetIOWriter == nil || pWriter.Buffer.Size() < tw.targetBufferSize { return nil } return tw.Flush() }