Merge branch 'philpearl-master'

This commit is contained in:
Alexandr Mayorskiy
2020-04-12 18:19:16 +03:00
3 changed files with 66 additions and 0 deletions
+20
View File
@@ -6,6 +6,7 @@ import (
"io/ioutil"
"net/http"
"strconv"
"unsafe"
"github.com/mailru/easyjson/jlexer"
"github.com/mailru/easyjson/jwriter"
@@ -36,9 +37,17 @@ type UnknownsMarshaler interface {
MarshalUnknowns(w *jwriter.Writer, first bool)
}
func isNilInterface(i interface{}) bool {
return (*[2]uintptr)(unsafe.Pointer(&i))[1] == 0
}
// Marshal returns data as a single byte slice. Method is suboptimal as the data is likely to be copied
// from a chain of smaller chunks.
func Marshal(v Marshaler) ([]byte, error) {
if isNilInterface(v) {
return nullBytes, nil
}
w := jwriter.Writer{}
v.MarshalEasyJSON(&w)
return w.BuildBytes()
@@ -46,6 +55,10 @@ func Marshal(v Marshaler) ([]byte, error) {
// MarshalToWriter marshals the data to an io.Writer.
func MarshalToWriter(v Marshaler, w io.Writer) (written int, err error) {
if isNilInterface(v) {
return w.Write(nullBytes)
}
jw := jwriter.Writer{}
v.MarshalEasyJSON(&jw)
return jw.DumpTo(w)
@@ -56,6 +69,13 @@ func MarshalToWriter(v Marshaler, w io.Writer) (written int, err error) {
// false if an error occurred before any http.ResponseWriter methods were actually
// invoked (in this case a 500 reply is possible).
func MarshalToHTTPResponseWriter(v Marshaler, w http.ResponseWriter) (started bool, written int, err error) {
if isNilInterface(v) {
w.Header().Set("Content-Type", "application/json")
w.Header().Set("Content-Length", strconv.Itoa(len(nullBytes)))
written, err = w.Write(nullBytes)
return true, written, err
}
jw := jwriter.Writer{}
v.MarshalEasyJSON(&jw)
if jw.Error != nil {
+12
View File
@@ -0,0 +1,12 @@
package easyjson
import "testing"
func BenchmarkNilCheck(b *testing.B) {
var a *int
for i := 0; i < b.N; i++ {
if !isNilInterface(a) {
b.Fatal("expected it to be nil")
}
}
}
+34
View File
@@ -1,6 +1,8 @@
package tests
import (
"bytes"
"net/http/httptest"
"reflect"
"testing"
@@ -267,3 +269,35 @@ func TestMethodsNoGenerated(t *testing.T) {
}
}
}
func TestNil(t *testing.T) {
var p *PrimitiveTypes
data, err := easyjson.Marshal(p)
if err != nil {
t.Errorf("easyjson.Marshal() error: %v", err)
}
if string(data) != "null" {
t.Errorf("Wanted null, got %q", string(data))
}
var b bytes.Buffer
if n, err := easyjson.MarshalToWriter(p, &b); err != nil || n != 4 {
t.Errorf("easyjson.MarshalToWriter() error: %v, written %d", err, n)
}
if s := b.String(); s != "null" {
t.Errorf("Wanted null, got %q", s)
}
w := httptest.NewRecorder()
started, written, err := easyjson.MarshalToHTTPResponseWriter(p, w)
if !started || written != 4 || err != nil {
t.Errorf("easyjson.MarshalToHTTPResponseWriter() error: %v, written %d, started %t",
err, written, started)
}
if s := w.Body.String(); s != "null" {
t.Errorf("Wanted null, got %q", s)
}
}