feat: support java null encoding
diff --git a/encode.go b/encode.go
index fb1fc28..e7fe4f3 100644
--- a/encode.go
+++ b/encode.go
@@ -36,6 +36,7 @@
classInfoList []*ClassInfo
buffer []byte
refMap map[unsafe.Pointer]_refElem
+ config *EncoderConfig
}
// classIndex find the index of the given java name in encoder class info list.
@@ -49,12 +50,32 @@
}
// NewEncoder generate an encoder instance
-func NewEncoder() *Encoder {
+func NewEncoder(opts ...EncoderOption) *Encoder {
buffer := make([]byte, 64)
+ config := &EncoderConfig{}
+ for _, opt := range opts {
+ opt(config)
+ }
return &Encoder{
buffer: buffer[:0],
refMap: make(map[unsafe.Pointer]_refElem, 7),
+ config: config,
+ }
+}
+
+// EncoderConfig config for encoder
+type EncoderConfig struct {
+ JavaNullCompatible bool
+}
+
+// EncoderOption inject configuration into encoder
+type EncoderOption func(*EncoderConfig)
+
+// WithJavaNullCompatible configuring java null compatible for encoder
+func WithJavaNullCompatible() EncoderOption {
+ return func(config *EncoderConfig) {
+ config.JavaNullCompatible = true
}
}
@@ -94,7 +115,13 @@
// Encode If @v can not be encoded, the return value is nil. At present only struct may can not be encoded.
func (e *Encoder) Encode(v interface{}) error {
- if v == nil {
+ if e.config.JavaNullCompatible {
+ vv := reflect.ValueOf(v)
+ if vv.Kind() == reflect.Ptr && vv.IsNil() {
+ e.buffer = EncNull(e.buffer)
+ return nil
+ }
+ } else if v == nil {
e.buffer = EncNull(e.buffer)
return nil
}
diff --git a/null_test.go b/null_test.go
index 2e0bab8..0881ae1 100644
--- a/null_test.go
+++ b/null_test.go
@@ -34,6 +34,18 @@
testDecodeFramework(t, "replyNull", nil)
}
-func TestNulEncode(t *testing.T) {
+func TestNullEncode(t *testing.T) {
testJavaDecode(t, "argNull", nil)
}
+
+func TestNullCompatibleEncode(t *testing.T) {
+ e := NewEncoder(
+ WithJavaNullCompatible(),
+ )
+ var null *int = nil
+ e.Encode(null)
+ if e.Buffer() == nil {
+ t.Fail()
+ }
+ assertEqual([]byte("N"), e.buffer, t)
+}