1
0
mirror of https://github.com/json-iterator/go.git synced 2025-06-24 23:16:47 +02:00

remove n from stream

This commit is contained in:
Tao Wen
2018-02-14 13:58:51 +08:00
parent 6a8f9fa342
commit 75810179f6
6 changed files with 99 additions and 363 deletions

View File

@ -599,10 +599,10 @@ func (codec *base64Codec) Encode(ptr unsafe.Pointer, stream *Stream) {
} }
encoding := base64.StdEncoding encoding := base64.StdEncoding
stream.writeByte('"') stream.writeByte('"')
toGrow := encoding.EncodedLen(len(src)) size := encoding.EncodedLen(len(src))
stream.ensure(toGrow) buf := make([]byte, size)
encoding.Encode(stream.buf[stream.n:], src) encoding.Encode(buf, src)
stream.n += toGrow stream.buf = append(stream.buf, buf...)
stream.writeByte('"') stream.writeByte('"')
} }
@ -615,10 +615,10 @@ func (codec *base64Codec) EncodeInterface(val interface{}, stream *Stream) {
} }
encoding := base64.StdEncoding encoding := base64.StdEncoding
stream.writeByte('"') stream.writeByte('"')
toGrow := encoding.EncodedLen(len(src)) size := encoding.EncodedLen(len(src))
stream.ensure(toGrow) buf := make([]byte, size)
encoding.Encode(stream.buf[stream.n:], src) encoding.Encode(buf, src)
stream.n += toGrow stream.buf = append(stream.buf, buf...)
stream.writeByte('"') stream.writeByte('"')
} }

View File

