Author: mturk Date: Thu Apr 16 07:47:36 2009 New Revision: 765492 URL: http://svn.apache.org/viewvc?rev=765492&view=rev Log: Add DirectByteBuffer array support. This is to allow struct iovec API's
Modified: commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/DirectByteBuffer.java commons/sandbox/runtime/trunk/src/main/native/configure commons/sandbox/runtime/trunk/src/main/native/include/acr.h commons/sandbox/runtime/trunk/src/main/native/include/acr_types.h commons/sandbox/runtime/trunk/src/main/native/include/arch/windows/acr_arch.h commons/sandbox/runtime/trunk/src/main/native/shared/clazz.c commons/sandbox/runtime/trunk/src/main/native/shared/dbb.c commons/sandbox/runtime/trunk/src/main/native/shared/error.c commons/sandbox/runtime/trunk/src/test/org/apache/commons/runtime/TestDirectByteBuffer.java Modified: commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/DirectByteBuffer.java URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/DirectByteBuffer.java?rev=765492&r1=765491&r2=765492&view=diff ============================================================================== --- commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/DirectByteBuffer.java (original) +++ commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/DirectByteBuffer.java Thu Apr 16 07:47:36 2009 @@ -20,7 +20,7 @@ /** Manages direct ByteBuffers * <br/><br/> - * <b>Warning:</b><br/>Using this class impropery may crash the running JVM. + * <b>Warning:</b><br/>Using this class improperly may crash the running JVM. * Any method call after free method was called might write or read from * the memory location that has been already allocated for * something else. @@ -36,13 +36,21 @@ // No class instance } - private static native ByteBuffer alloc0(int size) + private static native ByteBuffer alloc0(int size) throws OutOfMemoryError, IllegalArgumentException; - private static native ByteBuffer alloc1(int size) + private static native ByteBuffer alloc1(int size) throws OutOfMemoryError, IllegalArgumentException; - private static native ByteBuffer attach(long mem, int offset, int size) + private static native ByteBuffer[] alloc2(int[] sizes, int off, int len) + throws OutOfMemoryError, IllegalArgumentException, + IndexOutOfBoundsException; + + private static native ByteBuffer[] alloc3(int[] sizes, int off, int len) + throws OutOfMemoryError, IllegalArgumentException, + IndexOutOfBoundsException; + + private static native ByteBuffer attach(long mem, int offset, int size) throws NullPointerException, IllegalArgumentException; private static native void copy0(ByteBuffer src, int srcPos, ByteBuffer dst, @@ -73,13 +81,126 @@ * @throws OutOfMemoryError if memory cannot be allocated from the system. * @throws IllegalArgumentException if <code>size</code> is invalid. */ - public static ByteBuffer allocateAndInitToZero(int size) + public static ByteBuffer allocateAndClear(int size) throws OutOfMemoryError, IllegalArgumentException { return alloc1(size); } /** + * Allocate a new ByteBuffer array from memory. + * <br/><br/><b>Warning:</b><br/> + * Allocated array elements share the same memory segment + * so the <code>free()</code> must be called only for a + * <b>first</b> returned array element since it contains the + * start of the allocated memory pointer. + * <br/><br/>Memory is internally aligned to 8 byte boundary + * meaning that there might be unused chunks of memory if + * the requested sizes are not aligned to a specified boundary. + * <br/><br/> + * For example if two ByteBuffers are allocated with sizes + * <code>2</code> and <code>3</code> the overall allocated + * memory will be <code>16</code> bytes because each requested + * size is aligned to 8 byte boundary. + * + * @param sizes Array of lengths for each ByteBuffer. + * @param off Start offset of the <code>sizes</code> array. + * @param len The length of the <code>sizes</code> array to use. + * @return The ByteBuffer array with allocated memory + * + * @throws OutOfMemoryError if memory cannot be allocated from the system. + * @throws IllegalArgumentException if <code>off</code> or <code>len</code> + * is invalid. + * @throws IndexOutOfBoundsException if copying would cause access of + * data outside array bounds. + */ + public static ByteBuffer[] allocate(int sizes[], int off, int len) + throws NullPointerException, IllegalArgumentException, + IndexOutOfBoundsException + { + return alloc2(sizes, off, len); + } + + /** + * Allocate a new ByteBuffer array from memory. + * <br/><br/><b>Warning:</b><br/> + * Allocated array elements share the same memory segment + * so the <code>free()</code> must be called only for a + * <b>first</b> returned array element since it contains the + * start of the allocated memory pointer. + * <br/><br/>This method does the same as calling the: + * <pre> + * + * DirectByteBuffer.allocate(sizes, 0, sizes.length); + * + * </pre> + * @param sizes Array of lengths for each ByteBuffer. + * @return The ByteBuffer array with allocated memory + * + * @throws OutOfMemoryError if memory cannot be allocated from the system. + * @throws IllegalArgumentException if <code>off</code> or <code>len</code> + * is invalid. + */ + public static ByteBuffer[] allocate(int sizes[]) + throws NullPointerException, IllegalArgumentException + { + return alloc2(sizes, 0, sizes.length); + } + + /** + * Allocate a new ByteBuffer array and set all of the memory + * bytes to zero. + * <br/><br/><b>Warning:</b><br/> + * Allocated array elements share the same memory segment + * so the <code>free()</code> must be called only for a + * <b>first</b> returned array element since it contains the + * start of the allocated memory pointer. + * @param sizes Array of lengths for each ByteBuffer. + * @param off Start offset of the <code>sizes</code> array. + * @param len The length of the <code>sizes</code> array to use. + * @return The ByteBuffer array with allocated memory + * + * @throws OutOfMemoryError if memory cannot be allocated from the system. + * @throws IllegalArgumentException if <code>off</code> or <code>len</code> + * is invalid. + * @throws IndexOutOfBoundsException if copying would cause access of + * data outside array bounds. + */ + public static ByteBuffer[] allocateAndClear(int sizes[], int off, int len) + throws NullPointerException, IllegalArgumentException, + IndexOutOfBoundsException + { + return alloc3(sizes, off, len); + } + + /** + * Allocate a new ByteBuffer array and set all of the memory + * bytes to zero. + * <br/><br/><b>Warning:</b><br/> + * Allocated array elements share the same memory segment + * so the <code>free()</code> must be called only for a + * <b>first</b> returned array element since it contains the + * start of the allocated memory pointer. + * <br/><br/>This method does the same as calling the: + * <pre> + * + * DirectByteBuffer.allocateAndClear(sizes, 0, sizes.length); + * + * </pre> + * @param sizes Array of lengths for each ByteBuffer. + * @return The ByteBuffer array with allocated memory + * + * @throws OutOfMemoryError if memory cannot be allocated from the system. + * @throws IllegalArgumentException if <code>off</code> or <code>len</code> + * is invalid. + */ + public static ByteBuffer[] allocateAndClear(int sizes[]) + throws NullPointerException, IllegalArgumentException + { + return alloc3(sizes, 0, sizes.length); + } + + /** * Allocate a new ByteBuffer from already allocated memory. * <br/><br/><b>Warning:</b><br/> * Allocated memory must be provided from call to the @@ -95,7 +216,7 @@ * @return The ByteBuffer with attached memory * * @throws NullPointerException if <code>mem</code> is zero - * @throws IllegalArgumentException if <code>offest</code> or + * @throws IllegalArgumentException if <code>offset</code> or * <code>size</code> are invalid. */ public static ByteBuffer allocate(long mem, int offset, int size) @@ -106,13 +227,13 @@ /** * Allocate a new ByteBuffer from already allocated ByteBuffer. - * @param buf The ByteBuffer whos memory to use + * @param buf The ByteBuffer who's memory to use * @param offset Offset from the memory to use * @param size The amount of memory to use * @return The ByteBuffer with attached memory * * @throws NullPointerException if <code>buf</code> is null - * @throws IllegalArgumentException if <code>offest</code> or + * @throws IllegalArgumentException if <code>offset</code> or * <code>size</code> are invalid. */ public static ByteBuffer allocate(ByteBuffer buf, int offset, int size) Modified: commons/sandbox/runtime/trunk/src/main/native/configure URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/configure?rev=765492&r1=765491&r2=765492&view=diff ============================================================================== --- commons/sandbox/runtime/trunk/src/main/native/configure (original) +++ commons/sandbox/runtime/trunk/src/main/native/configure Thu Apr 16 07:47:36 2009 @@ -486,12 +486,16 @@ #define HAVE_SYS_SOCKET_H `have_include sys/socket` #define HAVE_SYS_WAIT_H `have_include sys/wait` #define HAVE_SYS_SYSLIMITS_H `have_include sys/syslimits` +#define HAVE_SYS_UIO_H `have_include sys/uio` #define HAVE_LIMITS_H `have_include limits` #define HAVE_CTYPE_H `have_include ctype` #define HAVE_WCHAR_H `have_include wchar` #define HAVE_WTYPE_H `have_include wctype` #define HAVE_AIO_H `have_include aio` #define HAVE_NETDB_H `have_include netdb` +#define HAVE_NETINET_IN_H `have_include netinet/in` +#define HAVE_ARPA_INET_H `have_include arpa/inet` +#define HAVE_SYS_UN_H `have_include sys/un` #define HAVE_STRERROR_R `have_strerror_r` #define HAS_BIG_ENDIAN $bige Modified: commons/sandbox/runtime/trunk/src/main/native/include/acr.h URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/include/acr.h?rev=765492&r1=765491&r2=765492&view=diff ============================================================================== --- commons/sandbox/runtime/trunk/src/main/native/include/acr.h (original) +++ commons/sandbox/runtime/trunk/src/main/native/include/acr.h Thu Apr 16 07:47:36 2009 @@ -129,6 +129,9 @@ #if HAVE_SYS_WAIT_H #include <sys/wait.h> #endif +#if HAVE_SYS_UIO_H +#include <sys/uio.h> +#endif /* Header files for PATH_MAX, _POSIX_PATH_MAX */ #if HAVE_LIMITS_H #include <limits.h> @@ -152,6 +155,15 @@ #if HAVE_NETDB_H #include <netdb.h> #endif +#if HAVE_NETINET_IN_H +#include <netinet/in.h> +#endif +#if HAVE_ARPA_INET_H +#include <arpa/inet.h> +#endif +#if HAVE_SYS_UN_H +#include <sys/un.h> +#endif #if defined(_DEBUG) || defined(DEBUG) #include <assert.h> Modified: commons/sandbox/runtime/trunk/src/main/native/include/acr_types.h URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/include/acr_types.h?rev=765492&r1=765491&r2=765492&view=diff ============================================================================== --- commons/sandbox/runtime/trunk/src/main/native/include/acr_types.h (original) +++ commons/sandbox/runtime/trunk/src/main/native/include/acr_types.h Thu Apr 16 07:47:36 2009 @@ -65,6 +65,7 @@ typedef enum { ACR_CC_OBJECT, /* Ljava/lang/Object; - String */ ACR_CC_STRING, /* Ljava/lang/String; - Object */ + ACR_CC_DBBUFF, /* Ljava/nio/ByteBuffer - ByteBuffer */ ACR_CC_ZARRAY, /* [Z - boolean[] */ ACR_CC_BARRAY, /* [B - byte[] */ ACR_CC_CARRAY, /* [C - char[] */ Modified: commons/sandbox/runtime/trunk/src/main/native/include/arch/windows/acr_arch.h URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/include/arch/windows/acr_arch.h?rev=765492&r1=765491&r2=765492&view=diff ============================================================================== --- commons/sandbox/runtime/trunk/src/main/native/include/arch/windows/acr_arch.h (original) +++ commons/sandbox/runtime/trunk/src/main/native/include/arch/windows/acr_arch.h Thu Apr 16 07:47:36 2009 @@ -48,7 +48,17 @@ UDP_TABLE_OWNER_MODULE } UDP_TABLE_CLASS, *PUDP_TABLE_CLASS; -#endif /* PRODUCT_UNDEFINED */ +#endif /* NTDDI_VISTA */ + +/* Missing POSIX declarations */ + +struct iovec { + void *iov_base; /* Starting address */ + size_t iov_len; /* Number of bytes */ +}; + + +/* End of POSIX */ /* Copied from http://source.winehq.org/source/include/winternl.h */ Modified: commons/sandbox/runtime/trunk/src/main/native/shared/clazz.c URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/shared/clazz.c?rev=765492&r1=765491&r2=765492&view=diff ============================================================================== --- commons/sandbox/runtime/trunk/src/main/native/shared/clazz.c (original) +++ commons/sandbox/runtime/trunk/src/main/native/shared/clazz.c Thu Apr 16 07:47:36 2009 @@ -32,21 +32,22 @@ const char *name; jclass clazz; } core_classes[] = { - { "Ljava/lang/Object;", NULL }, - { "Ljava/lang/String;", NULL }, - { "[Z", NULL }, - { "[B", NULL }, - { "[C", NULL }, - { "[I", NULL }, - { "[J", NULL }, - { "[Ljava/lang/Object;", NULL }, - { "[Ljava/lang/String;", NULL }, - { "[[Z", NULL }, - { "[[B", NULL }, - { "[[C", NULL }, - { "[[I", NULL }, - { "[[J", NULL }, - { NULL, NULL } + { "Ljava/lang/Object;", NULL }, + { "Ljava/lang/String;", NULL }, + { "Ljava/nio/ByteBuffer;", NULL }, + { "[Z", NULL }, + { "[B", NULL }, + { "[C", NULL }, + { "[I", NULL }, + { "[J", NULL }, + { "[Ljava/lang/Object;", NULL }, + { "[Ljava/lang/String;", NULL }, + { "[[Z", NULL }, + { "[[B", NULL }, + { "[[C", NULL }, + { "[[I", NULL }, + { "[[J", NULL }, + { NULL, NULL } }; int ACR_InitClazzCache(JNIEnv *_E) @@ -72,8 +73,21 @@ if (o != NULL) { core_classes[i].clazz = (jclass)(*_E)->NewGlobalRef(_E, o); (*_E)->DeleteLocalRef(_E, o); + if (core_classes[i].clazz == NULL) { +#ifdef ACR_ENABLE_TEST + fprintf(stderr, "[ERROR] Cannot reference core class '%s'\n", + core_classes[i].name); + fflush(stderr); +#endif + return ACR_ENOMEM; + } } else { +#ifdef ACR_ENABLE_TEST + fprintf(stderr, "[ERROR] Cannot find core class '%s'\n", + core_classes[i].name); + fflush(stderr); +#endif return ACR_ESYMNOTFOUND; } i++; @@ -113,13 +127,31 @@ if (o != NULL) { c = (jclass)(*_E)->NewGlobalRef(_E, o); (*_E)->DeleteLocalRef(_E, o); + if (c == NULL) { + /* According to the JNI spec this can + * happen if the system runs out of memory. + */ +#ifdef ACR_ENABLE_TEST + fprintf(stderr, "[ERROR] Cannot reference class '%s'\n", name); + fflush(stderr); +#endif + return NULL; + } if (m) (*_E)->MonitorEnter(_E, m); ACR_TableAdd(_E, THROW_FMARK, clazz_cache, name, c, 0); if (m) (*_E)->MonitorExit(_E, m); } - + else { + /* Class cannot fe found. The exception has already + * been thrown. + */ +#ifdef ACR_ENABLE_TEST + fprintf(stderr, "[ERROR] Cannot find class '%s'\n", name); + fflush(stderr); +#endif + } return c; } Modified: commons/sandbox/runtime/trunk/src/main/native/shared/dbb.c URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/shared/dbb.c?rev=765492&r1=765491&r2=765492&view=diff ============================================================================== --- commons/sandbox/runtime/trunk/src/main/native/shared/dbb.c (original) +++ commons/sandbox/runtime/trunk/src/main/native/shared/dbb.c Thu Apr 16 07:47:36 2009 @@ -22,6 +22,7 @@ #include "acr.h" #include "acr_private.h" #include "acr_error.h" +#include "acr_clazz.h" /** * DirectByteBuffer utilities @@ -78,6 +79,170 @@ } } +ACR_JNI_EXPORT_DECLARE(jobject, DirectByteBuffer, alloc2)(ACR_JNISTDARGS, + jintArray sizes, + jint off, jint len) +{ + jint i; + jint *ia; + jsize is; + size_t sz = 0; + void *mem; + jobjectArray rv = NULL; + + UNREFERENCED_O; + + if (len < 1 || off < 0) { + ACR_ThrowException(_E, THROW_FMARK, ACR_EX_EINVAL, + ACR_EINVALSIZ); + return NULL; + } + if ((is = (*_E)->GetArrayLength(_E, sizes)) < 1) { + /* At least one element is needed */ + ACR_ThrowException(_E, THROW_FMARK, ACR_EX_EINVAL, + ACR_EINVALSIZ); + return NULL; + } + if ((jsize)(off + len) > is) { + ACR_ThrowException(_E, THROW_FMARK, ACR_EX_EINVAL, + ACR_EX_EINDEX); + return NULL; + } + + if (!(ia = (*_E)->GetIntArrayElements(_E, sizes, NULL))) { + ACR_ThrowException(_E, THROW_FMARK, ACR_EX_EINVAL, + ACR_EISNULL); + return NULL; + } + if (!(rv = ACR_NewCoreObjectArray(_E, ACR_CC_DBBUFF, (jsize)len))) { + /* Failed creating ByteBuffer[] array */ + goto cleanup; + } + for (i = off; i < len; i++) { + /* calculate overall size using the default alignment */ + sz += ACR_ALIGN_DEFAULT(ia[i]); + } + if ((mem = malloc(sz)) != NULL) { + size_t offset = 0; + jsize aindex = 0; + for (i = off; i < len; i++) { + size_t n = ACR_ALIGN_DEFAULT(ia[i]); + jobject bb = (*_E)->NewDirectByteBuffer(_E, mem + offset, + (jlong)ia[i]); + if (bb == NULL) { + /* One of the constructors failed. + * The entire ByteBuffer[] array is invalid. + */ + free(mem); + rv = NULL; + goto cleanup; + } + (*_E)->SetObjectArrayElement(_E, rv, aindex++, bb); + if ((*_E)->ExceptionCheck(_E)) { + /* One of the setters failed. + * The entire ByteBuffer[] array is invalid. + */ + free(mem); + rv = NULL; + goto cleanup; + } + offset += n; + } + } + else { + ACR_ThrowException(_E, THROW_FMARK, ACR_EX_ENOMEM, + ACR_GET_OS_ERROR()); + /* XXX: Should we cleanup the created array? */ + rv = NULL; + } + +cleanup: + (*_E)->ReleaseIntArrayElements(_E, sizes, ia, JNI_ABORT); + return rv; +} + +ACR_JNI_EXPORT_DECLARE(jobject, DirectByteBuffer, alloc3)(ACR_JNISTDARGS, + jintArray sizes, + jint off, jint len) +{ + jint i; + jint *ia; + jsize is; + size_t sz = 0; + void *mem; + jobjectArray rv = NULL; + + UNREFERENCED_O; + + if (len < 1 || off < 0) { + ACR_ThrowException(_E, THROW_FMARK, ACR_EX_EINVAL, + ACR_EINVALSIZ); + return NULL; + } + if ((is = (*_E)->GetArrayLength(_E, sizes)) < 1) { + /* At least one element is needed */ + ACR_ThrowException(_E, THROW_FMARK, ACR_EX_EINVAL, + ACR_EINVALSIZ); + return NULL; + } + if ((jsize)(off + len) > is) { + ACR_ThrowException(_E, THROW_FMARK, ACR_EX_EINVAL, + ACR_EX_EINDEX); + return NULL; + } + + if (!(ia = (*_E)->GetIntArrayElements(_E, sizes, NULL))) { + ACR_ThrowException(_E, THROW_FMARK, ACR_EX_EINVAL, + ACR_EISNULL); + return NULL; + } + if (!(rv = ACR_NewCoreObjectArray(_E, ACR_CC_DBBUFF, (jsize)len))) { + /* Failed creating ByteBuffer[] array */ + goto cleanup; + } + for (i = off; i < len; i++) { + /* calculate overall size using the default alignment */ + sz += ACR_ALIGN_DEFAULT(ia[i]); + } + if ((mem = calloc(1, sz)) != NULL) { + size_t offset = 0; + jsize aindex = 0; + for (i = off; i < len; i++) { + size_t n = ACR_ALIGN_DEFAULT(ia[i]); + jobject bb = (*_E)->NewDirectByteBuffer(_E, mem + offset, + (jlong)ia[i]); + if (bb == NULL) { + /* One of the constructors failed. + * The entire ByteBuffer[] array is invalid. + */ + free(mem); + rv = NULL; + goto cleanup; + } + (*_E)->SetObjectArrayElement(_E, rv, aindex++, bb); + if ((*_E)->ExceptionCheck(_E)) { + /* One of the setters failed. + * The entire ByteBuffer[] array is invalid. + */ + free(mem); + rv = NULL; + goto cleanup; + } + offset += n; + } + } + else { + ACR_ThrowException(_E, THROW_FMARK, ACR_EX_ENOMEM, + ACR_GET_OS_ERROR()); + /* XXX: Should we cleanup the created array? */ + rv = NULL; + } + +cleanup: + (*_E)->ReleaseIntArrayElements(_E, sizes, ia, JNI_ABORT); + return rv; +} + ACR_JNI_EXPORT_DECLARE(jobject, DirectByteBuffer, attach)(ACR_JNISTDARGS, jlong addr, jint offset, Modified: commons/sandbox/runtime/trunk/src/main/native/shared/error.c URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/shared/error.c?rev=765492&r1=765491&r2=765492&view=diff ============================================================================== --- commons/sandbox/runtime/trunk/src/main/native/shared/error.c (original) +++ commons/sandbox/runtime/trunk/src/main/native/shared/error.c Thu Apr 16 07:47:36 2009 @@ -54,10 +54,16 @@ } ec = (*env)->FindClass(env, clazz); if (IS_JOBJECT_NULL(env, ec)) { + /* If the class cannot be found, + * the Exception has already been thrown. + * See JNI Find Class for the Exceptions thrown. + */ +#ifdef ACR_ENABLE_TEST fprintf(stderr, "[ERROR] Cannot find class '%s'\n", clazz); if (msg) fprintf(stderr, " %s\n", msg); fflush(stderr); +#endif return; } (*env)->ThrowNew(env, ec, msg); Modified: commons/sandbox/runtime/trunk/src/test/org/apache/commons/runtime/TestDirectByteBuffer.java URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/test/org/apache/commons/runtime/TestDirectByteBuffer.java?rev=765492&r1=765491&r2=765492&view=diff ============================================================================== --- commons/sandbox/runtime/trunk/src/test/org/apache/commons/runtime/TestDirectByteBuffer.java (original) +++ commons/sandbox/runtime/trunk/src/test/org/apache/commons/runtime/TestDirectByteBuffer.java Thu Apr 16 07:47:36 2009 @@ -51,7 +51,7 @@ public void testCalloc() throws Exception { - ByteBuffer bb = DirectByteBuffer.allocateAndInitToZero(1000); + ByteBuffer bb = DirectByteBuffer.allocateAndClear(1000); assertTrue("Direct", bb.isDirect()); assertEquals("Capacity", 1000, bb.capacity()); DirectByteBuffer.free(bb); @@ -97,7 +97,7 @@ throws Exception { ByteBuffer sb = DirectByteBuffer.allocate(1000); - ByteBuffer db = DirectByteBuffer.allocateAndInitToZero(1000); + ByteBuffer db = DirectByteBuffer.allocateAndClear(1000); assertTrue("Direct", sb.isDirect()); assertTrue("Direct", db.isDirect()); sb.putInt(0xcafebabe); @@ -108,4 +108,41 @@ DirectByteBuffer.free(db); } + public void testArrayCreate() + throws Exception + { + int [] sizes = { 100, 10, 100, 1000 }; + ByteBuffer[] a = DirectByteBuffer.allocate(sizes, 0, sizes.length); + assertNotNull("Array", a); + + for (int i = 0; i < sizes.length; i++) { + assertEquals("Capacity" + i, sizes[i], a[i].capacity()); + } + + /* WARNING: Free only the first array element + * because they all share the same memory + */ + DirectByteBuffer.free(a[0]); + + } + + public void testArrayCreateAndClear() + throws Exception + { + int [] sizes = { 100, 10, 100 , 1000}; + ByteBuffer[] a = DirectByteBuffer.allocateAndClear(sizes, 0, sizes.length); + assertNotNull("Array", a); + + for (int i = 0; i < sizes.length; i++) { + assertEquals("Capacity" + i, sizes[i], a[i].capacity()); + } + + /* WARNING: Free only the first array element + * because they all share the same memory + */ + DirectByteBuffer.free(a[0]); + + } + } +