Skip to content

Commit b97436d

Browse files
committed
add wrappedbuffer class that uses unsafe if available
1 parent 1b0a8a7 commit b97436d

File tree

2 files changed

+144
-2
lines changed

2 files changed

+144
-2
lines changed

src/main/java/bwapi/Client.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,8 @@ class Client {
6262
try {
6363
this.connect(procID);
6464
return;
65-
} catch (final Exception exception) {
66-
System.err.println(exception);
65+
} catch (final Exception e) {
66+
System.err.println(e.getMessage());
6767
}
6868
}
6969
}
Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
package bwapi;
2+
3+
import sun.misc.Unsafe;
4+
import sun.nio.ch.DirectBuffer;
5+
6+
import java.lang.reflect.Field;
7+
import java.nio.ByteBuffer;
8+
import java.nio.CharBuffer;
9+
import java.nio.charset.Charset;
10+
import java.nio.charset.CharsetEncoder;
11+
import java.nio.charset.StandardCharsets;
12+
import java.util.Optional;
13+
14+
/**
15+
* Wrapper around ByteBuffer that makes use of sun.misc.Unsafe if available.
16+
* If not available it will fall back on using the ByteBuffer itself.
17+
*/
18+
class WrappedBuffer {
19+
private static final CharsetEncoder enc = Charset.forName("ISO-8859-1").newEncoder();
20+
21+
private final ByteBuffer buffer;
22+
private final long address;
23+
private final Unsafe unsafe;
24+
private final boolean useUnsafe;
25+
26+
WrappedBuffer(final ByteBuffer byteBuffer) {
27+
final Optional<Unsafe> optionalUnsafe = getTheUnsafe();
28+
29+
buffer = byteBuffer;
30+
31+
useUnsafe = optionalUnsafe.isPresent();
32+
address = useUnsafe ? ((DirectBuffer) buffer).address() : 0;
33+
unsafe = useUnsafe ? optionalUnsafe.get() : null;
34+
}
35+
36+
private static Optional<Unsafe> getTheUnsafe() {
37+
try {
38+
final Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe");
39+
theUnsafe.setAccessible(true);
40+
return Optional.of((Unsafe) theUnsafe.get(null));
41+
}
42+
catch (final Exception e) {
43+
e.printStackTrace();
44+
return Optional.empty();
45+
}
46+
}
47+
48+
public byte getByte(final int offset) {
49+
if (useUnsafe) {
50+
return unsafe.getByte(address + offset);
51+
}
52+
else {
53+
return buffer.get(offset);
54+
}
55+
}
56+
57+
public void putByte(final int offset, final byte value) {
58+
if (useUnsafe) {
59+
unsafe.putByte(address + offset, value);
60+
}
61+
else {
62+
buffer.put(offset, value);
63+
}
64+
}
65+
66+
public short getShort(final int offset) {
67+
if (useUnsafe) {
68+
return unsafe.getShort(address + offset);
69+
}
70+
else {
71+
return buffer.getShort(offset);
72+
}
73+
}
74+
75+
public void putShort(final int offset, final short value) {
76+
if (useUnsafe) {
77+
unsafe.putShort(address + offset, value);
78+
}
79+
else {
80+
buffer.putShort(offset, value);
81+
}
82+
}
83+
84+
public int getInt(final int offset) {
85+
if (useUnsafe) {
86+
return unsafe.getInt(address + offset);
87+
}
88+
else {
89+
return buffer.getInt(offset);
90+
}
91+
}
92+
93+
public void putInt(final int offset, final int value) {
94+
if (useUnsafe) {
95+
unsafe.putInt(address + offset, value);
96+
}
97+
else {
98+
buffer.putInt(offset, value);
99+
}
100+
}
101+
102+
public double getDouble(final int offset) {
103+
if (useUnsafe) {
104+
return unsafe.getDouble(address + offset);
105+
}
106+
else {
107+
return buffer.getDouble(offset);
108+
}
109+
}
110+
111+
public void putDouble(final int offset, final double value) {
112+
if (useUnsafe) {
113+
unsafe.putDouble(address + offset, value);
114+
}
115+
else {
116+
buffer.putDouble(offset, value);
117+
}
118+
}
119+
120+
public String getString(final int offset, final int maxLen) {
121+
final byte[] buf = new byte[maxLen];
122+
buffer.position(offset);
123+
buffer.get(buf, 0, maxLen);
124+
buffer.position(0);
125+
int len = 0;
126+
while (len < maxLen && buf[len] != 0) {
127+
++len;
128+
}
129+
return new String(buf, 0, len, StandardCharsets.ISO_8859_1);
130+
}
131+
132+
public void putString(final int offset, final int maxLen, final String string) {
133+
final int len = string.length() + 1;
134+
if (len >= maxLen) {
135+
throw new StringIndexOutOfBoundsException();
136+
}
137+
buffer.position(offset);
138+
enc.encode(CharBuffer.wrap(string), buffer, true);
139+
buffer.put((byte) 0);
140+
buffer.rewind();
141+
}
142+
}

0 commit comments

Comments
 (0)