Author: mturk
Date: Fri Apr 24 10:04:31 2009
New Revision: 768243

URL: http://svn.apache.org/viewvc?rev=768243&view=rev
Log:
Add new allocate method for DBB

Modified:
    
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/DirectByteBuffer.java
    commons/sandbox/runtime/trunk/src/main/native/shared/dbb.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=768243&r1=768242&r2=768243&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
 Fri Apr 24 10:04:31 2009
@@ -60,6 +60,11 @@
     private static native ByteBuffer    alloc5(Pointer ptr)
         throws NullPointerException;
 
+    private static native ByteBuffer[]  alloc6(Pointer ptr, long[] sizes,
+                                               int off, int len)
+        throws OutOfMemoryError, IllegalArgumentException,
+        IndexOutOfBoundsException;
+
     private static native ByteBuffer    attach(long mem, long offset, long 
size)
         throws NullPointerException, IllegalArgumentException;
 
@@ -137,6 +142,73 @@
     }
 
     /**
+     * Allocate a new ByteBuffer array from memory contained by {...@code ptr}.
+     * <p>
+     * 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.
+     * </p>
+     * <p>
+     * For example if two ByteBuffers are allocated with sizes
+     * {...@code 2} and {...@code 3} the overall allocated
+     * memory will be {...@code 16} bytes because each requested
+     * size is aligned to 8 byte boundary.
+     * </p>
+     *
+     * @param ptr {...@link Pointer} taht holds the native memory area.
+     * @param sizes Array of lengths for each ByteBuffer.
+     * @param off Start offset of the {...@code sizes} array.
+     * @param len The length of the {...@code sizes} 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} or {...@code len}
+     *         is invalid.
+     * @throws IndexOutOfBoundsException if copying would cause access of
+     *         data outside array bounds.
+     */
+    public static ByteBuffer[] allocate(Pointer ptr, long sizes[], int off, 
int len)
+        throws NullPointerException, IllegalArgumentException,
+        IndexOutOfBoundsException
+    {
+        return alloc6(ptr, sizes, off, len);
+    }
+
+    /**
+     * Allocate a new ByteBuffer array from memory contained by {...@code ptr}.
+     * <p>
+     * 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.
+     * </p>
+     * <p>
+     * This method does the same as calling the:
+     * <pre>
+     *
+     * DirectByteBuffer.allocate(ptr, sizes, 0, sizes.length);
+     *
+     * </pre>
+     *
+     * @param ptr {...@link Pointer} taht holds the native memory area.
+     * @param sizes Array of lengths for each ByteBuffer.
+     * @param off Start offset of the {...@code sizes} array.
+     * @param len The length of the {...@code sizes} 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} or {...@code len}
+     *         is invalid.
+     * @throws IndexOutOfBoundsException if copying would cause access of
+     *         data outside array bounds.
+     */
+    public static ByteBuffer[] allocate(Pointer ptr, long sizes[])
+        throws NullPointerException, IllegalArgumentException,
+        IndexOutOfBoundsException
+    {
+        return alloc6(ptr, sizes, 0, sizes.length);
+    }
+
+    /**
      * Allocate a new ByteBuffer array from memory.
      * </p>
      * <b>Warning:</b><br/>

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=768243&r1=768242&r2=768243&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/shared/dbb.c (original)
+++ commons/sandbox/runtime/trunk/src/main/native/shared/dbb.c Fri Apr 24 
10:04:31 2009
@@ -284,6 +284,94 @@
     return (*_E)->NewDirectByteBuffer(_E, sp, sl);
 }
 
+ACR_JNI_EXPORT_DECLARE(jobject, DirectByteBuffer, alloc6)(ACR_JNISTDARGS,
+                                                          jobject ptr,
+                                                          jlongArray sizes,
+                                                          jint off, jint len)
+{
+    jint   i;
+    jlong *ia;
+    jsize  is;
+    size_t sl;
+    size_t sz = 0;
+    jobjectArray rv = NULL;
+    char  *sp = (char *)ACR_PointerGet(_E, ptr, &sl);
+
+    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_EINDEX, 0);
+        return NULL;
+    }
+
+    if (!(ia = (*_E)->GetLongArrayElements(_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 = 0; i < len; i++) {
+        /* calculate overall size using the default alignment */
+        sz += ACR_ALIGN_DEFAULT((size_t)ia[i + off]);
+    }
+    if (sp == NULL) {
+        if (!(sp = malloc(sz))) {
+            ACR_ThrowException(_E, THROW_FMARK, ACR_EX_ENOMEM,
+                               ACR_GET_OS_ERROR());
+            rv = NULL;
+            goto cleanup;
+        }
+        ACR_PointerSet(_E, ptr, sp, sz);
+        sl = sz;
+    }
+    if (sz <= sl) {
+        size_t offset = 0;
+        for (i = 0; i < len; i++) {
+            size_t n = ACR_ALIGN_DEFAULT((size_t)ia[i + off]);
+            jobject bb = (*_E)->NewDirectByteBuffer(_E, sp + offset,
+                                                    ia[i + off]);
+            if (bb == NULL) {
+                /* One of the constructors failed.
+                 * The entire ByteBuffer[] array is invalid.
+                 */
+                rv = NULL;
+                goto cleanup;
+            }
+            (*_E)->SetObjectArrayElement(_E, rv, (jsize)i, bb);
+            if ((*_E)->ExceptionCheck(_E)) {
+                /* One of the setters failed.
+                 * The entire ByteBuffer[] array is invalid.
+                 */
+                rv = NULL;
+                goto cleanup;
+            }
+            offset += n;
+        }
+    }
+    else {
+        ACR_ThrowException(_E, THROW_FMARK, ACR_EX_EINDEX, 0);
+        rv = NULL;
+    }
+
+cleanup:
+    (*_E)->ReleaseLongArrayElements(_E, sizes, ia, JNI_ABORT);
+    return rv;
+}
+
 ACR_JNI_EXPORT_DECLARE(jobject, DirectByteBuffer, attach)(ACR_JNISTDARGS,
                                                           jlong addr,
                                                           jlong offset,

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=768243&r1=768242&r2=768243&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
 Fri Apr 24 10:04:31 2009
@@ -209,5 +209,47 @@
 
     }
 
