github.com/searKing/golang/go@v1.2.117/encoding/prettyjson/stream.go (about)

     1  // Copyright 2023 The searKing Author. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package prettyjson
     6  
     7  import "io"
     8  
     9  // An Encoder writes JSON values to an output stream.
    10  type Encoder struct {
    11  	w          io.Writer
    12  	err        error
    13  	escapeHTML bool
    14  
    15  	indentBuf    []byte
    16  	indentPrefix string
    17  	indentValue  string
    18  
    19  	truncateBytes  int
    20  	truncateString int
    21  	truncateMap    int
    22  	truncateSlice  int
    23  	truncateArray  int
    24  }
    25  
    26  // NewEncoder returns a new encoder that writes to w.
    27  func NewEncoder(w io.Writer) *Encoder {
    28  	return &Encoder{w: w, escapeHTML: true}
    29  }
    30  
    31  // Encode writes the JSON encoding of v to the stream,
    32  // followed by a newline character.
    33  //
    34  // See the documentation for Marshal for details about the
    35  // conversion of Go values to JSON.
    36  func (enc *Encoder) Encode(v any) error {
    37  	if enc.err != nil {
    38  		return enc.err
    39  	}
    40  
    41  	e := newEncodeState()
    42  	defer encodeStatePool.Put(e)
    43  
    44  	err := e.marshal(v, encOpts{escapeHTML: enc.escapeHTML,
    45  		truncateBytes:        enc.truncateBytes,
    46  		truncateString:       enc.truncateString,
    47  		truncateMap:          enc.truncateMap,
    48  		truncateSliceOrArray: enc.truncateSlice})
    49  	if err != nil {
    50  		return err
    51  	}
    52  
    53  	// Terminate each value with a newline.
    54  	// This makes the output look a little nicer
    55  	// when debugging, and some kind of space
    56  	// is required if the encoded value was a number,
    57  	// so that the reader knows there aren't more
    58  	// digits coming.
    59  	e.WriteByte('\n')
    60  
    61  	b := e.Bytes()
    62  	if enc.indentPrefix != "" || enc.indentValue != "" {
    63  		enc.indentBuf, err = appendIndent(enc.indentBuf[:0], b, enc.indentPrefix, enc.indentValue)
    64  		if err != nil {
    65  			return err
    66  		}
    67  		b = enc.indentBuf
    68  	}
    69  	if _, err = enc.w.Write(b); err != nil {
    70  		enc.err = err
    71  	}
    72  	return err
    73  }
    74  
    75  // SetIndent instructs the encoder to format each subsequent encoded
    76  // value as if indented by the package-level function Indent(dst, src, prefix, indent).
    77  // Calling SetIndent("", "") disables indentation.
    78  func (enc *Encoder) SetIndent(prefix, indent string) {
    79  	enc.indentPrefix = prefix
    80  	enc.indentValue = indent
    81  }
    82  
    83  // SetEscapeHTML specifies whether problematic HTML characters
    84  // should be escaped inside JSON quoted strings.
    85  // The default behavior is to escape &, <, and > to \u0026, \u003c, and \u003e
    86  // to avoid certain safety problems that can arise when embedding JSON in HTML.
    87  //
    88  // In non-HTML settings where the escaping interferes with the readability
    89  // of the output, SetEscapeHTML(false) disables this behavior.
    90  func (enc *Encoder) SetEscapeHTML(on bool) {
    91  	enc.escapeHTML = on
    92  }
    93  
    94  // SetTruncate shrinks bytes, string, map, slice, array 's len to n at most
    95  func (enc *Encoder) SetTruncate(n int) {
    96  	enc.truncateBytes = n
    97  	enc.truncateString = n
    98  	enc.truncateMap = n
    99  	enc.truncateSlice = n
   100  	enc.truncateArray = n
   101  }