Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix decoding error for map in map #229

Merged
merged 3 commits into from
Sep 7, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 10 additions & 3 deletions map.go
Original file line number Diff line number Diff line change
Expand Up @@ -268,9 +268,13 @@ func (d *Decoder) decMap(flag int32) (interface{}, error) {
if !ok {
return nil, perrors.Errorf("the type of map key must be string, but get %v", k)
}
fieldValue = instValue.FieldByName(fieldName)
if fieldValue.IsValid() {
fieldValue.Set(EnsureRawValue(v))
if instValue.Kind() == reflect.Map {
instValue.SetMapIndex(reflect.ValueOf(k), EnsureRawValue(v))
} else {
fieldValue = instValue.FieldByName(fieldName)
if fieldValue.IsValid() {
fieldValue.Set(EnsureRawValue(v))
}
}
}
_, err = d.readByte()
Expand All @@ -280,6 +284,9 @@ func (d *Decoder) decMap(flag int32) (interface{}, error) {
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()
Expand Down
11 changes: 11 additions & 0 deletions map_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,3 +96,14 @@ func TestMapEncode(t *testing.T) {
testJavaDecode(t, "argUntypedMap_1", map[interface{}]interface{}{"a": int32(0)})
testJavaDecode(t, "argUntypedMap_2", map[interface{}]interface{}{int32(0): "a", int32(1): "b"})
}

func TestCustomMap(t *testing.T) {
testDecodeFramework(t, "customReplyMap", map[interface{}]interface{}{"a": int32(1), "b": int32(2)})

mapInMap := map[interface{}]interface{}{
"obj1": map[interface{}]interface{}{"a": int32(1)},
"obj2": map[interface{}]interface{}{"b": int32(2)},
}
testDecodeFramework(t, "customReplyMapInMap", mapInMap)
testDecodeFramework(t, "customReplyMapInMapJsonObject", mapInMap)
}
77 changes: 43 additions & 34 deletions pojo.go
Original file line number Diff line number Diff line change
Expand Up @@ -115,17 +115,22 @@ func showPOJORegistry() {

// RegisterPOJO Register a POJO instance. The return value is -1 if @o has been registered.
func RegisterPOJO(o POJO) int {
return RegisterPOJOMapping(o.JavaClassName(), o)
}

// RegisterPOJOMapping Register a POJO instance. The return value is -1 if @o has been registered.
func RegisterPOJOMapping(javaClassName string, o interface{}) int {
// # definition for an object (compact map)
// class-def ::= 'C' string int string*
pojoRegistry.Lock()
defer pojoRegistry.Unlock()

if goName, ok := pojoRegistry.j2g[o.JavaClassName()]; ok {
if goName, ok := pojoRegistry.j2g[javaClassName]; ok {
return pojoRegistry.registry[goName].index
}

// JavaClassName shouldn't equal to goName
if _, ok := pojoRegistry.registry[o.JavaClassName()]; ok {
if _, ok := pojoRegistry.registry[javaClassName]; ok {
return -1
}

Expand All @@ -140,7 +145,7 @@ func RegisterPOJO(o POJO) int {
structInfo.typ = obtainValueType(o)

structInfo.goName = structInfo.typ.String()
structInfo.javaName = o.JavaClassName()
structInfo.javaName = javaClassName
structInfo.inst = o
pojoRegistry.j2g[structInfo.javaName] = structInfo.goName
registerTypeName(structInfo.goName, structInfo.javaName)
Expand All @@ -149,37 +154,37 @@ func RegisterPOJO(o POJO) int {
nextStruct := []reflect.Type{structInfo.typ}
for len(nextStruct) > 0 {
current := nextStruct[0]

for i := 0; i < current.NumField(); i++ {

// skip unexported anonymous filed
if current.Field(i).PkgPath != "" {
continue
}

structField := current.Field(i)

// skip ignored field
tagVal, hasTag := structField.Tag.Lookup(tagIdentifier)
if tagVal == `-` {
continue
if current.Kind() == reflect.Struct {
for i := 0; i < current.NumField(); i++ {
// skip unexported anonymous filed
if current.Field(i).PkgPath != "" {
continue
}

structField := current.Field(i)

// skip ignored field
tagVal, hasTag := structField.Tag.Lookup(tagIdentifier)
if tagVal == `-` {
continue
}

// flat anonymous field
if structField.Anonymous && structField.Type.Kind() == reflect.Struct {
nextStruct = append(nextStruct, structField.Type)
continue
}

var fieldName string
if hasTag {
fieldName = tagVal
} else {
fieldName = lowerCamelCase(structField.Name)
}

fieldList = append(fieldList, fieldName)
bBody = encString(bBody, fieldName)
}

// flat anonymous field
if structField.Anonymous && structField.Type.Kind() == reflect.Struct {
nextStruct = append(nextStruct, structField.Type)
continue
}

var fieldName string
if hasTag {
fieldName = tagVal
} else {
fieldName = lowerCamelCase(structField.Name)
}

fieldList = append(fieldList, fieldName)
bBody = encString(bBody, fieldName)
}

nextStruct = nextStruct[1:]
Expand Down Expand Up @@ -235,7 +240,7 @@ func unRegisterPOJO(o POJO) int {
return -1
}

func obtainValueType(o POJO) reflect.Type {
func obtainValueType(o interface{}) reflect.Type {
v := reflect.ValueOf(o)
switch v.Kind() {
case reflect.Struct:
Expand Down Expand Up @@ -385,6 +390,10 @@ func createInstance(goName string) interface{} {
return nil
}

if s.typ.Kind() == reflect.Map {
return reflect.MakeMap(s.typ).Interface()
}

return reflect.New(s.typ).Interface()
}

Expand Down
5 changes: 5 additions & 0 deletions test_hessian/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,11 @@
<artifactId>dubbo</artifactId>
<version>2.6.5</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.70</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
Expand Down
80 changes: 57 additions & 23 deletions test_hessian/src/main/java/test/TestCustomReply.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,26 +18,29 @@
package test;

import com.alibaba.com.caucho.hessian.io.Hessian2Output;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.caucho.hessian.test.A0;
import com.caucho.hessian.test.A1;
import test.model.DateDemo;

import java.io.OutputStream;
import java.io.Serializable;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import test.model.DateDemo;


public class TestCustomReply {

private Hessian2Output output;
private HashMap<Class<?>, String> typeMap;

TestCustomReply(OutputStream os) {
public TestCustomReply(OutputStream os) {
output = new Hessian2Output(os);

typeMap = new HashMap<>();
Expand Down Expand Up @@ -355,32 +358,32 @@ public void customReplyTypedFixedInteger() throws Exception {
}

public void customReplyTypedFixedList_BigInteger() throws Exception {
BigInteger[] integers = new BigInteger[] {
new BigInteger("1234"),
new BigInteger("12347890"),
new BigInteger("123478901234"),
new BigInteger("1234789012345678"),
new BigInteger("123478901234567890"),
new BigInteger("1234789012345678901234"),
new BigInteger("12347890123456789012345678"),
new BigInteger("123478901234567890123456781234"),
new BigInteger("1234789012345678901234567812345678"),
new BigInteger("12347890123456789012345678123456781234"),
new BigInteger("-12347890123456789012345678123456781234"),
new BigInteger("0"),
BigInteger[] integers = new BigInteger[]{
new BigInteger("1234"),
new BigInteger("12347890"),
new BigInteger("123478901234"),
new BigInteger("1234789012345678"),
new BigInteger("123478901234567890"),
new BigInteger("1234789012345678901234"),
new BigInteger("12347890123456789012345678"),
new BigInteger("123478901234567890123456781234"),
new BigInteger("1234789012345678901234567812345678"),
new BigInteger("12347890123456789012345678123456781234"),
new BigInteger("-12347890123456789012345678123456781234"),
new BigInteger("0"),
};
output.writeObject(integers);
output.flush();
}

public void customReplyTypedFixedList_CustomObject() throws Exception {
Object[] objects = new Object[] {
new BigInteger("1234"),
new BigInteger("-12347890"),
new BigInteger("0"),
new BigDecimal("123.4"),
new BigDecimal("-123.45"),
new BigDecimal("0"),
Object[] objects = new Object[]{
new BigInteger("1234"),
new BigInteger("-12347890"),
new BigInteger("0"),
new BigDecimal("123.4"),
new BigDecimal("-123.45"),
new BigDecimal("0"),
};
output.writeObject(objects);
output.flush();
Expand Down Expand Up @@ -473,6 +476,37 @@ public void customReplyTypedFixedList_HashSetCustomObject() throws Exception {
output.writeObject(set);
output.flush();
}

public void customReplyMap() throws Exception {
Map<String, Object> map = new HashMap<String, Object>(4);
map.put("a", 1);
map.put("b", 2);
output.writeObject(map);
output.flush();
}

public Map<String, Object> mapInMap() throws Exception {
Map<String, Object> map1 = new HashMap<String, Object>();
map1.put("a", 1);
Map<String, Object> map2 = new HashMap<String, Object>();
map2.put("b", 2);

Map<String, Object> map = new HashMap<String, Object>();
map.put("obj1", map1);
map.put("obj2", map2);
return map;
}

public void customReplyMapInMap() throws Exception {
output.writeObject(mapInMap());
output.flush();
}

public void customReplyMapInMapJsonObject() throws Exception {
JSONObject json = JSON.parseObject(JSON.toJSONString(mapInMap()));
output.writeObject(json);
output.flush();
}
}

interface Leg {
Expand Down