From 937d1e1d0948974a27d212e669f34964710bf4fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B3=93=E8=AF=9A?= Date: Thu, 19 Dec 2024 16:12:55 +0800 Subject: [PATCH 1/4] add UT for Hessian2Input.readObject() --- .../caucho/hessian/io/Hessian2InputTest.java | 71 +++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 src/test/java/com/caucho/hessian/io/Hessian2InputTest.java diff --git a/src/test/java/com/caucho/hessian/io/Hessian2InputTest.java b/src/test/java/com/caucho/hessian/io/Hessian2InputTest.java new file mode 100644 index 0000000..69a8a77 --- /dev/null +++ b/src/test/java/com/caucho/hessian/io/Hessian2InputTest.java @@ -0,0 +1,71 @@ +package com.caucho.hessian.io; + +import org.junit.Assert; +import org.junit.Test; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; + +public class Hessian2InputTest { + + SerializerFactory serializerFactory = new SerializerFactory(); + + @Test + public void testSerialize() { + byte[] originBytes = generateLargeByteArray(64 * 1024); + byte[] encodeBytes = hessianEncodeByte(originBytes); + byte[] decodeBytes = hessianDecodeByte(encodeBytes); + Assert.assertArrayEquals(originBytes, decodeBytes); + } + + @Test + public void testSerializeTime() { + byte[] originBytes = generateLargeByteArray(1024 * 1024); + byte[] encodeBytes = hessianEncodeByte(originBytes); + + long start = System.currentTimeMillis(); + for (int i = 0; i < 1000; i++) { + hessianDecodeByte(encodeBytes); + } + long end = System.currentTimeMillis(); + System.out.println("cost:" + (end - start)); + } + + private static byte[] generateLargeByteArray(int size) { + byte[] largeArray = new byte[size]; + for (int i = 0; i < size; i++) { + largeArray[i] = (byte) (i % 256); + } + return largeArray; + } + + private byte[] hessianEncodeByte(byte[] bytes) { + serializerFactory.setAllowNonSerializable(true); + ByteArrayOutputStream os = new ByteArrayOutputStream(); + Hessian2Output output = new Hessian2Output(os); + output.setSerializerFactory(serializerFactory); + try { + output.writeObject(bytes); + output.close(); + } catch (IOException e) { + throw new RuntimeException(e); + } + return os.toByteArray(); + } + + private byte[] hessianDecodeByte(byte[] bytes) { + ByteArrayInputStream bis = new ByteArrayInputStream(bytes); + Hessian2Input input = new Hessian2Input(bis); + input.setSerializerFactory(serializerFactory); + byte[] decodeObject; + try { + decodeObject = (byte[]) input.readObject(); + input.close(); + } catch (IOException e) { + throw new RuntimeException(e); + } + return decodeObject; + } + +} \ No newline at end of file From e284829af619b5975572aa3cc3962b08cb93099f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B3=93=E8=AF=9A?= Date: Thu, 19 Dec 2024 16:22:11 +0800 Subject: [PATCH 2/4] UT for Hessian2Input.readObject() --- .../com/caucho/hessian/io/Hessian2InputTest.java | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/test/java/com/caucho/hessian/io/Hessian2InputTest.java b/src/test/java/com/caucho/hessian/io/Hessian2InputTest.java index 69a8a77..e0d40fd 100644 --- a/src/test/java/com/caucho/hessian/io/Hessian2InputTest.java +++ b/src/test/java/com/caucho/hessian/io/Hessian2InputTest.java @@ -11,12 +11,20 @@ public class Hessian2InputTest { SerializerFactory serializerFactory = new SerializerFactory(); + int[] sizeList = new int[] { + 0, 2, 16, 512, 1024, + 0x8000, 0x8000 + 1, + 64 * 1024, 64 * 1024 * 1024 + }; + @Test public void testSerialize() { - byte[] originBytes = generateLargeByteArray(64 * 1024); - byte[] encodeBytes = hessianEncodeByte(originBytes); - byte[] decodeBytes = hessianDecodeByte(encodeBytes); - Assert.assertArrayEquals(originBytes, decodeBytes); + for (int i = 0; i < sizeList.length; i++) { + byte[] originBytes = generateLargeByteArray(sizeList[i]); + byte[] encodeBytes = hessianEncodeByte(originBytes); + byte[] decodeBytes = hessianDecodeByte(encodeBytes); + Assert.assertArrayEquals(originBytes, decodeBytes); + } } @Test From c1dcd54253319f274e5e332677a234a21f04cc0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B3=93=E8=AF=9A?= Date: Thu, 19 Dec 2024 16:24:18 +0800 Subject: [PATCH 3/4] optimize performance : Hessian2Input.readObject() for 'B' or 'b' --- .../com/caucho/hessian/io/Hessian2Input.java | 85 +++++++++++++++++-- 1 file changed, 80 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/caucho/hessian/io/Hessian2Input.java b/src/main/java/com/caucho/hessian/io/Hessian2Input.java index 4f81721..2ebc650 100644 --- a/src/main/java/com/caucho/hessian/io/Hessian2Input.java +++ b/src/main/java/com/caucho/hessian/io/Hessian2Input.java @@ -2583,13 +2583,88 @@ public Object readObject() _isLastChunk = tag == 'B'; _chunkLength = (read() << 8) + read(); - int data; - ByteArrayOutputStream bos = new ByteArrayOutputStream(); + ByteArrayOutputStream bos = null; + while (!_isLastChunk) { + if (bos == null) { + bos = new ByteArrayOutputStream(); + } + byte[] temp = new byte[_chunkLength]; + int i = 0; + + //处理完内存里的buffer + while (_offset < _length && i < _chunkLength) { + temp[i] = _buffer[_offset++]; + i++; + } + int needRead = _chunkLength - i; + if (needRead > 0) { + _is.read(temp, i, needRead); + } + + bos.write(temp); + + //读下一个块 + int code = read(); + switch (code) { + case 'b': + _isLastChunk = false; + _chunkLength = (read() << 8) + read(); + break; + + case 'B': + _isLastChunk = true; + _chunkLength = (read() << 8) + read(); + break; + + case 0x20: + case 0x21: + case 0x22: + case 0x23: + case 0x24: + case 0x25: + case 0x26: + case 0x27: + case 0x28: + case 0x29: + case 0x2a: + case 0x2b: + case 0x2c: + case 0x2d: + case 0x2e: + case 0x2f: + _isLastChunk = true; + _chunkLength = code - 0x20; + break; + + default: + throw expect("byte[]", code); + } + } - while ((data = parseByte()) >= 0) - bos.write(data); + byte[] res = new byte[_chunkLength]; + int i = 0; - return bos.toByteArray(); + //处理完内存里的buffer + while (_offset < _length && i < _chunkLength) { + res[i] = _buffer[_offset++]; + i++; + } + int needRead = _chunkLength - i; + if (needRead > 0) { + _is.read(res, i, needRead); + } + + if (bos != null) { + bos.write(res); + res = bos.toByteArray(); + } + + for (i = 0; i < res.length; i++) { + res[i] = (byte) (res[i] & 0xff); + } + + _chunkLength = 0; + return res; } case 0x20: From f7dfbe78b5d584b603fb02f3e4cacf74b85478e4 Mon Sep 17 00:00:00 2001 From: "liujianjun.ljj" Date: Sun, 27 Apr 2025 14:37:34 +0800 Subject: [PATCH 4/4] format code --- .../caucho/hessian/io/Hessian2InputTest.java | 26 +++++++++++++++---- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/src/test/java/com/caucho/hessian/io/Hessian2InputTest.java b/src/test/java/com/caucho/hessian/io/Hessian2InputTest.java index e0d40fd..e911df8 100644 --- a/src/test/java/com/caucho/hessian/io/Hessian2InputTest.java +++ b/src/test/java/com/caucho/hessian/io/Hessian2InputTest.java @@ -1,3 +1,19 @@ +/* + * 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.caucho.hessian.io; import org.junit.Assert; @@ -11,11 +27,11 @@ public class Hessian2InputTest { SerializerFactory serializerFactory = new SerializerFactory(); - int[] sizeList = new int[] { - 0, 2, 16, 512, 1024, - 0x8000, 0x8000 + 1, - 64 * 1024, 64 * 1024 * 1024 - }; + int[] sizeList = new int[] { + 0, 2, 16, 512, 1024, + 0x8000, 0x8000 + 1, + 64 * 1024, 64 * 1024 * 1024 + }; @Test public void testSerialize() {