+    public void testArrayCreatePtr()
+        throws Throwable
+    {
+        long [] sizes = { 100, 10, 100, 1000 };
+        // Aligned size
+        // 100->104 + 1000->1000 = 1104
+        Pointer mem = Memory.malloc(1104);
+        ByteBuffer[] a = DirectByteBuffer.allocate(mem, sizes, 2, 2);
+        assertNotNull("Array", a);
+
+        for (int i = 0; i < 2; i++) {
+            assertEquals("Capacity" + i, sizes[i+2], a[i].capacity());
+        }
+
+        /* WARNING: Do not free any Buffer.
+         * Use Pointer.free()
+         */
+        mem.free();
+
+    }
+
+    public void testArrayCreateNull()
+        throws Throwable
+    {
+        long [] sizes = { 100, 10, 100, 1000 };
+        Pointer mem = Memory.malloc();
+        ByteBuffer[] a = DirectByteBuffer.allocate(mem, sizes, 2, 2);
+        assertNotNull("Array", a);
+
+        for (int i = 0; i < 2; i++) {
+            assertEquals("Capacity" + i, sizes[i+2], a[i].capacity());
+        }
+        // Aligned size
+        // 100->104 + 1000->1000 = 1104
+        assertEquals("Size", 1104, mem.size().intValue());
+        /* WARNING: Do not free any Buffer.
+         * Use Pointer.free()
+         */
+        mem.free();
+
+    }
+
 }
 


Reply via email to