bind/java: support byte arrays.

Fixes golang/go#9338.

Change-Id: I6e2af67cdf7f923963fa525b944613a91aac994e
Reviewed-on: https://go-review.googlesource.com/1884
Reviewed-by: David Crawshaw <crawshaw@golang.org>
This commit is contained in:
Hyang-Ah Hana Kim
2014-12-19 20:07:11 +00:00
parent 1aa04cf038
commit b2e453e1cd
10 changed files with 182 additions and 22 deletions
+29
View File
@@ -1,6 +1,9 @@
package go;
import android.test.suitebuilder.annotation.Suppress;
import android.test.MoreAsserts;
import java.util.Arrays;
import java.util.Random;
import go.testpkg.Testpkg;
@@ -52,6 +55,32 @@ public class SeqTest extends TestCase {
}
}
public void testByteArray() {
for (int i = 0; i < 2048; i++) {
if (i == 0) {
byte[] got = Testpkg.BytesAppend(null, null);
assertEquals("Bytes(null+null) should match", (byte[])null, got);
got = Testpkg.BytesAppend(new byte[0], new byte[0]);
assertEquals("Bytes(empty+empty) should match", (byte[])null, got);
continue;
}
byte[] want = new byte[i];
new Random().nextBytes(want);
byte[] s1 = null;
byte[] s2 = null;
if (i > 0) {
s1 = Arrays.copyOfRange(want, 0, 1);
}
if (i > 1) {
s2 = Arrays.copyOfRange(want, 1, i);
}
byte[] got = Testpkg.BytesAppend(s1, s2);
MoreAsserts.assertEquals("Bytes(len="+i+") should match", want, got);
}
}
public void testGoRefGC() {
Testpkg.S s = Testpkg.New();
runGC();
+43
View File
@@ -203,6 +203,20 @@ Java_go_Seq_readUTF16(JNIEnv *env, jobject obj) {
return (*env)->NewString(env, (jchar*)mem_read(env, obj, 2*size), size);
}
JNIEXPORT jbyteArray JNICALL
Java_go_Seq_readByteArray(JNIEnv *env, jobject obj) {
// Send the (array length, pointer) pair encoded as two int64.
// The pointer value is omitted if array length is 0.
jlong size = Java_go_Seq_readInt64(env, obj);
if (size == 0) {
return NULL;
}
jbyteArray res = (*env)->NewByteArray(env, size);
jlong ptr = Java_go_Seq_readInt64(env, obj);
(*env)->SetByteArrayRegion(env, res, 0, size, (jbyte*)(intptr_t)(ptr));
return res;
}
#define MEM_WRITE(ty) (*(ty*)mem_write(env, obj, sizeof(ty)))
JNIEXPORT void JNICALL
@@ -246,6 +260,35 @@ Java_go_Seq_writeUTF16(JNIEnv *env, jobject obj, jstring v) {
(*env)->GetStringRegion(env, v, 0, size, (jchar*)mem_write(env, obj, 2*size));
}
JNIEXPORT void JNICALL
Java_go_Seq_writeByteArray(JNIEnv *env, jobject obj, jbyteArray v) {
// For Byte array, we pass only the (array length, pointer) pair
// encoded as two int64 values. If the array length is 0,
// the pointer value is omitted.
if (v == NULL) {
MEM_WRITE(int64_t) = 0;
return;
}
jsize len = (*env)->GetArrayLength(env, v);
MEM_WRITE(int64_t) = len;
if (len == 0) {
return;
}
jboolean isCopy;
jbyte* b = (*env)->GetByteArrayElements(env, v, &isCopy);
if (isCopy) {
// TODO: It's not clear how to handle if b is pointing to
// a copy that may become invalid with ReleaseByteArrayElements.
// Should we fall back to copy the byte array into the buffer?
LOG_FATAL("got a copied byte array (len=%d)", len);
}
// gross pointer-to-int64 conversion.
MEM_WRITE(int64_t) = (int64_t)((intptr_t)b);
(*env)->ReleaseByteArrayElements(env, v, (jbyte*)b, 0);
}
JNIEXPORT void JNICALL
Java_go_Seq_resetOffset(JNIEnv *env, jobject obj) {
mem *m = mem_get(env, obj);
+19 -7
View File
@@ -20,6 +20,17 @@ public abstract class Testpkg {
return _result;
}
public static byte[] BytesAppend(byte[] a, byte[] b) {
go.Seq _in = new go.Seq();
go.Seq _out = new go.Seq();
byte[] _result;
_in.writeByteArray(a);
_in.writeByteArray(b);
Seq.send(DESCRIPTOR, CALL_BytesAppend, _in, _out);
_result = _out.readByteArray();
return _result;
}
public static void Call(I i) {
go.Seq _in = new go.Seq();
go.Seq _out = new go.Seq();
@@ -171,12 +182,13 @@ public abstract class Testpkg {
}
private static final int CALL_Add = 1;
private static final int CALL_Call = 2;
private static final int CALL_Err = 3;
private static final int CALL_GC = 4;
private static final int CALL_Keep = 5;
private static final int CALL_New = 6;
private static final int CALL_NumSCollected = 7;
private static final int CALL_StrDup = 8;
private static final int CALL_BytesAppend = 2;
private static final int CALL_Call = 3;
private static final int CALL_Err = 4;
private static final int CALL_GC = 5;
private static final int CALL_Keep = 6;
private static final int CALL_New = 7;
private static final int CALL_NumSCollected = 8;
private static final int CALL_StrDup = 9;
private static final String DESCRIPTOR = "testpkg";
}
+15 -7
View File
@@ -16,6 +16,13 @@ func proxy_Add(out, in *seq.Buffer) {
out.WriteInt(res)
}
func proxy_BytesAppend(out, in *seq.Buffer) {
param_a := in.ReadByteArray()
param_b := in.ReadByteArray()
res := testpkg.BytesAppend(param_a, param_b)
out.WriteByteArray(res)
}
func proxy_Call(out, in *seq.Buffer) {
var param_i testpkg.I
param_i_ref := in.ReadRef()
@@ -99,11 +106,12 @@ func proxy_StrDup(out, in *seq.Buffer) {
func init() {
seq.Register("testpkg", 1, proxy_Add)
seq.Register("testpkg", 2, proxy_Call)
seq.Register("testpkg", 3, proxy_Err)
seq.Register("testpkg", 4, proxy_GC)
seq.Register("testpkg", 5, proxy_Keep)
seq.Register("testpkg", 6, proxy_New)
seq.Register("testpkg", 7, proxy_NumSCollected)
seq.Register("testpkg", 8, proxy_StrDup)
seq.Register("testpkg", 2, proxy_BytesAppend)
seq.Register("testpkg", 3, proxy_Call)
seq.Register("testpkg", 4, proxy_Err)
seq.Register("testpkg", 5, proxy_GC)
seq.Register("testpkg", 6, proxy_Keep)
seq.Register("testpkg", 7, proxy_New)
seq.Register("testpkg", 8, proxy_NumSCollected)
seq.Register("testpkg", 9, proxy_StrDup)
}
+4
View File
@@ -68,3 +68,7 @@ func Err(s string) error {
}
return nil
}
func BytesAppend(a []byte, b []byte) []byte {
return append(a, b...)
}