diff --git a/bind/java/SeqTest.java b/bind/java/SeqTest.java index 953add3..57df87d 100644 --- a/bind/java/SeqTest.java +++ b/bind/java/SeqTest.java @@ -16,6 +16,28 @@ public class SeqTest extends TestCase { assertEquals("Unexpected arithmetic failure", 7, res); } + public void testShortString() { + String want = "a short string"; + String got = Testpkg.StrDup(want); + assertEquals("Strings should match", want, got); + } + + public void testLongString() { + StringBuilder b = new StringBuilder(); + for (int i = 0; i < 128*1024; i++) { + b.append("0123456789"); + } + String want = b.toString(); + String got = Testpkg.StrDup(want); + assertEquals("Strings should match", want, got); + } + + public void testUnicode() { + String want = "Hello, 世界"; + String got = Testpkg.StrDup(want); + assertEquals("Strings should match", want, got); + } + public void testGoRefGC() { Testpkg.S s = Testpkg.New(); runGC(); diff --git a/bind/java/seq_android.c b/bind/java/seq_android.c index d5373af..3e5ef98 100644 --- a/bind/java/seq_android.c +++ b/bind/java/seq_android.c @@ -30,21 +30,27 @@ typedef struct mem { uint32_t cap; } mem; -static mem *mem_resize(mem *m, uint32_t size) { +// mem_ensure ensures that m has at least size bytes free. +// If m is NULL, it is created. +static mem *mem_ensure(mem *m, uint32_t size) { if (m == NULL) { m = (mem*)malloc(sizeof(mem)); if (m == NULL) { - LOG_FATAL("mem_resize malloc failed"); + LOG_FATAL("mem_ensure malloc failed"); } + m->cap = 0; m->off = 0; m->len = 0; m->buf = NULL; } - m->buf = (uint8_t*)realloc((void*)m->buf, size); - if (m->buf == NULL) { - LOG_FATAL("mem_resize realloc failed, size=%d", size); + if (m->cap > m->off+size) { + return m; } - m->cap = size; + m->buf = (uint8_t*)realloc((void*)m->buf, m->off+size); + if (m->buf == NULL) { + LOG_FATAL("mem_ensure realloc failed, off=%d, size=%d", m->off, size); + } + m->cap = m->off+size; return m; } @@ -78,9 +84,11 @@ uint8_t *mem_write(JNIEnv *env, jobject obj, uint32_t size) { if (m->off != m->len) { LOG_FATAL("write can only append to seq, size: (off=%d, len=%d, size=%d", m->off, m->len, size); } - if (m->off+size > m->cap) { - m = mem_resize(m, 2*m->cap); + uint32_t cap = m->cap; + while (m->off+size > cap) { + cap *= 2; } + m = mem_ensure(m, cap); uint8_t *res = m->buf+m->off; m->off += size; m->len += size; @@ -130,8 +138,8 @@ void init_seq(void *javavm) { JNIEXPORT void JNICALL Java_go_Seq_ensure(JNIEnv *env, jobject obj, jint size) { mem *m = mem_get(env, obj); - if (m == NULL || size > m->cap - m->off) { - m = mem_resize(m, size); + if (m == NULL || m->off+size > m->cap) { + m = mem_ensure(m, size); (*env)->SetLongField(env, obj, memptr_id, (jlong)(uintptr_t)m); } } diff --git a/bind/java/testpkg/Testpkg.java b/bind/java/testpkg/Testpkg.java index 67b55b4..b7bfa2a 100644 --- a/bind/java/testpkg/Testpkg.java +++ b/bind/java/testpkg/Testpkg.java @@ -23,7 +23,6 @@ public abstract class Testpkg { public static void Call(I i) { go.Seq _in = new go.Seq(); go.Seq _out = new go.Seq(); - System.out.println("Call!"); _in.writeRef(i.ref()); Seq.send(DESCRIPTOR, CALL_Call, _in, _out); } @@ -150,11 +149,22 @@ public abstract class Testpkg { } + public static String StrDup(String s) { + go.Seq _in = new go.Seq(); + go.Seq _out = new go.Seq(); + String _result; + _in.writeUTF16(s); + Seq.send(DESCRIPTOR, CALL_StrDup, _in, _out); + _result = _out.readUTF16(); + return _result; + } + private static final int CALL_Add = 1; private static final int CALL_Call = 2; private static final int CALL_GC = 3; private static final int CALL_Keep = 4; private static final int CALL_New = 5; private static final int CALL_NumSCollected = 6; + private static final int CALL_StrDup = 7; private static final String DESCRIPTOR = "testpkg"; } diff --git a/bind/java/testpkg/go_testpkg/go_testpkg.go b/bind/java/testpkg/go_testpkg/go_testpkg.go index 2282676..227f6ec 100644 --- a/bind/java/testpkg/go_testpkg/go_testpkg.go +++ b/bind/java/testpkg/go_testpkg/go_testpkg.go @@ -81,6 +81,12 @@ func init() { seq.Register(proxySDescriptor, proxySFCode, proxySF) } +func proxy_StrDup(out, in *seq.Buffer) { + param_s := in.ReadUTF16() + res := testpkg.StrDup(param_s) + out.WriteUTF16(res) +} + func init() { seq.Register("testpkg", 1, proxy_Add) seq.Register("testpkg", 2, proxy_Call) @@ -88,4 +94,5 @@ func init() { seq.Register("testpkg", 4, proxy_Keep) seq.Register("testpkg", 5, proxy_New) seq.Register("testpkg", 6, proxy_NumSCollected) + seq.Register("testpkg", 7, proxy_StrDup) } diff --git a/bind/java/testpkg/testpkg.go b/bind/java/testpkg/testpkg.go index 278d373..68e085e 100644 --- a/bind/java/testpkg/testpkg.go +++ b/bind/java/testpkg/testpkg.go @@ -56,3 +56,7 @@ func Add(x, y int) int { func NumSCollected() int { return numSCollected } + +func StrDup(s string) string { + return s +}