summaryrefslogtreecommitdiff
path: root/borrowed_misc.go
diff options
context:
space:
mode:
Diffstat (limited to 'borrowed_misc.go')
-rw-r--r--borrowed_misc.go43
1 files changed, 43 insertions, 0 deletions
diff --git a/borrowed_misc.go b/borrowed_misc.go
index 59c49aa..52f4a12 100644
--- a/borrowed_misc.go
+++ b/borrowed_misc.go
@@ -7,7 +7,10 @@
package lowmemjson
import (
+ "io"
+ "math"
"reflect"
+ "strconv"
)
// isEmptyValue is borrowed from encode.go.
@@ -28,3 +31,43 @@ func isEmptyValue(v reflect.Value) bool {
}
return false
}
+
+// encodeFloat is lightly modified from
+// encode.go:floatEncoder.encode().
+func encodeFloat(w io.Writer, bits int, v reflect.Value) error {
+ var scratch [64]byte
+
+ f := v.Float()
+ if math.IsInf(f, 0) || math.IsNaN(f) {
+ return &EncodeValueError{Value: v, Str: strconv.FormatFloat(f, 'g', -1, bits)}
+ }
+
+ // Convert as if by ES6 number to string conversion.
+ // This matches most other JSON generators.
+ // See golang.org/issue/6384 and golang.org/issue/14135.
+ // Like fmt %g, but the exponent cutoffs are different
+ // and exponents themselves are not padded to two digits.
+ b := scratch[:0]
+ abs := math.Abs(f)
+ fmt := byte('f')
+ // Note: Must use float32 comparisons for underlying float32 value to get precise cutoffs right.
+ if abs != 0 {
+ if bits == 64 && (abs < 1e-6 || abs >= 1e21) || bits == 32 && (float32(abs) < 1e-6 || float32(abs) >= 1e21) {
+ fmt = 'e'
+ }
+ }
+ b = strconv.AppendFloat(b, f, fmt, -1, bits)
+ if fmt == 'e' {
+ // clean up e-09 to e-9
+ n := len(b)
+ if n >= 4 && b[n-4] == 'e' && b[n-3] == '-' && b[n-2] == '0' {
+ b[n-2] = b[n-1]
+ b = b[:n-1]
+ }
+ }
+
+ if _, err := w.Write(b); err != nil {
+ return err
+ }
+ return nil
+}