goprotobuf: Write C++-compatible ±Inf and NaN floats in text format.
R=r
CC=golang-dev
https://codereview.appspot.com/10113046
diff --git a/proto/text.go b/proto/text.go
index 8c39b8a..ff8a0bb 100644
--- a/proto/text.go
+++ b/proto/text.go
@@ -39,6 +39,7 @@
"fmt"
"io"
"log"
+ "math"
"os"
"reflect"
"sort"
@@ -55,6 +56,9 @@
backslashT = []byte{'\\', 't'}
backslashDQ = []byte{'\\', '"'}
backslashBS = []byte{'\\', '\\'}
+ posInf = []byte("inf")
+ negInf = []byte("-inf")
+ nan = []byte("nan")
)
type writer interface {
@@ -292,8 +296,27 @@
func writeAny(w *textWriter, v reflect.Value, props *Properties) error {
v = reflect.Indirect(v)
+ // Floats have special cases.
+ if v.Kind() == reflect.Float32 || v.Kind() == reflect.Float64 {
+ x := v.Float()
+ var b []byte
+ switch {
+ case math.IsInf(x, 1):
+ b = posInf
+ case math.IsInf(x, -1):
+ b = negInf
+ case math.IsNaN(x):
+ b = nan
+ }
+ if b != nil {
+ _, err := w.Write(b)
+ return err
+ }
+ // Other values are handled below.
+ }
+
// We don't attempt to serialise every possible value type; only those
- // that can occur in protocol buffers, plus a few extra that were easy.
+ // that can occur in protocol buffers.
switch v.Kind() {
case reflect.Slice:
// Should only be a []byte; repeated fields are handled in writeStruct.