fix map decode error #259
diff --git a/decode.go b/decode.go
index b916703..ad08db5 100644
--- a/decode.go
+++ b/decode.go
@@ -33,7 +33,6 @@
reader *bufio.Reader
refs []interface{}
// record type refs, both list and map need it
- // todo: map
typeRefs *TypeRefs
classInfoList []*classInfo
isSkip bool
@@ -162,36 +161,48 @@
}
// read the type of data, used to decode list or map
-func (d *Decoder) decType() (string, error) {
+func (d *Decoder) decMapType() (reflect.Type, error) {
var (
- err error
- arr [1]byte
- buf []byte
- tag byte
- idx int32
- typ reflect.Type
+ err error
+ arr [1]byte
+ buf []byte
+ tag byte
+ idx int32
+ typ reflect.Type
+ typName string
)
buf = arr[:1]
if _, err = io.ReadFull(d.reader, buf); err != nil {
- return "", perrors.WithStack(err)
+ return nil, perrors.WithStack(err)
}
tag = buf[0]
if (tag >= BC_STRING_DIRECT && tag <= STRING_DIRECT_MAX) ||
(tag >= 0x30 && tag <= 0x33) || (tag == BC_STRING) || (tag == BC_STRING_CHUNK) {
- return d.decString(int32(tag))
+ typName, err = d.decString(int32(tag))
+ if err != nil {
+ return nil, perrors.WithStack(err)
+ }
+ info, ok := getStructInfo(typName)
+ if ok {
+ typ = info.typ
+ } else {
+ typ = reflect.TypeOf(map[interface{}]interface{}{})
+ }
+ d.typeRefs.appendTypeRefs(typName, typ)
+ return typ, nil
}
if idx, err = d.decInt32(int32(tag)); err != nil {
- return "", perrors.WithStack(err)
+ return nil, perrors.WithStack(err)
}
- typ, _, err = d.getStructDefByIndex(int(idx))
- if err == nil {
- return typ.String(), nil
+ typ = d.typeRefs.Get(int(idx))
+ if typ == nil {
+ return nil, perrors.Errorf("the type ref index %d is out of range", idx)
}
- return "", err
+ return typ, err
}
// Decode parse hessian data, and ensure the reflection value unpacked
diff --git a/decode_test.go b/decode_test.go
index 3c4dd95..0e57f45 100644
--- a/decode_test.go
+++ b/decode_test.go
@@ -110,7 +110,7 @@
func testDecodeJavaData(t *testing.T, method, className string, skip bool, expected interface{}) {
r, e := decodeJavaResponse(method, className, skip)
if e != nil {
- t.Errorf("%s: decode fail with error %v", method, e)
+ t.Errorf("%s: decode fail with error: %v", method, e)
return
}
diff --git a/map.go b/map.go
index 0d83d4e..dc7a235 100644
--- a/map.go
+++ b/map.go
@@ -217,7 +217,7 @@
return nil
}
-// TODO to decode ref object in map
+// decode map object
func (d *Decoder) decMap(flag int32) (interface{}, error) {
var (
err error
@@ -231,6 +231,7 @@
instValue reflect.Value
fieldName string
fieldValue reflect.Value
+ typ reflect.Type
)
if flag != TAG_READ {
@@ -245,67 +246,48 @@
case tag == BC_REF:
return d.decRef(int32(tag))
case tag == BC_MAP:
- if t, err = d.decType(); err != nil {
+ if typ, err = d.decMapType(); err != nil {
return nil, err
}
- _, ok = checkPOJORegistry(t)
- if ok {
- inst = createInstance(t)
- instValue = reflect.ValueOf(inst)
- d.appendRefs(inst)
- for d.peekByte() != BC_END {
- k, err = d.Decode()
- if err != nil {
- return nil, err
- }
- v, err = d.Decode()
- if err != nil {
- return nil, err
- }
+ if typ.Kind() == reflect.Map {
+ instValue = reflect.MakeMap(typ)
+ } else {
+ instValue = reflect.New(typ).Elem()
+ }
+ inst = instValue.Interface()
+
+ d.typeRefs.appendTypeRefs(t, typ)
+ d.appendRefs(inst)
+ for d.peekByte() != BC_END {
+ k, err = d.Decode()
+ if err != nil {
+ return nil, err
+ }
+ v, err = d.Decode()
+ if err != nil {
+ return nil, err
+ }
+
+ if typ.Kind() == reflect.Map {
+ instValue.SetMapIndex(reflect.ValueOf(k), EnsureRawValue(v))
+ } else {
fieldName, ok = k.(string)
if !ok {
return nil, perrors.Errorf("the type of map key must be string, but get %v", k)
}
- if instValue.Kind() == reflect.Map {
- instValue.SetMapIndex(reflect.ValueOf(k), EnsureRawValue(v))
- } else {
- fieldValue = instValue.FieldByName(fieldName)
- if fieldValue.IsValid() {
- fieldValue.Set(EnsureRawValue(v))
- }
+ fieldValue = instValue.FieldByName(fieldName)
+ if fieldValue.IsValid() {
+ fieldValue.Set(EnsureRawValue(v))
}
}
- _, err = d.ReadByte()
- if err != nil {
- return nil, perrors.WithStack(err)
- }
- return inst, nil
- } else {
- m = make(map[interface{}]interface{})
- classIndex := RegisterPOJOMapping(t, m)
- d.appendClsDef(pojoRegistry.classInfoList[classIndex])
-
- d.appendRefs(m)
- for d.peekByte() != BC_END {
- k, err = d.Decode()
- if err != nil {
- return nil, err
- }
- v, err = d.Decode()
- if err != nil {
- return nil, err
- }
- m[k] = v
- }
- _, err = d.ReadByte()
- if err != nil {
- return nil, perrors.WithStack(err)
- }
- return m, nil
}
-
+ _, err = d.ReadByte()
+ if err != nil {
+ return nil, perrors.WithStack(err)
+ }
+ return inst, nil
case tag == BC_MAP_UNTYPED:
m = make(map[interface{}]interface{})
d.appendRefs(m)
diff --git a/object.go b/object.go
index 0172162..b4fe854 100644
--- a/object.go
+++ b/object.go
@@ -22,9 +22,7 @@
"reflect"
"strings"
"sync"
-)
-import (
perrors "github.com/pkg/errors"
)
@@ -376,6 +374,10 @@
}
func (d *Decoder) decInstance(typ reflect.Type, cls *classInfo) (interface{}, error) {
+ //if typ.Kind() == reflect.Map {
+ // return d.decTypeMap(typ)
+ //}
+
if typ.Kind() != reflect.Struct {
return nil, perrors.Errorf("wrong type expect Struct but get:%s", typ.String())
}
diff --git a/serialize_test.go b/serialize_test.go
index 4d602c5..4ba4148 100644
--- a/serialize_test.go
+++ b/serialize_test.go
@@ -165,6 +165,23 @@
}
}
+func TestCustomReplyObjectJsonObjectBigDecimalDecode(t *testing.T) {
+ decimal := &big.Decimal{}
+ _ = decimal.FromString("100")
+
+ out, err := decodeJavaResponse(`customReplyObjectJsonObjectBigDecimal`, ``, false)
+ if err != nil {
+ t.Error(err)
+ return
+ }
+
+ res := out.(map[interface{}]interface{})
+ assert.Equal(t, 1, len(res))
+
+ dec := res["test_BigDecimal"].(*big.Decimal)
+ assert.Equal(t, decimal.String(), dec.String())
+}
+
func TestObjectListGoDecode(t *testing.T) {
data := []string{
"1234",
diff --git a/test_hessian/src/main/java/test/TestCustomReply.java b/test_hessian/src/main/java/test/TestCustomReply.java
index be212ac..1e22922 100644
--- a/test_hessian/src/main/java/test/TestCustomReply.java
+++ b/test_hessian/src/main/java/test/TestCustomReply.java
@@ -419,6 +419,15 @@
output.flush();
}
+ public void customReplyObjectJsonObjectBigDecimal() throws Exception {
+ //TestJsonObject t = new TestJsonObject();
+ JSONObject t = new JSONObject();
+ BigDecimal decimal = new BigDecimal("100");
+ t.put("test_BigDecimal",decimal);
+ output.writeObject(t);
+ output.flush();
+ }
+
public void customReplyTypedFixedDateNull() throws Exception {
DateDemo demo = new DateDemo("zhangshan", null, null);
output.writeObject(demo);
@@ -567,3 +576,4 @@
public String name;
public Integer age;
}
+