@ -10,11 +10,9 @@ type Stream struct {
cfg *frozenConfig cfg *frozenConfig
out io.Writer out io.Writer
buf []byte buf []byte
n int
Error error Error error
indention int indention int
Attachment interface{} // open for customized encoder Attachment interface{} // open for customized encoder
floatBuf []byte
} }
// NewStream create new stream instance. // NewStream create new stream instance.
@ -25,11 +23,9 @@ func NewStream(cfg API, out io.Writer, bufSize int) *Stream {
return &Stream{ return &Stream{
cfg: cfg.(*frozenConfig), cfg: cfg.(*frozenConfig),
out: out, out: out,
buf: make([]byte, bufSize), buf: make([]byte, 0, bufSize),
n: 0,
Error: nil, Error: nil,
indention: 0, indention: 0,
floatBuf: make([]byte, 0, 32),
} }
} }
@ -41,22 +37,22 @@ func (stream *Stream) Pool() StreamPool {
// Reset reuse this stream instance by assign a new writer // Reset reuse this stream instance by assign a new writer
func (stream *Stream) Reset(out io.Writer) { func (stream *Stream) Reset(out io.Writer) {
stream.out = out stream.out = out
stream.n = 0 stream.buf = stream.buf[:0]
} }
// Available returns how many bytes are unused in the buffer. // Available returns how many bytes are unused in the buffer.
func (stream *Stream) Available() int { func (stream *Stream) Available() int {
return len(stream.buf) - stream.n return cap(stream.buf) - len(stream.buf)
} }
// Buffered returns the number of bytes that have been written into the current buffer. // Buffered returns the number of bytes that have been written into the current buffer.
func (stream *Stream) Buffered() int { func (stream *Stream) Buffered() int {
return stream.n return len(stream.buf)
} }
// Buffer if writer is nil, use this method to take the result // Buffer if writer is nil, use this method to take the result
func (stream *Stream) Buffer() []byte { func (stream *Stream) Buffer() []byte {
return stream.buf[:stream.n] return stream.buf
} }
// Write writes the contents of p into the buffer. // Write writes the contents of p into the buffer.
@ -64,97 +60,34 @@ func (stream *Stream) Buffer() []byte {
// If nn < len(p), it also returns an error explaining // If nn < len(p), it also returns an error explaining
// why the write is short. // why the write is short.
func (stream *Stream) Write(p []byte) (nn int, err error) { func (stream *Stream) Write(p []byte) (nn int, err error) {
for len(p) > stream.Available() && stream.Error == nil { stream.buf = append(stream.buf, p...)
if stream.out == nil { if stream.out != nil {
stream.growAtLeast(len(p)) nn, err = stream.out.Write(stream.buf)
} else { stream.buf = stream.buf[nn:]
var n int return
if stream.Buffered() == 0 {
// Large write, empty buffer.
// Write directly from p to avoid copy.
n, stream.Error = stream.out.Write(p)
} else {
n = copy(stream.buf[stream.n:], p)
stream.n += n
stream.Flush()
}
nn += n
p = p[n:]
}
} }
if stream.Error != nil { return len(p), nil
return nn, stream.Error
}
n := copy(stream.buf[stream.n:], p)
stream.n += n
nn += n
return nn, nil
} }
// WriteByte writes a single byte. // WriteByte writes a single byte.
func (stream *Stream) writeByte(c byte) { func (stream *Stream) writeByte(c byte) {
if stream.Error != nil { stream.buf = append(stream.buf, c)
return
}
if stream.Available() < 1 {
stream.growAtLeast(1)
}
stream.buf[stream.n] = c
stream.n++
} }
func (stream *Stream) writeTwoBytes(c1 byte, c2 byte) { func (stream *Stream) writeTwoBytes(c1 byte, c2 byte) {
if stream.Error != nil { stream.buf = append(stream.buf, c1, c2)
return
}
if stream.Available() < 2 {
stream.growAtLeast(2)
}
stream.buf[stream.n] = c1
stream.buf[stream.n+1] = c2
stream.n += 2
} }
func (stream *Stream) writeThreeBytes(c1 byte, c2 byte, c3 byte) { func (stream *Stream) writeThreeBytes(c1 byte, c2 byte, c3 byte) {
if stream.Error != nil { stream.buf = append(stream.buf, c1, c2, c3)
return
}
if stream.Available() < 3 {
stream.growAtLeast(3)
}
stream.buf[stream.n] = c1
stream.buf[stream.n+1] = c2
stream.buf[stream.n+2] = c3
stream.n += 3
} }
func (stream *Stream) writeFourBytes(c1 byte, c2 byte, c3 byte, c4 byte) { func (stream *Stream) writeFourBytes(c1 byte, c2 byte, c3 byte, c4 byte) {
if stream.Error != nil { stream.buf = append(stream.buf, c1, c2, c3, c4)
return
}
if stream.Available() < 4 {
stream.growAtLeast(4)
}
stream.buf[stream.n] = c1
stream.buf[stream.n+1] = c2
stream.buf[stream.n+2] = c3
stream.buf[stream.n+3] = c4
stream.n += 4
} }
func (stream *Stream) writeFiveBytes(c1 byte, c2 byte, c3 byte, c4 byte, c5 byte) { func (stream *Stream) writeFiveBytes(c1 byte, c2 byte, c3 byte, c4 byte, c5 byte) {
if stream.Error != nil { stream.buf = append(stream.buf, c1, c2, c3, c4, c5)
return
}
if stream.Available() < 5 {
stream.growAtLeast(5)
}
stream.buf[stream.n] = c1
stream.buf[stream.n+1] = c2
stream.buf[stream.n+2] = c3
stream.buf[stream.n+3] = c4
stream.buf[stream.n+4] = c5
stream.n += 5
} }
// Flush writes any buffered data to the underlying io.Writer. // Flush writes any buffered data to the underlying io.Writer.
@ -165,56 +98,20 @@ func (stream *Stream) Flush() error {
if stream.Error != nil { if stream.Error != nil {
return stream.Error return stream.Error
} }
if stream.n == 0 { n, err := stream.out.Write(stream.buf)
return nil
}
n, err := stream.out.Write(stream.buf[0:stream.n])
if n < stream.n && err == nil {
err = io.ErrShortWrite
}
if err != nil { if err != nil {
if n > 0 && n < stream.n { if stream.Error == nil {
copy(stream.buf[0:stream.n-n], stream.buf[n:stream.n]) stream.Error = err
} }
stream.n -= n
stream.Error = err
return err return err
} }
stream.n = 0 stream.buf = stream.buf[n:]
return nil return nil
} }
func (stream *Stream) ensure(minimal int) {
available := stream.Available()
if available < minimal {
stream.growAtLeast(minimal)
}
}
func (stream *Stream) growAtLeast(minimal int) {
if stream.out != nil {
stream.Flush()
if stream.Available() >= minimal {
return
}
}
toGrow := len(stream.buf)
if toGrow < minimal {
toGrow = minimal
}
newBuf := make([]byte, len(stream.buf)+toGrow)
copy(newBuf, stream.Buffer())
stream.buf = newBuf
}
// WriteRaw write string out without quotes, just like []byte // WriteRaw write string out without quotes, just like []byte
func (stream *Stream) WriteRaw(s string) { func (stream *Stream) WriteRaw(s string) {
stream.ensure(len(s)) stream.buf = append(stream.buf, s...)
if stream.Error != nil {
return
}
n := copy(stream.buf[stream.n:], s)
stream.n += n
} }
// WriteNil write null to stream // WriteNil write null to stream
@ -275,6 +172,7 @@ func (stream *Stream) WriteEmptyObject() {
func (stream *Stream) WriteMore() { func (stream *Stream) WriteMore() {
stream.writeByte(',') stream.writeByte(',')
stream.writeIndention(0) stream.writeIndention(0)
stream.Flush()
} }
// WriteArrayStart write [ with possible indention // WriteArrayStart write [ with possible indention
@ -302,9 +200,7 @@ func (stream *Stream) writeIndention(delta int) {
} }
stream.writeByte('\n') stream.writeByte('\n')
toWrite := stream.indention - delta toWrite := stream.indention - delta
stream.ensure(toWrite) for i := 0; i < toWrite; i++ {
for i := 0; i < toWrite && stream.n < len(stream.buf); i++ { stream.buf = append(stream.buf, ' ')
stream.buf[stream.n] = ' '
stream.n++
} }
} }

