Skip to content

Commit f5a37ff

Browse files
Preserve buffer positions during binary export (#2821)
* Preserve buffer positions during binary export * Use absolute buffer reads during binary export --------- Co-authored-by: Riccardo Balbo <os@rblb.it>
1 parent 62ea013 commit f5a37ff

2 files changed

Lines changed: 150 additions & 13 deletions

File tree

jme3-core/src/plugins/java/com/jme3/export/binary/BinaryOutputCapsule.java

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -913,13 +913,11 @@ protected void write(FloatBuffer value) throws IOException {
913913
write(NULL_OBJECT);
914914
return;
915915
}
916-
value.rewind();
917916
int length = value.limit();
918917
write(length);
919918
for (int x = 0; x < length; x++) {
920-
writeForBuffer(value.get());
919+
writeForBuffer(value.get(x));
921920
}
922-
value.rewind();
923921
}
924922

925923
// int buffer
@@ -929,14 +927,12 @@ protected void write(IntBuffer value) throws IOException {
929927
write(NULL_OBJECT);
930928
return;
931929
}
932-
value.rewind();
933930
int length = value.limit();
934931
write(length);
935932

936933
for (int x = 0; x < length; x++) {
937-
writeForBuffer(value.get());
934+
writeForBuffer(value.get(x));
938935
}
939-
value.rewind();
940936
}
941937

942938
// byte buffer
@@ -946,13 +942,11 @@ protected void write(ByteBuffer value) throws IOException {
946942
write(NULL_OBJECT);
947943
return;
948944
}
949-
value.rewind();
950945
int length = value.limit();
951946
write(length);
952947
for (int x = 0; x < length; x++) {
953-
writeForBuffer(value.get());
948+
writeForBuffer(value.get(x));
954949
}
955-
value.rewind();
956950
}
957951

958952
// short buffer
@@ -962,13 +956,11 @@ protected void write(ShortBuffer value) throws IOException {
962956
write(NULL_OBJECT);
963957
return;
964958
}
965-
value.rewind();
966959
int length = value.limit();
967960
write(length);
968961
for (int x = 0; x < length; x++) {
969-
writeForBuffer(value.get());
962+
writeForBuffer(value.get(x));
970963
}
971-
value.rewind();
972964
}
973965

