go_dreamfactory/lego/sys/codec/render/json_stream.go
2022-07-11 17:10:49 +08:00

201 lines
4.9 KiB
Go

package render
import (
"go_dreamfactory/lego/sys/codec/core"
"go_dreamfactory/lego/sys/codec/utils"
"github.com/modern-go/reflect2"
)
func NewStream(codec core.ICodec, bufSize int) *JsonStream {
return &JsonStream{
codec: codec,
buf: make([]byte, 0, bufSize),
err: nil,
indention: 0,
}
}
type JsonStream struct {
codec core.ICodec
err error
buf []byte
indention int
}
//写入对象
func (this *JsonStream) WriteVal(val interface{}) {
if nil == val {
this.WriteNil()
return
}
cacheKey := reflect2.RTypeOf(val)
encoder := this.codec.GetEncoderFromCache(cacheKey)
if encoder == nil {
typ := reflect2.TypeOf(val)
encoder = this.codec.EncoderOf(typ)
}
encoder.Encode(reflect2.PtrOf(val), this)
}
func (this *JsonStream) WriteNil() {
this.writeFourBytes('n', 'u', 'l', 'l')
}
func (this *JsonStream) WriteEmptyArray() {
this.writeTwoBytes('[', ']')
}
func (this *JsonStream) WriteArrayStart() {
this.indention += this.codec.Options().IndentionStep
this.writeByte('[')
this.writeIndention(0)
}
func (this *JsonStream) WriteArrayEnd() {
this.writeIndention(this.codec.Options().IndentionStep)
this.indention -= this.codec.Options().IndentionStep
this.writeByte(']')
}
func (this *JsonStream) WriteEmptyObject() {
this.writeTwoBytes('{', '}')
}
func (this *JsonStream) WriteObjectStart() {
this.indention += this.codec.Options().IndentionStep
this.writeByte('{')
this.writeIndention(0)
}
func (this *JsonStream) WriteObjectEnd() {
this.writeIndention(this.codec.Options().IndentionStep)
this.indention -= this.codec.Options().IndentionStep
this.writeByte('}')
}
func (this *JsonStream) WriteMemberSplit() {
this.writeByte(',')
this.writeIndention(0)
}
func (this *JsonStream) WriteKVSplit() {
this.writeByte(':')
}
func (this *JsonStream) WriteKeyStart() {
this.writeByte('"')
}
func (this *JsonStream) WriteKeyEnd() {
this.writeByte('"')
}
func (this *JsonStream) WriteObjectFieldName(val string) {
this.WriteString(val)
if this.indention > 0 {
this.writeTwoBytes(':', ' ')
} else {
this.writeByte(':')
}
}
func (this *JsonStream) WriteBool(val bool) {
if val {
this.writeTrue()
} else {
this.writeFalse()
}
}
func (this *JsonStream) WriteInt8(val int8) {
utils.WriteInt8ToString(&this.buf, val)
}
func (this *JsonStream) WriteInt16(val int16) {
utils.WriteInt16ToString(&this.buf, val)
}
func (this *JsonStream) WriteInt32(val int32) {
utils.WriteInt32ToString(&this.buf, val)
}
func (this *JsonStream) WriteInt64(val int64) {
utils.WriteInt64ToString(&this.buf, val)
}
func (this *JsonStream) WriteUint8(val uint8) {
utils.WriteUint8ToString(&this.buf, val)
}
func (this *JsonStream) WriteUint16(val uint16) {
utils.WriteUint16ToString(&this.buf, val)
}
func (this *JsonStream) WriteUint32(val uint32) {
utils.WriteUint32ToString(&this.buf, val)
}
func (this *JsonStream) WriteUint64(val uint64) {
utils.WriteUint64ToString(&this.buf, val)
}
func (this *JsonStream) WriteFloat32(val float32) {
utils.WriteFloat32ToString(&this.buf, val)
}
func (this *JsonStream) WriteFloat64(val float64) {
utils.WriteFloat64ToString(&this.buf, val)
}
func (this *JsonStream) WriteString(val string) {
valLen := len(val)
this.buf = append(this.buf, '"')
i := 0
for ; i < valLen; i++ {
c := val[i]
if c > 31 && c != '"' && c != '\\' {
this.buf = append(this.buf, c)
} else {
break
}
}
if i == valLen {
this.buf = append(this.buf, '"')
return
}
utils.WriteStringSlowPath(&this.buf, i, val, valLen)
}
func (this *JsonStream) WriteBytes(val []byte) {
this.buf = append(this.buf, val...)
}
func (this *JsonStream) Buffer() []byte {
return this.buf
}
func (this *JsonStream) Error() error {
return this.err
}
func (this *JsonStream) SetErr(err error) {
this.err = err
}
//-------------------------------------------------------------------------------------------------------------------------------------------------------------------
// WriteTrue write true to stream
func (stream *JsonStream) writeTrue() {
stream.writeFourBytes('t', 'r', 'u', 'e')
}
// WriteFalse write false to stream
func (stream *JsonStream) writeFalse() {
stream.writeFiveBytes('f', 'a', 'l', 's', 'e')
}
func (this *JsonStream) writeByte(c byte) {
this.buf = append(this.buf, c)
}
func (this *JsonStream) writeTwoBytes(c1 byte, c2 byte) {
this.buf = append(this.buf, c1, c2)
}
func (this *JsonStream) writeThreeBytes(c1 byte, c2 byte, c3 byte) {
this.buf = append(this.buf, c1, c2, c3)
}
func (this *JsonStream) writeFourBytes(c1 byte, c2 byte, c3 byte, c4 byte) {
this.buf = append(this.buf, c1, c2, c3, c4)
}
func (this *JsonStream) writeFiveBytes(c1 byte, c2 byte, c3 byte, c4 byte, c5 byte) {
this.buf = append(this.buf, c1, c2, c3, c4, c5)
}
func (stream *JsonStream) writeIndention(delta int) {
if stream.indention == 0 {
return
}
stream.writeByte('\n')
toWrite := stream.indention - delta
for i := 0; i < toWrite; i++ {
stream.buf = append(stream.buf, ' ')
}
}