View File

@ -21,9 +21,7 @@ func (stream *Stream) WriteFloat32(val float32) {
fmt = 'e' fmt = 'e'
} }
} }
stream.floatBuf = strconv.AppendFloat(stream.floatBuf, float64(val), fmt, -1, 32) stream.buf = strconv.AppendFloat(stream.buf, float64(val), fmt, -1, 32)
stream.Write(stream.floatBuf)
stream.floatBuf = stream.floatBuf[:0]
} }
// WriteFloat32Lossy write float32 to stream with ONLY 6 digits precision although much much faster // WriteFloat32Lossy write float32 to stream with ONLY 6 digits precision although much much faster
@ -45,13 +43,12 @@ func (stream *Stream) WriteFloat32Lossy(val float32) {
return return
} }
stream.writeByte('.') stream.writeByte('.')
stream.ensure(10)
for p := precision - 1; p > 0 && fval < pow10[p]; p-- { for p := precision - 1; p > 0 && fval < pow10[p]; p-- {
stream.writeByte('0') stream.writeByte('0')
} }
stream.WriteUint64(fval) stream.WriteUint64(fval)
for stream.buf[stream.n-1] == '0' { for stream.buf[len(stream.buf)-1] == '0' {
stream.n-- stream.buf = stream.buf[:len(stream.buf)-1]
} }
} }
@ -65,9 +62,7 @@ func (stream *Stream) WriteFloat64(val float64) {
fmt = 'e' fmt = 'e'
} }
} }
stream.floatBuf = strconv.AppendFloat(stream.floatBuf, float64(val), fmt, -1, 64) stream.buf = strconv.AppendFloat(stream.buf, float64(val), fmt, -1, 64)
stream.Write(stream.floatBuf)
stream.floatBuf = stream.floatBuf[:0]
} }
// WriteFloat64Lossy write float64 to stream with ONLY 6 digits precision although much much faster // WriteFloat64Lossy write float64 to stream with ONLY 6 digits precision although much much faster
@ -89,12 +84,11 @@ func (stream *Stream) WriteFloat64Lossy(val float64) {
return return
} }
stream.writeByte('.') stream.writeByte('.')
stream.ensure(10)
for p := precision - 1; p > 0 && fval < pow10[p]; p-- { for p := precision - 1; p > 0 && fval < pow10[p]; p-- {
stream.writeByte('0') stream.writeByte('0')
} }
stream.WriteUint64(fval) stream.WriteUint64(fval)
for stream.buf[stream.n-1] == '0' { for stream.buf[len(stream.buf)-1] == '0' {
stream.n-- stream.buf = stream.buf[:len(stream.buf)-1]
} }
} }

