Tao Wen 9 rokov pred
rodič
commit
ba3c30799b
3 zmenil súbory, kde vykonal 82 pridanie a 0 odobranie
  1. 39 0
      feature_stream_float.go
  2. 27 0
      jsoniter_float_test.go
  3. 16 0
      stream.go

+ 39 - 0
feature_stream_float.go

@@ -0,0 +1,39 @@
+package jsoniter
+
+import "strconv"
+
+var POW10 []uint64
+
+func init() {
+	POW10 = []uint64{1, 10, 100, 1000, 10000, 100000, 1000000}
+}
+
+func (stream *Stream) WriteFloat32(val float32) {
+	if val < 0 {
+		stream.writeByte('-')
+		val = -val
+	}
+	if val > 0x4ffffff {
+		stream.WriteRaw(strconv.FormatFloat(float64(val), 'f', -1, 32));
+		return
+	}
+	precision := 6
+	exp := uint64(1000000) // 6
+	lval := uint64(float64(val) * float64(exp) + 0.5)
+	stream.WriteUint64(lval / exp)
+	fval := lval % exp
+	if fval == 0 {
+		return
+	}
+	stream.writeByte('.')
+	if stream.Available() < 10 {
+		stream.Flush()
+	}
+	for p := precision - 1; p > 0 && fval < POW10[p]; p-- {
+		stream.writeByte('0')
+	}
+	stream.WriteUint64(fval);
+	for stream.buf[stream.n - 1] == '0' {
+		stream.n--;
+	}
+}

+ 27 - 0
jsoniter_float_test.go

@@ -4,6 +4,9 @@ import (
 	"encoding/json"
 	"fmt"
 	"testing"
+	"github.com/json-iterator/go/require"
+	"bytes"
+	"strconv"
 )
 
 func Test_float64_0(t *testing.T) {
@@ -31,6 +34,30 @@ func Test_float32_1_dot_1_comma(t *testing.T) {
 	}
 }
 
+func Test_write_float32(t *testing.T) {
+	vals := []float32{0, 1, -1, 99, 0xff, 0xfff, 0xffff, 0xfffff, 0xffffff, 0x4ffffff, 0xfffffff,
+	-0x4ffffff, -0xfffffff, 1.2345, 1.23456, 1.234567, 1.001}
+	for _, val := range vals {
+		t.Run(fmt.Sprintf("%v", val), func(t *testing.T) {
+			should := require.New(t)
+			buf := &bytes.Buffer{}
+			stream := NewStream(buf, 4096)
+			stream.WriteFloat32(val)
+			stream.Flush()
+			should.Nil(stream.Error)
+			should.Equal(strconv.FormatFloat(float64(val), 'f', -1, 32), buf.String())
+		})
+	}
+	should := require.New(t)
+	buf := &bytes.Buffer{}
+	stream := NewStream(buf, 10)
+	stream.WriteRaw("abcdefg")
+	stream.WriteFloat32(1.123456)
+	stream.Flush()
+	should.Nil(stream.Error)
+	should.Equal("abcdefg1.123456", buf.String())
+}
+
 func Benchmark_jsoniter_float(b *testing.B) {
 	b.ReportAllocs()
 	for n := 0; n < b.N; n++ {

+ 16 - 0
stream.go

@@ -104,7 +104,22 @@ func (b *Stream) Flush() error {
 	return nil
 }
 
+func (b *Stream) WriteRaw(s string) {
+	for len(s) > b.Available() && b.Error == nil {
+		n := copy(b.buf[b.n:], s)
+		b.n += n
+		s = s[n:]
+		b.Flush()
+	}
+	if b.Error != nil {
+		return
+	}
+	n := copy(b.buf[b.n:], s)
+	b.n += n
+}
+
 func (b *Stream) WriteString(s string) {
+	b.writeByte('"')
 	for len(s) > b.Available() && b.Error == nil {
 		n := copy(b.buf[b.n:], s)
 		b.n += n
@@ -116,6 +131,7 @@ func (b *Stream) WriteString(s string) {
 	}
 	n := copy(b.buf[b.n:], s)
 	b.n += n
+	b.writeByte('"')
 }
 
 func (stream *Stream) WriteNull() {