Merge remote-tracking branch 'origin/master'
diff --git a/src/main/java/com/alibaba/com/caucho/hessian/io/Hessian2Input.java b/src/main/java/com/alibaba/com/caucho/hessian/io/Hessian2Input.java
index 749ad91..6bac79e 100644
--- a/src/main/java/com/alibaba/com/caucho/hessian/io/Hessian2Input.java
+++ b/src/main/java/com/alibaba/com/caucho/hessian/io/Hessian2Input.java
@@ -114,9 +114,6 @@
private boolean _isStreaming;
// the method for a call
private String _method;
- private int _argLength;
- private Reader _chunkReader;
- private InputStream _chunkInputStream;
private Throwable _replyFault;
private StringBuilder _sbuf = new StringBuilder();
// true if this is the last chunk
@@ -185,14 +182,37 @@
}
@Override
+ public void init(InputStream is) {
+ _is = is;
+
+ reset();
+ }
+
+ public void reset() {
+ resetReferences();
+
+ if (_classDefs != null) {
+ _classDefs.clear();
+ }
+
+ if (_types != null) {
+ _types.clear();
+ }
+
+ _offset = 0;
+ _length = 0;
+ }
+
+ @Override
public boolean checkAndReadNull() {
try {
- int tmp_offset = _offset;
int tag = read();
if ('N' == tag) {
return true;
}
- _offset = tmp_offset;
+ if (-1 != tag) {
+ _offset--;
+ }
} catch (IOException ignored) {
}
return false;
@@ -455,12 +475,9 @@
throws IOException {
int tag = read();
- if (tag == 'p')
- _isStreaming = false;
- else if (tag == 'P')
- _isStreaming = true;
- else
+ if (tag != 'p' && tag != 'P') {
throw error("expected Hessian message ('p') at " + codeName(tag));
+ }
int major = read();
int minor = read();
@@ -3393,7 +3410,10 @@
_isLastChunk = true;
_chunkLength = tag - 0x20;
break;
- case 0x34: case 0x35: case 0x36: case 0x37:
+ case 0x34:
+ case 0x35:
+ case 0x36:
+ case 0x37:
_isLastChunk = true;
_chunkLength = (tag - 0x34) * 256 + read();
break;
@@ -3451,7 +3471,10 @@
_isLastChunk = true;
_chunkLength = code - 0x20;
break;
- case 0x34: case 0x35: case 0x36: case 0x37:
+ case 0x34:
+ case 0x35:
+ case 0x36:
+ case 0x37:
_isLastChunk = true;
_chunkLength = (code - 0x34) * 256 + read();
break;
diff --git a/src/main/java/com/alibaba/com/caucho/hessian/io/Hessian2Output.java b/src/main/java/com/alibaba/com/caucho/hessian/io/Hessian2Output.java
index 3eb98b5..c4a6850 100644
--- a/src/main/java/com/alibaba/com/caucho/hessian/io/Hessian2Output.java
+++ b/src/main/java/com/alibaba/com/caucho/hessian/io/Hessian2Output.java
@@ -101,6 +101,30 @@
_os = os;
}
+ @Override
+ public void init(OutputStream os) {
+ reset();
+
+ _os = os;
+ }
+
+ /**
+ * Resets all counters and references
+ */
+ public void reset() {
+ resetReferences();
+
+ if (_classRefs != null) {
+ _classRefs.clear();
+ }
+
+ if (_typeRefs != null) {
+ _typeRefs.clear();
+ }
+
+ _offset = 0;
+ }
+
public boolean isCloseStreamOnClose() {
return _isCloseStreamOnClose;
}
@@ -384,10 +408,7 @@
return;
}
- Serializer serializer;
-
- serializer = findSerializerFactory().getSerializer(object.getClass());
-
+ Serializer serializer = findSerializerFactory().getSerializer(object.getClass());
serializer.writeObject(object, this);
}
diff --git a/src/test/java/com/alibaba/com/caucho/hessian/io/Hessian2ReuseTest.java b/src/test/java/com/alibaba/com/caucho/hessian/io/Hessian2ReuseTest.java
new file mode 100644
index 0000000..6e71b91
--- /dev/null
+++ b/src/test/java/com/alibaba/com/caucho/hessian/io/Hessian2ReuseTest.java
@@ -0,0 +1,154 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.alibaba.com.caucho.hessian.io;
+
+import com.alibaba.com.caucho.hessian.io.base.SerializeTestBase;
+import com.alibaba.com.caucho.hessian.io.beans.*;
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.util.*;
+import java.util.concurrent.ThreadLocalRandom;
+
+public class Hessian2ReuseTest extends SerializeTestBase {
+
+ private static final Hessian2Input h2i = new Hessian2Input(null);
+
+ private static final Hessian2Output h2o = new Hessian2Output(null);
+
+ @SuppressWarnings("unchecked")
+ private static <T> T serializeAndDeserialize(T obj, Class<T> clazz) throws IOException {
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ h2o.init(outputStream);
+ h2o.writeObject(obj);
+ h2o.flush();
+
+ h2i.init(new ByteArrayInputStream(outputStream.toByteArray()));
+ return (T) h2i.readObject(clazz);
+ }
+
+ @Test
+ public void testString() throws IOException {
+ for (int i = 0; i < 100; i++) {
+ String obj = "Hello, Hessian2, round:" + i;
+
+ String newObj = serializeAndDeserialize(obj, String.class);
+ Assert.assertEquals(obj, newObj);
+
+ String newObj2 = baseHessian2Serialize(obj);
+ Assert.assertEquals(newObj, newObj2);
+ }
+ }
+
+ @Test
+ public void testDate() throws IOException {
+ long mills = System.currentTimeMillis();
+ serializeAndDeserialize(new Date(mills), Date.class);
+ serializeAndDeserialize(new Date(mills + 1000_000), Date.class);
+ }
+
+ @Test
+ public void testBaseUser() throws IOException {
+ for (int i = 0; i < 100; i++) {
+ BaseUser obj = new BaseUser();
+ obj.setUserId(i * ThreadLocalRandom.current().nextInt(10000));
+ obj.setUserName(String.valueOf(System.currentTimeMillis()));
+
+ BaseUser newObj = serializeAndDeserialize(obj, BaseUser.class);
+ Assert.assertEquals(obj, newObj);
+
+ BaseUser newObj2 = baseHessian2Serialize(obj);
+ Assert.assertEquals(newObj, newObj2);
+ }
+ }
+
+ @Test
+ public void testSubUser() throws IOException {
+ for (int i = 0; i < 100; i++) {
+ SubUser obj = new SubUser();
+ obj.setUserId(i * ThreadLocalRandom.current().nextInt(10000));
+ obj.setUserName(String.valueOf(System.currentTimeMillis()));
+ obj.setAgeList(Arrays.asList(12, 13, 14, 15));
+ obj.setSexyList(Arrays.asList(true, false));
+ obj.setWeightList(Arrays.asList(120D, 130D, 140D));
+
+ SubUser newObj = serializeAndDeserialize(obj, SubUser.class);
+ Assert.assertEquals(obj, newObj);
+
+ SubUser newObj2 = baseHessian2Serialize(obj);
+ Assert.assertEquals(newObj, newObj2);
+ }
+ }
+
+ @Test
+ public void testGrandsonUser() throws IOException {
+ for (int i = 0; i < 100; i++) {
+ GrandsonUser obj = new GrandsonUser();
+ obj.setUserId(i * ThreadLocalRandom.current().nextInt(10000));
+ obj.setUserName(String.valueOf(System.currentTimeMillis()));
+ obj.setAgeList(Arrays.asList(12, 13, 14, 15));
+ obj.setSexyList(Arrays.asList(true, false));
+ obj.setWeightList(Arrays.asList(120D, 130D, 140D));
+
+ SubUser newObj = serializeAndDeserialize(obj, SubUser.class);
+ Assert.assertEquals(obj, newObj);
+
+ SubUser newObj2 = baseHessian2Serialize(obj);
+ Assert.assertEquals(newObj, newObj2);
+ }
+ }
+
+ @Test
+ public void testType() throws IOException {
+ serializeAndDeserialize(Type.Lower, Type.class);
+ serializeAndDeserialize(Type.Normal, Type.class);
+ serializeAndDeserialize(Type.High, Type.class);
+ }
+
+ @Test
+ public void testHessian2StringShortType() throws IOException {
+ for (int i = 0; i < 100; i++) {
+ Hessian2StringShortType obj = new Hessian2StringShortType();
+ obj.shortSet = new HashSet<>();
+ obj.stringShortMap = new HashMap<>();
+ obj.stringByteMap = new HashMap<>();
+ obj.stringPersonTypeMap = new HashMap<>();
+
+ obj.shortSet.add((short) i);
+ obj.shortSet.add((short) (i * 2));
+
+// shortType.stringShortMap.put(String.valueOf(i), (short) i);
+// shortType.stringShortMap.put(String.valueOf(i * 100), (short) (i * 100));
+
+// shortType.stringByteMap.put(String.valueOf(i), (byte) 1);
+
+ List<Short> shorts = Arrays.asList((short) 12, (short) 4);
+ PersonType abc = new PersonType("ABC", 12, 128D, (short) 1, (byte) 2, shorts);
+ obj.stringPersonTypeMap.put("P_" + i, abc);
+
+ Hessian2StringShortType newObj = serializeAndDeserialize(obj, Hessian2StringShortType.class);
+ Assert.assertEquals(obj, newObj);
+
+ Hessian2StringShortType newObj2 = baseHessian2Serialize(obj);
+ Assert.assertEquals(newObj, newObj2);
+ }
+ }
+
+}
diff --git a/src/test/java/com/alibaba/com/caucho/hessian/io/Hessian2StringShortTest.java b/src/test/java/com/alibaba/com/caucho/hessian/io/Hessian2StringShortTest.java
index d59ef71..30991f0 100644
--- a/src/test/java/com/alibaba/com/caucho/hessian/io/Hessian2StringShortTest.java
+++ b/src/test/java/com/alibaba/com/caucho/hessian/io/Hessian2StringShortTest.java
@@ -20,10 +20,12 @@
import com.alibaba.com.caucho.hessian.io.beans.Hessian2StringShortType;
import com.alibaba.com.caucho.hessian.io.beans.PersonType;
+import org.junit.Assert;
import org.junit.Test;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
+import java.io.IOException;
import java.util.*;
import static junit.framework.TestCase.assertEquals;
@@ -92,8 +94,8 @@
public void serialize_map_then_deserialize0() throws Exception {
Map<String, Short> stringShortMap = new HashMap<String, Short>();
- stringShortMap.put("first", (short)0);
- stringShortMap.put("last", (short)60);
+ stringShortMap.put("first", (short) 0);
+ stringShortMap.put("last", (short) 60);
ByteArrayOutputStream bout = new ByteArrayOutputStream();
Hessian2Output out = new Hessian2Output(bout);
@@ -112,8 +114,8 @@
assertTrue(deserialize != null);
assertTrue(deserialize.size() == 2);
assertTrue(deserialize.get("last") instanceof Short);
- assertEquals(Short.valueOf((short)0), deserialize.get("first"));
- assertEquals(Short.valueOf((short)60), deserialize.get("last"));
+ assertEquals(Short.valueOf((short) 0), deserialize.get("first"));
+ assertEquals(Short.valueOf((short) 60), deserialize.get("last"));
}
@Test
@@ -181,8 +183,8 @@
public void serialize_list_then_deserialize0() throws Exception {
List<Short> shortList = new ArrayList<Short>();
- shortList.add((short)0);
- shortList.add((short)60);
+ shortList.add((short) 0);
+ shortList.add((short) 60);
ByteArrayOutputStream bout = new ByteArrayOutputStream();
Hessian2Output out = new Hessian2Output(bout);
@@ -200,8 +202,8 @@
assertTrue(deserialize != null);
assertTrue(deserialize.size() == 2);
assertTrue(deserialize.get(1) instanceof Short);
- assertEquals(Short.valueOf((short)0), deserialize.get(0));
- assertEquals(Short.valueOf((short)60), deserialize.get(1));
+ assertEquals(Short.valueOf((short) 0), deserialize.get(0));
+ assertEquals(Short.valueOf((short) 60), deserialize.get(1));
}
@Test
@@ -219,4 +221,30 @@
assertTrue(deserialize.shortSet.contains((short) 0));
assertTrue(deserialize.shortSet.contains((short) 60));
}
+
+ @Test
+ public void test_string_short_type() throws IOException {
+ for (int i = 0; i < 100; i++) {
+ Hessian2StringShortType obj = new Hessian2StringShortType();
+ obj.shortSet = new HashSet<>();
+ obj.stringShortMap = new HashMap<>();
+ obj.stringByteMap = new HashMap<>();
+ obj.stringPersonTypeMap = new HashMap<>();
+
+ obj.shortSet.add((short) i);
+ obj.shortSet.add((short) (i * 2));
+
+ obj.stringShortMap.put(String.valueOf(i), (short) i);
+ obj.stringShortMap.put(String.valueOf(i * 100), (short) (i * 100));
+ obj.stringByteMap.put(String.valueOf(i), (byte) 1);
+
+ List<Short> shorts = Arrays.asList((short) 12, (short) 4);
+ PersonType abc = new PersonType("ABC", 12, 128D, (short) 1, (byte) 2, shorts);
+ obj.stringPersonTypeMap.put("P_" + i, abc);
+
+ Hessian2StringShortType newObj = baseHessian2Serialize(obj);
+ Assert.assertEquals(obj, newObj);
+ System.out.println("ShortTypeTest.testHessian2StringShortType(): i=" + i + " passed!");
+ }
+ }
}
diff --git a/src/test/java/com/alibaba/com/caucho/hessian/io/beans/BaseUser.java b/src/test/java/com/alibaba/com/caucho/hessian/io/beans/BaseUser.java
index f0b36ce..f8914dd 100644
--- a/src/test/java/com/alibaba/com/caucho/hessian/io/beans/BaseUser.java
+++ b/src/test/java/com/alibaba/com/caucho/hessian/io/beans/BaseUser.java
@@ -17,6 +17,7 @@
package com.alibaba.com.caucho.hessian.io.beans;
import java.io.Serializable;
+import java.util.Objects;
/**
*/
@@ -40,4 +41,18 @@
public void setUserName(String userName) {
this.userName = userName;
}
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (!(o instanceof BaseUser)) return false;
+ BaseUser user = (BaseUser) o;
+ return Objects.equals(userId, user.userId) &&
+ Objects.equals(userName, user.userName);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(userId, userName);
+ }
}
diff --git a/src/test/java/com/alibaba/com/caucho/hessian/io/beans/GrandsonUser.java b/src/test/java/com/alibaba/com/caucho/hessian/io/beans/GrandsonUser.java
index c9bb635..521fbae 100644
--- a/src/test/java/com/alibaba/com/caucho/hessian/io/beans/GrandsonUser.java
+++ b/src/test/java/com/alibaba/com/caucho/hessian/io/beans/GrandsonUser.java
@@ -17,6 +17,7 @@
package com.alibaba.com.caucho.hessian.io.beans;
import java.io.Serializable;
+import java.util.Objects;
/**
*/
@@ -32,4 +33,18 @@
public void setUserName(String userName) {
this.userName = userName;
}
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (!(o instanceof GrandsonUser)) return false;
+ if (!super.equals(o)) return false;
+ GrandsonUser that = (GrandsonUser) o;
+ return Objects.equals(userName, that.userName);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(super.hashCode(), userName);
+ }
}
diff --git a/src/test/java/com/alibaba/com/caucho/hessian/io/beans/Hessian2StringShortType.java b/src/test/java/com/alibaba/com/caucho/hessian/io/beans/Hessian2StringShortType.java
index fd0df68..3a22f87 100644
--- a/src/test/java/com/alibaba/com/caucho/hessian/io/beans/Hessian2StringShortType.java
+++ b/src/test/java/com/alibaba/com/caucho/hessian/io/beans/Hessian2StringShortType.java
@@ -18,6 +18,7 @@
import java.io.Serializable;
import java.util.Map;
+import java.util.Objects;
import java.util.Set;
/**
@@ -36,4 +37,20 @@
public Hessian2StringShortType() {
}
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (!(o instanceof Hessian2StringShortType)) return false;
+ Hessian2StringShortType that = (Hessian2StringShortType) o;
+ return Objects.equals(shortSet, that.shortSet) &&
+ Objects.equals(stringShortMap, that.stringShortMap) &&
+ Objects.equals(stringByteMap, that.stringByteMap) &&
+ Objects.equals(stringPersonTypeMap, that.stringPersonTypeMap);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(shortSet, stringShortMap, stringByteMap, stringPersonTypeMap);
+ }
}
diff --git a/src/test/java/com/alibaba/com/caucho/hessian/io/beans/SubUser.java b/src/test/java/com/alibaba/com/caucho/hessian/io/beans/SubUser.java
index 7553f48..203679b 100644
--- a/src/test/java/com/alibaba/com/caucho/hessian/io/beans/SubUser.java
+++ b/src/test/java/com/alibaba/com/caucho/hessian/io/beans/SubUser.java
@@ -18,6 +18,7 @@
import java.io.Serializable;
import java.util.List;
+import java.util.Objects;
/**
*
@@ -62,4 +63,21 @@
public void setSexyList(List<Boolean> sexyList) {
this.sexyList = sexyList;
}
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (!(o instanceof SubUser)) return false;
+ if (!super.equals(o)) return false;
+ SubUser subUser = (SubUser) o;
+ return Objects.equals(userName, subUser.userName) &&
+ Objects.equals(ageList, subUser.ageList) &&
+ Objects.equals(weightList, subUser.weightList) &&
+ Objects.equals(sexyList, subUser.sexyList);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(super.hashCode(), userName, ageList, weightList, sexyList);
+ }
}