View File

@ -14,299 +14,169 @@ func init() {
} }
} }
func writeFirstBuf(buf []byte, v uint32, n int) int { func writeFirstBuf(space []byte, v uint32) []byte {
start := v >> 24 start := v >> 24
if start == 0 { if start == 0 {
buf[n] = byte(v >> 16) space = append(space, byte(v >> 16), byte(v >> 8))
n++
buf[n] = byte(v >> 8)
n++
} else if start == 1 { } else if start == 1 {
buf[n] = byte(v >> 8) space = append(space, byte(v >> 8))
n++
} }
buf[n] = byte(v) space = append(space, byte(v))
n++ return space
return n
} }
func writeBuf(buf []byte, v uint32, n int) { func writeBuf(buf []byte, v uint32) []byte {
buf[n] = byte(v >> 16) return append(buf, byte(v >> 16), byte(v >> 8), byte(v))
buf[n+1] = byte(v >> 8)
buf[n+2] = byte(v)
} }
// WriteUint8 write uint8 to stream // WriteUint8 write uint8 to stream
func (stream *Stream) WriteUint8(val uint8) { func (stream *Stream) WriteUint8(val uint8) {
stream.ensure(3) stream.buf = writeFirstBuf(stream.buf, digits[val])
stream.n = writeFirstBuf(stream.buf, digits[val], stream.n)
} }
// WriteInt8 write int8 to stream // WriteInt8 write int8 to stream
func (stream *Stream) WriteInt8(nval int8) { func (stream *Stream) WriteInt8(nval int8) {
stream.ensure(4)
n := stream.n
var val uint8 var val uint8
if nval < 0 { if nval < 0 {
val = uint8(-nval) val = uint8(-nval)
stream.buf[n] = '-' stream.buf = append(stream.buf, '-')
n++
} else { } else {
val = uint8(nval) val = uint8(nval)
} }
stream.n = writeFirstBuf(stream.buf, digits[val], n) stream.buf = writeFirstBuf(stream.buf, digits[val])
} }
// WriteUint16 write uint16 to stream // WriteUint16 write uint16 to stream
func (stream *Stream) WriteUint16(val uint16) { func (stream *Stream) WriteUint16(val uint16) {
stream.ensure(5)
q1 := val / 1000 q1 := val / 1000
if q1 == 0 { if q1 == 0 {
stream.n = writeFirstBuf(stream.buf, digits[val], stream.n) stream.buf = writeFirstBuf(stream.buf, digits[val])
return return
} }
r1 := val - q1*1000 r1 := val - q1*1000
n := writeFirstBuf(stream.buf, digits[q1], stream.n) stream.buf = writeFirstBuf(stream.buf, digits[q1])
writeBuf(stream.buf, digits[r1], n) stream.buf = writeBuf(stream.buf, digits[r1])
stream.n = n + 3
return return
} }
// WriteInt16 write int16 to stream // WriteInt16 write int16 to stream
func (stream *Stream) WriteInt16(nval int16) { func (stream *Stream) WriteInt16(nval int16) {
stream.ensure(6)
n := stream.n
var val uint16 var val uint16
if nval < 0 { if nval < 0 {
val = uint16(-nval) val = uint16(-nval)
stream.buf[n] = '-' stream.buf = append(stream.buf, '-')
n++
} else { } else {
val = uint16(nval) val = uint16(nval)
} }
q1 := val / 1000 stream.WriteUint16(val)
if q1 == 0 {
stream.n = writeFirstBuf(stream.buf, digits[val], n)
return
}
r1 := val - q1*1000
n = writeFirstBuf(stream.buf, digits[q1], n)
writeBuf(stream.buf, digits[r1], n)
stream.n = n + 3
return
} }
// WriteUint32 write uint32 to stream // WriteUint32 write uint32 to stream
func (stream *Stream) WriteUint32(val uint32) { func (stream *Stream) WriteUint32(val uint32) {
stream.ensure(10)
n := stream.n
q1 := val / 1000 q1 := val / 1000
if q1 == 0 { if q1 == 0 {
stream.n = writeFirstBuf(stream.buf, digits[val], n) stream.buf = writeFirstBuf(stream.buf, digits[val])
return return
} }
r1 := val - q1*1000 r1 := val - q1*1000
q2 := q1 / 1000 q2 := q1 / 1000
if q2 == 0 { if q2 == 0 {
n := writeFirstBuf(stream.buf, digits[q1], n) stream.buf = writeFirstBuf(stream.buf, digits[q1])
writeBuf(stream.buf, digits[r1], n) stream.buf = writeBuf(stream.buf, digits[r1])
stream.n = n + 3
return return
} }
r2 := q1 - q2*1000 r2 := q1 - q2*1000
q3 := q2 / 1000 q3 := q2 / 1000
if q3 == 0 { if q3 == 0 {
n = writeFirstBuf(stream.buf, digits[q2], n) stream.buf = writeFirstBuf(stream.buf, digits[q2])
} else { } else {
r3 := q2 - q3*1000 r3 := q2 - q3*1000
stream.buf[n] = byte(q3 + '0') stream.buf = append(stream.buf, byte(q3 + '0'))
n++ stream.buf = writeBuf(stream.buf, digits[r3])
writeBuf(stream.buf, digits[r3], n)
n += 3
} }
writeBuf(stream.buf, digits[r2], n) stream.buf = writeBuf(stream.buf, digits[r2])
writeBuf(stream.buf, digits[r1], n+3) stream.buf = writeBuf(stream.buf, digits[r1])
stream.n = n + 6
} }
// WriteInt32 write int32 to stream // WriteInt32 write int32 to stream
func (stream *Stream) WriteInt32(nval int32) { func (stream *Stream) WriteInt32(nval int32) {
stream.ensure(11)
n := stream.n
var val uint32 var val uint32
if nval < 0 { if nval < 0 {
val = uint32(-nval) val = uint32(-nval)
stream.buf[n] = '-' stream.buf = append(stream.buf, '-')
n++
} else { } else {
val = uint32(nval) val = uint32(nval)
} }
q1 := val / 1000 stream.WriteUint32(val)
if q1 == 0 {
stream.n = writeFirstBuf(stream.buf, digits[val], n)
return
}
r1 := val - q1*1000
q2 := q1 / 1000
if q2 == 0 {
n := writeFirstBuf(stream.buf, digits[q1], n)
writeBuf(stream.buf, digits[r1], n)
stream.n = n + 3
return
}
r2 := q1 - q2*1000
q3 := q2 / 1000
if q3 == 0 {
n = writeFirstBuf(stream.buf, digits[q2], n)
} else {
r3 := q2 - q3*1000
stream.buf[n] = byte(q3 + '0')
n++
writeBuf(stream.buf, digits[r3], n)
n += 3
}
writeBuf(stream.buf, digits[r2], n)
writeBuf(stream.buf, digits[r1], n+3)
stream.n = n + 6
} }
// WriteUint64 write uint64 to stream // WriteUint64 write uint64 to stream
func (stream *Stream) WriteUint64(val uint64) { func (stream *Stream) WriteUint64(val uint64) {
stream.ensure(20)
n := stream.n
q1 := val / 1000 q1 := val / 1000
if q1 == 0 { if q1 == 0 {
stream.n = writeFirstBuf(stream.buf, digits[val], n) stream.buf = writeFirstBuf(stream.buf, digits[val])
return return
} }
r1 := val - q1*1000 r1 := val - q1*1000
q2 := q1 / 1000 q2 := q1 / 1000
if q2 == 0 { if q2 == 0 {
n := writeFirstBuf(stream.buf, digits[q1], n) stream.buf = writeFirstBuf(stream.buf, digits[q1])
writeBuf(stream.buf, digits[r1], n) stream.buf = writeBuf(stream.buf, digits[r1])
stream.n = n + 3
return return
} }
r2 := q1 - q2*1000 r2 := q1 - q2*1000
q3 := q2 / 1000 q3 := q2 / 1000
if q3 == 0 { if q3 == 0 {
n = writeFirstBuf(stream.buf, digits[q2], n) stream.buf = writeFirstBuf(stream.buf, digits[q2])
writeBuf(stream.buf, digits[r2], n) stream.buf = writeBuf(stream.buf, digits[r2])
writeBuf(stream.buf, digits[r1], n+3) stream.buf = writeBuf(stream.buf, digits[r1])
stream.n = n + 6
return return
} }
r3 := q2 - q3*1000 r3 := q2 - q3*1000
q4 := q3 / 1000 q4 := q3 / 1000
if q4 == 0 { if q4 == 0 {
n = writeFirstBuf(stream.buf, digits[q3], n) stream.buf = writeFirstBuf(stream.buf, digits[q3])
writeBuf(stream.buf, digits[r3], n) stream.buf = writeBuf(stream.buf, digits[r3])
writeBuf(stream.buf, digits[r2], n+3) stream.buf = writeBuf(stream.buf, digits[r2])
writeBuf(stream.buf, digits[r1], n+6) stream.buf = writeBuf(stream.buf, digits[r1])
stream.n = n + 9
return return
} }
r4 := q3 - q4*1000 r4 := q3 - q4*1000
q5 := q4 / 1000 q5 := q4 / 1000
if q5 == 0 { if q5 == 0 {
n = writeFirstBuf(stream.buf, digits[q4], n) stream.buf = writeFirstBuf(stream.buf, digits[q4])
writeBuf(stream.buf, digits[r4], n) stream.buf = writeBuf(stream.buf, digits[r4])
writeBuf(stream.buf, digits[r3], n+3) stream.buf = writeBuf(stream.buf, digits[r3])
writeBuf(stream.buf, digits[r2], n+6) stream.buf = writeBuf(stream.buf, digits[r2])
writeBuf(stream.buf, digits[r1], n+9) stream.buf = writeBuf(stream.buf, digits[r1])
stream.n = n + 12
return return
} }
r5 := q4 - q5*1000 r5 := q4 - q5*1000
q6 := q5 / 1000 q6 := q5 / 1000
if q6 == 0 { if q6 == 0 {
n = writeFirstBuf(stream.buf, digits[q5], n) stream.buf = writeFirstBuf(stream.buf, digits[q5])
} else { } else {
n = writeFirstBuf(stream.buf, digits[q6], n) stream.buf = writeFirstBuf(stream.buf, digits[q6])
r6 := q5 - q6*1000 r6 := q5 - q6*1000
writeBuf(stream.buf, digits[r6], n) stream.buf = writeBuf(stream.buf, digits[r6])
n += 3
} }
writeBuf(stream.buf, digits[r5], n) stream.buf = writeBuf(stream.buf, digits[r5])
writeBuf(stream.buf, digits[r4], n+3) stream.buf = writeBuf(stream.buf, digits[r4])
writeBuf(stream.buf, digits[r3], n+6) stream.buf = writeBuf(stream.buf, digits[r3])
writeBuf(stream.buf, digits[r2], n+9) stream.buf = writeBuf(stream.buf, digits[r2])
writeBuf(stream.buf, digits[r1], n+12) stream.buf = writeBuf(stream.buf, digits[r1])
stream.n = n + 15
} }
// WriteInt64 write int64 to stream // WriteInt64 write int64 to stream
func (stream *Stream) WriteInt64(nval int64) { func (stream *Stream) WriteInt64(nval int64) {
stream.ensure(20)
n := stream.n
var val uint64 var val uint64
if nval < 0 { if nval < 0 {
val = uint64(-nval) val = uint64(-nval)
stream.buf[n] = '-' stream.buf = append(stream.buf, '-')
n++
} else { } else {
val = uint64(nval) val = uint64(nval)
} }
q1 := val / 1000 stream.WriteUint64(val)
if q1 == 0 {
stream.n = writeFirstBuf(stream.buf, digits[val], n)
return
}
r1 := val - q1*1000
q2 := q1 / 1000
if q2 == 0 {
n := writeFirstBuf(stream.buf, digits[q1], n)
writeBuf(stream.buf, digits[r1], n)
stream.n = n + 3
return
}
r2 := q1 - q2*1000
q3 := q2 / 1000
if q3 == 0 {
n = writeFirstBuf(stream.buf, digits[q2], n)
writeBuf(stream.buf, digits[r2], n)
writeBuf(stream.buf, digits[r1], n+3)
stream.n = n + 6
return
}
r3 := q2 - q3*1000
q4 := q3 / 1000
if q4 == 0 {
n = writeFirstBuf(stream.buf, digits[q3], n)
writeBuf(stream.buf, digits[r3], n)
writeBuf(stream.buf, digits[r2], n+3)
writeBuf(stream.buf, digits[r1], n+6)
stream.n = n + 9
return
}
r4 := q3 - q4*1000
q5 := q4 / 1000
if q5 == 0 {
n = writeFirstBuf(stream.buf, digits[q4], n)
writeBuf(stream.buf, digits[r4], n)
writeBuf(stream.buf, digits[r3], n+3)
writeBuf(stream.buf, digits[r2], n+6)
writeBuf(stream.buf, digits[r1], n+9)
stream.n = n + 12
return
}
r5 := q4 - q5*1000
q6 := q5 / 1000
if q6 == 0 {
n = writeFirstBuf(stream.buf, digits[q5], n)
} else {
stream.buf[n] = byte(q6 + '0')
n++
r6 := q5 - q6*1000
writeBuf(stream.buf, digits[r6], n)
n += 3
}
writeBuf(stream.buf, digits[r5], n)
writeBuf(stream.buf, digits[r4], n+3)
writeBuf(stream.buf, digits[r3], n+6)
writeBuf(stream.buf, digits[r2], n+9)
writeBuf(stream.buf, digits[r1], n+12)
stream.n = n + 15
} }
// WriteInt write int to stream // WriteInt write int to stream