974966
@Override
@@ -981,4 +973,4 @@ public void write(Enum value, String name, Enum defVal) throws IOException {
981973
write(value.name(), name, null);
982974
}
983975
}
984-
}
976+
}
Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
/*
2+
* Copyright (c) 2009-2026 jMonkeyEngine
3+
* All rights reserved.
4+
*
5+
* Redistribution and use in source and binary forms, with or without
6+
* modification, are permitted provided that the following conditions are
7+
* met:
8+
*
9+
* * Redistributions of source code must retain the above copyright
10+
* notice, this list of conditions and the following disclaimer.
11+
*
12+
* * Redistributions in binary form must reproduce the above copyright
13+
* notice, this list of conditions and the following disclaimer in the
14+
* documentation and/or other materials provided with the distribution.
15+
*
16+
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors
17+
* may be used to endorse or promote products derived from this software
18+
* without specific prior written permission.
19+
*
20+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21+
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22+
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23+
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24+
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25+
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26+
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
27+
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
28+
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29+
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30+
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31+
*/
32+
package com.jme3.export.binary;
33+
34+
import com.jme3.export.InputCapsule;
35+
import com.jme3.export.JmeExporter;
36+
import com.jme3.export.JmeImporter;
37+
import com.jme3.export.OutputCapsule;
38+
import com.jme3.export.Savable;
39+
import java.io.ByteArrayInputStream;
40+
import java.io.ByteArrayOutputStream;
41+
import java.io.IOException;
42+
import java.nio.ByteBuffer;
43+
import java.nio.FloatBuffer;
44+
import java.nio.IntBuffer;
45+
import java.nio.ShortBuffer;
46+
import org.junit.jupiter.api.Test;
47+
48+
import static org.junit.jupiter.api.Assertions.assertEquals;
49+
50+
public class BinaryOutputCapsuleBufferPositionTest {
51+
52+
@Test
53+
public void savePreservesNioBufferPositions() throws IOException {
54+
BufferPositionSavable savable = new BufferPositionSavable();
55+
savable.byteBuffer = byteBuffer(1, 2, 3, 4);
56+
savable.floatBuffer = floatBuffer(1f, 2f, 3f, 4f);
57+
savable.intBuffer = intBuffer(1, 2, 3, 4);
58+
savable.shortBuffer = shortBuffer((short) 1, (short) 2, (short) 3, (short) 4);
59+
60+
savable.byteBuffer.position(2);
61+
savable.floatBuffer.position(2);
62+
savable.intBuffer.position(2);
63+
savable.shortBuffer.position(2);
64+
65+
ByteArrayOutputStream output = new ByteArrayOutputStream();
66+
BinaryExporter.getInstance().save(savable, output);
67+
68+
assertEquals(2, savable.byteBuffer.position());
69+
assertEquals(2, savable.floatBuffer.position());
70+
assertEquals(2, savable.intBuffer.position());
71+
assertEquals(2, savable.shortBuffer.position());
72+
73+
BufferPositionSavable copy = (BufferPositionSavable) BinaryImporter.getInstance()
74+
.load(new ByteArrayInputStream(output.toByteArray()));
75+
76+
assertEquals(4, copy.byteBuffer.limit());
77+
assertEquals(1, copy.byteBuffer.get(0));
78+
assertEquals(4, copy.byteBuffer.get(3));
79+
assertEquals(4, copy.floatBuffer.limit());
80+
assertEquals(1f, copy.floatBuffer.get(0));
81+
assertEquals(4f, copy.floatBuffer.get(3));
82+
assertEquals(4, copy.intBuffer.limit());
83+
assertEquals(1, copy.intBuffer.get(0));
84+
assertEquals(4, copy.intBuffer.get(3));
85+
assertEquals(4, copy.shortBuffer.limit());
86+
assertEquals((short) 1, copy.shortBuffer.get(0));
87+
assertEquals((short) 4, copy.shortBuffer.get(3));
88+
}
89+
90+
private static ByteBuffer byteBuffer(int... values) {
91+
ByteBuffer buffer = ByteBuffer.allocate(values.length);
92+
for (int value : values) {
93+
buffer.put((byte) value);
94+
}
95+
buffer.rewind();
96+
return buffer;
97+
}
98+
99+
private static FloatBuffer floatBuffer(float... values) {
100+
FloatBuffer buffer = FloatBuffer.allocate(values.length);
101+
buffer.put(values);
102+
buffer.rewind();
103+
return buffer;
104+
}
105+
106+
private static IntBuffer intBuffer(int... values) {
107+
IntBuffer buffer = IntBuffer.allocate(values.length);
108+
buffer.put(values);
109+
buffer.rewind();
110+
return buffer;
111+
}
112+
113+
private static ShortBuffer shortBuffer(short... values) {
114+
ShortBuffer buffer = ShortBuffer.allocate(values.length);
115+
buffer.put(values);
116+
buffer.rewind();
117+
return buffer;
118+
}
119+
120+
public static class BufferPositionSavable implements Savable {
121+
122+
ByteBuffer byteBuffer;
123+
FloatBuffer floatBuffer;
124+
IntBuffer intBuffer;
125+
ShortBuffer shortBuffer;
126+
127+
@Override
128+
public void write(JmeExporter exporter) throws IOException {
129+
OutputCapsule capsule = exporter.getCapsule(this);
130+
capsule.write(byteBuffer, "byteBuffer", null);
131+
capsule.write(floatBuffer, "floatBuffer", null);
132+
capsule.write(intBuffer, "intBuffer", null);
133+
capsule.write(shortBuffer, "shortBuffer", null);
134+
}
135+
136+
@Override
137+
public void read(JmeImporter importer) throws IOException {
138+
InputCapsule capsule = importer.getCapsule(this);
139+
byteBuffer = capsule.readByteBuffer("byteBuffer", null);
140+
floatBuffer = capsule.readFloatBuffer("floatBuffer", null);
141+
intBuffer = capsule.readIntBuffer("intBuffer", null);
142+
shortBuffer = capsule.readShortBuffer("shortBuffer", null);
143+
}
144+
}
145+
}

0 commit comments

Comments
 (0)