View File

@ -219,34 +219,22 @@ var hex = "0123456789abcdef"
// WriteStringWithHTMLEscaped write string to stream with html special characters escaped // WriteStringWithHTMLEscaped write string to stream with html special characters escaped
func (stream *Stream) WriteStringWithHTMLEscaped(s string) { func (stream *Stream) WriteStringWithHTMLEscaped(s string) {
stream.ensure(32)
valLen := len(s) valLen := len(s)
toWriteLen := valLen stream.buf = append(stream.buf, '"')
bufLengthMinusTwo := len(stream.buf) - 2 // make room for the quotes
if stream.n+toWriteLen > bufLengthMinusTwo {
toWriteLen = bufLengthMinusTwo - stream.n
}
n := stream.n
stream.buf[n] = '"'
n++
// write string, the fast path, without utf8 and escape support // write string, the fast path, without utf8 and escape support
i := 0 i := 0
for ; i < toWriteLen; i++ { for ; i < valLen; i++ {
c := s[i] c := s[i]
if c < utf8.RuneSelf && htmlSafeSet[c] { if c < utf8.RuneSelf && htmlSafeSet[c] {
stream.buf[n] = c stream.buf = append(stream.buf, c)
n++
} else { } else {
break break
} }
} }
if i == valLen { if i == valLen {
stream.buf[n] = '"' stream.buf = append(stream.buf, '"')
n++
stream.n = n
return return
} }
stream.n = n
writeStringSlowPathWithHTMLEscaped(stream, i, s, valLen) writeStringSlowPathWithHTMLEscaped(stream, i, s, valLen)
} }
@ -321,34 +309,22 @@ func writeStringSlowPathWithHTMLEscaped(stream *Stream, i int, s string, valLen
// WriteString write string to stream without html escape // WriteString write string to stream without html escape
func (stream *Stream) WriteString(s string) { func (stream *Stream) WriteString(s string) {
stream.ensure(32)
valLen := len(s) valLen := len(s)
toWriteLen := valLen stream.buf = append(stream.buf, '"')
bufLengthMinusTwo := len(stream.buf) - 2 // make room for the quotes
if stream.n+toWriteLen > bufLengthMinusTwo {
toWriteLen = bufLengthMinusTwo - stream.n
}
n := stream.n
stream.buf[n] = '"'
n++
// write string, the fast path, without utf8 and escape support // write string, the fast path, without utf8 and escape support
i := 0 i := 0
for ; i < toWriteLen; i++ { for ; i < valLen; i++ {
c := s[i] c := s[i]
if c > 31 && c != '"' && c != '\\' { if c > 31 && c != '"' && c != '\\' {
stream.buf[n] = c stream.buf = append(stream.buf, c)
n++
} else { } else {
break break
} }
} }
if i == valLen { if i == valLen {
stream.buf[n] = '"' stream.buf = append(stream.buf, '"')
n++
stream.n = n
return return
} }
stream.n = n
writeStringSlowPath(stream, i, s, valLen) writeStringSlowPath(stream, i, s, valLen)
} }

View File

@ -23,10 +23,10 @@ func Test_writeBytes_should_grow_buffer(t *testing.T) {
stream := NewStream(ConfigDefault, nil, 1) stream := NewStream(ConfigDefault, nil, 1)
stream.Write([]byte{'1', '2'}) stream.Write([]byte{'1', '2'})
should.Equal("12", string(stream.Buffer())) should.Equal("12", string(stream.Buffer()))
should.Equal(3, len(stream.buf)) should.Equal(2, len(stream.buf))
stream.Write([]byte{'3', '4', '5', '6', '7'}) stream.Write([]byte{'3', '4', '5', '6', '7'})
should.Equal("1234567", string(stream.Buffer())) should.Equal("1234567", string(stream.Buffer()))
should.Equal(8, len(stream.buf)) should.Equal(7, len(stream.buf))
} }
func Test_writeIndention_should_grow_buffer(t *testing.T) { func Test_writeIndention_should_grow_buffer(t *testing.T) {
@ -65,5 +65,5 @@ func Test_flush_buffer_should_stop_grow_buffer(t *testing.T) {
writer := new(NopWriter) writer := new(NopWriter)
NewEncoder(writer).Encode(make([]int, 10000000)) NewEncoder(writer).Encode(make([]int, 10000000))
should := require.New(t) should := require.New(t)
should.Equal(512, writer.bufferSize) should.Equal(8, writer.bufferSize)
} }