Author: mturk
Date: Sat Jun 20 07:40:33 2009
New Revision: 786765

URL: http://svn.apache.org/viewvc?rev=786765&view=rev
Log:
Add initial Structure classess

Added:
    
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/AbstractStructure.java
   (with props)
    
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/OffsetOf.java
   (with props)
    
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/exception/UnalignedParameterException.java
   (with props)
    
commons/sandbox/runtime/trunk/src/test/org/apache/commons/runtime/TestStructure.java
   (with props)
Modified:
    
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/Structure.java
    
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/Structure32.java
    
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/Structure64.java
    
commons/sandbox/runtime/trunk/src/test/org/apache/commons/runtime/TestAll.java
    
commons/sandbox/runtime/trunk/src/test/org/apache/commons/runtime/TestMemory.java

Added: 
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/AbstractStructure.java
URL: 
http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/AbstractStructure.java?rev=786765&view=auto
==============================================================================
--- 
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/AbstractStructure.java
 (added)
+++ 
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/AbstractStructure.java
 Sat Jun 20 07:40:33 2009
@@ -0,0 +1,243 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.runtime;
+import java.lang.annotation.*;
+import java.lang.reflect.*;
+import java.util.Arrays;
+
+/**
+ * Represents the Operating System C/C++ Abstract Structure.
+ * <p>
+ * </p>
+ * @since Runtime 1.0
+ */
+public abstract class AbstractStructure
+{
+
+    private int sizeof;
+    private int count;
+    private int align;
+    private int   [] offset;
+    private int   [] esizes;
+    private int   [] asizes;
+    private Field [] fields;
+    private boolean  inited = false;
+
+    /** Default constructor for derived classes.
+     */
+    protected AbstractStructure()
+    {
+        sizeof = 0;
+        count  = 0;
+        align  = 4;
+    }
+
+    private void init()
+    {
+        if (inited)
+            return;
+        inited = true;
+        for (Field f : this.getClass().getFields()) {
+            OffsetOf o = f.getAnnotation(OffsetOf.class);
+            if (o != null) {
+                count++;
+            }
+        }
+        if (count > 0) {
+            int i  = 0;
+            offset = new int[count];
+            esizes = new int[count];
+            asizes = new int[count];
+            fields = new Field[count];
+            for (Field f : this.getClass().getFields()) {
+                OffsetOf o = f.getAnnotation(OffsetOf.class);
+                if (o != null)
+                    offset[i++] = o.value();
+            }
+            // This presumes there are no two offsets with the same value
+            Arrays.sort(offset);
+            for (Field f : this.getClass().getFields()) {
+                OffsetOf o = f.getAnnotation(OffsetOf.class);
+                if (o != null) {
+                    for (i = 0; i < count; i++) {
+                        if (offset[i] == o.value()) {
+                            fields[i] = f;
+                            int rsize = getElementSize(f, this);
+                            align     = Math.max(align, Math.min(8, rsize));
+                            esizes[i] = rsize;
+                            asizes[i] = getArrayElementLength(f, this);
+                        }
+                    }
+                }
+            }
+            sizeof = 0;
+            for (i = 0; i < count; i++) {
+                sizeof += (sizeof + esizes[i]) % esizes[i];
+                offset[i] = sizeof;
+                if (asizes[i] > 0)
+                    sizeof += (esizes[i] * asizes[i]);
+                else
+                    sizeof += esizes[i];
+            }
+            sizeof = align(sizeof, align);
+        }
+    }
+
+    public static final int align(int size, int boundary)
+    {
+        return (((size) + ((boundary) - 1)) & ~((boundary) - 1));
+    }
+
+    private static final int getPrimitiveElementSize(Class c)
+    {
+        int n;
+        if (c == byte.class)
+            n = 1;
+        else if (c == char.class)
+            n = 2;
+        else if (c == short.class)
+            n = 2;
+        else if (c == int.class)
+            n = 4;
+        else if (c == float.class)
+            n = 4;
+        else if (c == long.class)
+            n = 8;
+        else if (c == double.class)
+            n = 8;
+        else
+            n = Pointer.SIZEOF;
+        return n;
+    }
+
+    private static final int getElementSize(Field f, Object struct)
+    {
+        int n = 0;
+        int s = 0;
+        Class c = f.getType();
+        if (c.isArray()) {
+            n = getPrimitiveElementSize(c.getComponentType());
+            try {
+                s = Array.getLength(f.get(struct));
+            } catch (Exception e) {
+                // Ignore null arrays
+            }
+            if (s == 0) {
+                // Treat null Arrays as Pointers
+                n = Pointer.SIZEOF;
+            }
+        }
+        else {
+            n = getPrimitiveElementSize(c);
+        }
+        return n;
+    }
+
+    private static final int getArrayElementLength(Field f, Object struct)
+    {
+        int n = 0;
+        Class c = f.getType();
+        if (c.isArray()) {
+            try {
+                n = Array.getLength(f.get(struct));
+            } catch (Throwable t) {
+                // Null arrays are Pointers
+            }
+        }
+        return n;
+    }
+
+    /**
+     * Return the element offset in this {...@code AbstractStructure}.
+     *
+     * @param name the name of the element.
+     * @return element offset or {...@code -1} if the {...@code name} was
+     *         not found.
+     */
+    public final int offsetof(String name)
+    {
+        init();
+        for (int i = 0; i < count; i++) {
+            if (fields[i].getName().equals(name))
+                return offset[i];
+        }
+        return -1;
+    }
+
+    /**
+     * Return the number of elements in this {...@code AbstractStructure}.
+     * <p>
+     * Only public class fileds having the {...@code OffsetOf} annotation
+     * will be taken as structure element fields.
+     * </p>
+     * @return element count.
+     */
+    public final int count()
+    {
+        init();
+        return count;
+    }
+
+    /**
+     * Return the size of this {...@code AbstractStructure}.
+     *
+     * @return structure size.
+     */
+    public final int sizeof()
+    {
+        init();
+        return sizeof;
+    }
+
+    /**
+     * Return the size of this {...@code AbstractStructure} element
+     * at {...@code index} position.
+     * <p>
+     * For array type of structure elements this method returns
+     * the absolute size of the array.
+     * </p>
+     * @param index the structure element index.
+     * @return structure size.
+     */
+    public final int sizeof(int index)
+        throws IndexOutOfBoundsException
+    {
+        init();
+        if (index < 0 || index >= count)
+            throw new IndexOutOfBoundsException();
+        if (asizes[index] > 0)
+            return esizes[index] * asizes[index];
+        else
+            return esizes[index];
+    }
+
+    /**
+     * Return the alignment of this {...@code AbstractStructure}.
+     * <p>
+     * The alignment is calculated according to the longest
+     * {...@code primitive} element in the structure.
+     * </p>
+     *
+     * @return structure alignment in bytes.
+     */
+    public final int alignment()
+    {
+        init();
+        return align;
+    }
+
+}

Propchange: 
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/AbstractStructure.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: 
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/OffsetOf.java
URL: 
http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/OffsetOf.java?rev=786765&view=auto
==============================================================================
--- 
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/OffsetOf.java
 (added)
+++ 
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/OffsetOf.java
 Sat Jun 20 07:40:33 2009
@@ -0,0 +1,29 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.runtime;
+import java.lang.annotation.*;
+
+/** 
+ * Annotation that represents the Structure member offsetof.
+ * @since Runtime 1.0
+ */
+...@retention(RetentionPolicy.RUNTIME)
+...@target(ElementType.FIELD)
+public @interface OffsetOf
+{
+    int value();
+}

Propchange: 
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/OffsetOf.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: 
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/Structure.java
URL: 
http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/Structure.java?rev=786765&r1=786764&r2=786765&view=diff
==============================================================================
--- 
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/Structure.java
 (original)
+++ 
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/Structure.java
 Sat Jun 20 07:40:33 2009
@@ -15,6 +15,7 @@
  */
 
 package org.apache.commons.runtime;
+import org.apache.commons.runtime.exception.UnalignedParameterException;
 
 /** Represents the Operating System C/C++ Structure pointer.
  * <p>
@@ -60,9 +61,12 @@
      * @throws IndexOutOfBoundsException if {...@code index} would cause access
      *          outside the structure address space.
      * @throws NullPointerException if structure pointer is {...@code null}.
+     * @throws UnalignedParameterException if attempt is made to access the
+     *          address that is aligned to the {...@code value} primitive type.
      */
     public abstract int    peek16(int index)
-        throws IndexOutOfBoundsException, NullPointerException;
+        throws IndexOutOfBoundsException, UnalignedParameterException,
+               NullPointerException;
 
     /**
      * Get a {...@code int} value this {...@code structure} contains at the
@@ -72,9 +76,12 @@
      * @throws IndexOutOfBoundsException if {...@code index} would cause access
      *          outside the structure address space.
      * @throws NullPointerException if structure pointer is {...@code null}.
+     * @throws UnalignedParameterException if attempt is made to access the
+     *          address that is aligned to the {...@code value} primitive type.
      */
     public abstract int    peek32(int index)
-        throws IndexOutOfBoundsException, NullPointerException;
+        throws IndexOutOfBoundsException, UnalignedParameterException,
+               NullPointerException;
 
     /**
      * Get a {...@code long} value this {...@code structure} contains at the
@@ -84,9 +91,12 @@
      * @throws IndexOutOfBoundsException if {...@code index} would cause access
      *          outside the structure address space.
      * @throws NullPointerException if structure pointer is {...@code null}.
+     * @throws UnalignedParameterException if attempt is made to access the
+     *          address that is aligned to the {...@code value} primitive type.
      */
     public abstract long   peek64(int index)
-        throws IndexOutOfBoundsException, NullPointerException;
+        throws IndexOutOfBoundsException, UnalignedParameterException,
+               NullPointerException;
 
     /**
      * Get a {...@code float} value this {...@code structure} contains at the
@@ -96,9 +106,12 @@
      * @throws IndexOutOfBoundsException if {...@code index} would cause access
      *          outside the structure address space.
      * @throws NullPointerException if structure pointer is {...@code null}.
+     * @throws UnalignedParameterException if attempt is made to access the
+     *          address that is aligned to the {...@code value} primitive type.
      */
     public abstract float  peek32f(int index)
-        throws IndexOutOfBoundsException, NullPointerException;
+        throws IndexOutOfBoundsException, UnalignedParameterException,
+               NullPointerException;
 
     /**
      * Get a {...@code double} value this {...@code structure} contains at the
@@ -108,9 +121,12 @@
      * @throws IndexOutOfBoundsException if {...@code index} would cause access
      *          outside the structure address space.
      * @throws NullPointerException if structure pointer is {...@code null}.
+     * @throws UnalignedParameterException if attempt is made to access the
+     *          address that is aligned to the {...@code value} primitive type.
      */
     public abstract double peek64f(int index)
-        throws IndexOutOfBoundsException, NullPointerException;
+        throws IndexOutOfBoundsException, UnalignedParameterException,
+               NullPointerException;
 
     /**
      * Set a {...@code byte} value to this {...@code structure} at the
@@ -122,7 +138,7 @@
      * @throws NullPointerException if pointer is {...@code null}.
      */
     public abstract void   poke(int index, int value)
-        throws IndexOutOfBoundsException, NullPointerException;
+        throws IndexOutOfBoundsException, UnalignedParameterException;
 
     /**
      * Set a {...@code short} value to this {...@code structure} at the
@@ -132,9 +148,12 @@
      * @throws IndexOutOfBoundsException if {...@code index} would cause access
      *          outside the structure address space.
      * @throws NullPointerException if pointer is {...@code null}.
+     * @throws UnalignedParameterException if attempt is made to access the
+     *          address that is aligned to the {...@code value} primitive type.
      */
     public abstract void   poke16(int index, int value)
-        throws IndexOutOfBoundsException, NullPointerException;
+        throws IndexOutOfBoundsException, UnalignedParameterException,
+               NullPointerException;
 
     /**
      * Set a {...@code integer} value to this {...@code structure} at the
@@ -144,9 +163,12 @@
      * @throws IndexOutOfBoundsException if {...@code index} would cause access
      *          outside the structure address space.
      * @throws NullPointerException if pointer is {...@code null}.
+     * @throws UnalignedParameterException if attempt is made to access the
+     *          address that is aligned to the {...@code value} primitive type.
      */
     public abstract void   poke32(int index, int value)
-        throws IndexOutOfBoundsException, NullPointerException;
+        throws IndexOutOfBoundsException, UnalignedParameterException,
+               NullPointerException;
 
     /**
      * Set a {...@code float} value to this {...@code structure} at the
@@ -156,9 +178,12 @@
      * @throws IndexOutOfBoundsException if {...@code index} would cause access
      *          outside the structure address space.
      * @throws NullPointerException if pointer is {...@code null}.
+     * @throws UnalignedParameterException if attempt is made to access the
+     *          address that is aligned to the {...@code value} primitive type.
      */
     public abstract void   poke32(int index, float value)
-        throws IndexOutOfBoundsException, NullPointerException;
+        throws IndexOutOfBoundsException, UnalignedParameterException,
+               NullPointerException;
 
     /**
      * Set a {...@code long} value to this {...@code structure} at the
@@ -168,9 +193,12 @@
      * @throws IndexOutOfBoundsException if {...@code index} would cause access
      *          outside the structure address space.
      * @throws NullPointerException if pointer is {...@code null}.
+     * @throws UnalignedParameterException if attempt is made to access the
+     *          address that is aligned to the {...@code value} primitive type.
      */
     public abstract void   poke64(int index, long value)
-        throws IndexOutOfBoundsException, NullPointerException;
+        throws IndexOutOfBoundsException, UnalignedParameterException,
+               NullPointerException;
 
     /**
      * Set a {...@code double} value to this {...@code structure} at the
@@ -180,9 +208,12 @@
      * @throws IndexOutOfBoundsException if {...@code index} would cause access
      *          outside the structure address space.
      * @throws NullPointerException if pointer is {...@code null}.
+     * @throws UnalignedParameterException if attempt is made to access the
+     *          address that is aligned to the {...@code value} primitive type.
      */
     public abstract void   poke64(int index, double value)
-        throws IndexOutOfBoundsException, NullPointerException;
+        throws IndexOutOfBoundsException, UnalignedParameterException,
+               NullPointerException;
 
     /**
      * Compares this {...@code Structure} to the specified object.

Modified: 
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/Structure32.java
URL: 
http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/Structure32.java?rev=786765&r1=786764&r2=786765&view=diff
==============================================================================
--- 
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/Structure32.java
 (original)
+++ 
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/Structure32.java
 Sat Jun 20 07:40:33 2009
@@ -15,6 +15,7 @@
  */
 
 package org.apache.commons.runtime;
+import org.apache.commons.runtime.exception.UnalignedParameterException;
 
 /** Represents the Operating System 32-bit C/C++ Structure pointer.
  * <p>
@@ -66,59 +67,74 @@
     {
         if (POINTER.POINTER == 0)
             throw new NullPointerException();
-        else if (index < 0 || index >= POINTER.PLENGTH)
+        else if (index < 0 || (index + 1) > POINTER.PLENGTH)
             throw new IndexOutOfBoundsException();
         return peek0(POINTER.POINTER + index);
     }
 
     public int peek16(int index)
-        throws IndexOutOfBoundsException, NullPointerException
+        throws IndexOutOfBoundsException, UnalignedParameterException,
+               NullPointerException
     {
         if (POINTER.POINTER == 0)
             throw new NullPointerException();
-        else if (index < 0 || index >= POINTER.PLENGTH / 2)
+        else if (index < 0 || (index + 2) > POINTER.PLENGTH)
             throw new IndexOutOfBoundsException();
-        return peek1(POINTER.POINTER + index / 2);
+        else if ((index & 0x01) != 0)
+            throw new UnalignedParameterException();
+        return peek1(POINTER.POINTER + index);
     }
 
     public int peek32(int index)
-        throws IndexOutOfBoundsException, NullPointerException
+        throws IndexOutOfBoundsException, UnalignedParameterException,
+               NullPointerException
     {
         if (POINTER.POINTER == 0)
             throw new NullPointerException();
-        else if (index < 0 || index >= POINTER.PLENGTH / 4)
+        else if (index < 0 || (index + 4) > POINTER.PLENGTH)
             throw new IndexOutOfBoundsException();
-        return peek2(POINTER.POINTER + index / 4);
+        else if ((index & 0x03) != 0)
+            throw new UnalignedParameterException();
+        return peek2(POINTER.POINTER + index);
     }
 
     public long peek64(int index)
-        throws IndexOutOfBoundsException, NullPointerException
+        throws IndexOutOfBoundsException, UnalignedParameterException,
+               NullPointerException
     {
         if (POINTER.POINTER == 0)
             throw new NullPointerException();
-        else if (index < 0 || index >= POINTER.PLENGTH / 8)
+        else if (index < 0 || (index + 8) > POINTER.PLENGTH)
             throw new IndexOutOfBoundsException();
-        return peek3(POINTER.POINTER + index / 8);
+        else if ((index & 0x07) != 0)
+            throw new UnalignedParameterException();
+        return peek3(POINTER.POINTER + index);
     }
 
     public float peek32f(int index)
-        throws IndexOutOfBoundsException, NullPointerException
+        throws IndexOutOfBoundsException, UnalignedParameterException,
+               NullPointerException
     {
         if (POINTER.POINTER == 0)
             throw new NullPointerException();
-        else if (index < 0 || index >= POINTER.PLENGTH / 4)
+        else if (index < 0 || (index + 4) > POINTER.PLENGTH)
             throw new IndexOutOfBoundsException();
-        return peek4(POINTER.POINTER + index / 4);
+        else if ((index & 0x03) != 0)
+            throw new UnalignedParameterException();
+        return peek4(POINTER.POINTER + index);
     }
 
     public double peek64f(int index)
-        throws IndexOutOfBoundsException, NullPointerException
+        throws IndexOutOfBoundsException, UnalignedParameterException,
+               NullPointerException
     {
         if (POINTER.POINTER == 0)
             throw new NullPointerException();
-        else if (index < 0 || index >= POINTER.PLENGTH / 8)
+        else if (index < 0 || (index + 8) > POINTER.PLENGTH)
             throw new IndexOutOfBoundsException();
-        return peek5(POINTER.POINTER + index / 8);
+        else if ((index & 0x07) != 0)
+            throw new UnalignedParameterException();
+        return peek5(POINTER.POINTER + index);
     }
 
     public void poke(int index, int value)
@@ -126,59 +142,74 @@
     {
         if (POINTER.POINTER == 0)
             throw new NullPointerException();
-        else if (index < 0 || index >= POINTER.PLENGTH)
+        else if (index < 0 || (index + 1) > POINTER.PLENGTH)
             throw new IndexOutOfBoundsException();
         poke0(POINTER.POINTER + index, value);
     }
 
     public void poke16(int index, int value)
-        throws IndexOutOfBoundsException, NullPointerException
+        throws IndexOutOfBoundsException, UnalignedParameterException,
+               NullPointerException
     {
         if (POINTER.POINTER == 0)
             throw new NullPointerException();
-        else if (index < 0 || index >= POINTER.PLENGTH / 2)
+        else if (index < 0 || (index + 2) > POINTER.PLENGTH)
             throw new IndexOutOfBoundsException();
-        poke1(POINTER.POINTER + index / 2, value);
+        else if ((index & 0x01) != 0)
+            throw new UnalignedParameterException();
+        poke1(POINTER.POINTER + index, value);
     }
 
     public void poke32(int index, int value)
-        throws IndexOutOfBoundsException, NullPointerException
+        throws IndexOutOfBoundsException, UnalignedParameterException,
+               NullPointerException
     {
         if (POINTER.POINTER == 0)
             throw new NullPointerException();
-        else if (index < 0 || index >= POINTER.PLENGTH / 4)
+        else if (index < 0 || (index + 4) > POINTER.PLENGTH)
             throw new IndexOutOfBoundsException();
-        poke2(POINTER.POINTER + index / 4, value);
+        else if ((index & 0x03) != 0)
+            throw new UnalignedParameterException();
+        poke2(POINTER.POINTER + index, value);
     }
 
     public void poke32(int index, float value)
-        throws IndexOutOfBoundsException, NullPointerException
+        throws IndexOutOfBoundsException, UnalignedParameterException,
+               NullPointerException
     {
         if (POINTER.POINTER == 0)
             throw new NullPointerException();
-        else if (index < 0 || index >= POINTER.PLENGTH / 4)
+        else if (index < 0 || (index + 4) > POINTER.PLENGTH)
             throw new IndexOutOfBoundsException();
-        poke4(POINTER.POINTER + index / 4, value);
+        else if ((index & 0x03) != 0)
+            throw new UnalignedParameterException();
+        poke4(POINTER.POINTER + index, value);
     }
 
     public void poke64(int index, long value)
-        throws IndexOutOfBoundsException, NullPointerException
+        throws IndexOutOfBoundsException, UnalignedParameterException,
+               NullPointerException
     {
         if (POINTER.POINTER == 0)
             throw new NullPointerException();
-        else if (index < 0 || index >= POINTER.PLENGTH / 8)
+        else if (index < 0 || (index + 8) > POINTER.PLENGTH)
             throw new IndexOutOfBoundsException();
-        poke3(POINTER.POINTER + index / 8, value);
+        else if ((index & 0x07) != 0)
+            throw new UnalignedParameterException();
+        poke3(POINTER.POINTER + index, value);
     }
 
     public void poke64(int index, double value)
-        throws IndexOutOfBoundsException, NullPointerException
+        throws IndexOutOfBoundsException, UnalignedParameterException,
+               NullPointerException
     {
         if (POINTER.POINTER == 0)
             throw new NullPointerException();
-        else if (index < 0 || index >= POINTER.PLENGTH / 8)
+        else if (index < 0 || (index + 8) > POINTER.PLENGTH)
             throw new IndexOutOfBoundsException();
-        poke5(POINTER.POINTER + index / 8, value);
+        else if ((index & 0x07) != 0)
+            throw new UnalignedParameterException();
+        poke5(POINTER.POINTER + index, value);
     }
 
     public String toString()

Modified: 
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/Structure64.java
URL: 
http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/Structure64.java?rev=786765&r1=786764&r2=786765&view=diff
==============================================================================
--- 
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/Structure64.java
 (original)
+++ 
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/Structure64.java
 Sat Jun 20 07:40:33 2009
@@ -15,6 +15,7 @@
  */
 
 package org.apache.commons.runtime;
+import org.apache.commons.runtime.exception.UnalignedParameterException;
 
 /** Represents the Operating System 64-bit C/C++ Structure pointer.
  * <p>
@@ -62,62 +63,77 @@
     }
 
     public int peek(int index)
-        throws IndexOutOfBoundsException, NullPointerException
+        throws IndexOutOfBoundsException, UnalignedParameterException
     {
         if (POINTER.POINTER == 0L)
             throw new NullPointerException();
-        else if (index < 0L || index >= POINTER.PLENGTH)
+        else if (index < 0L || (index + 1) > POINTER.PLENGTH)
             throw new IndexOutOfBoundsException();
         return peek0(POINTER.POINTER + index);
     }
 
     public int peek16(int index)
-        throws IndexOutOfBoundsException, NullPointerException
+        throws IndexOutOfBoundsException, UnalignedParameterException,
+               NullPointerException
     {
         if (POINTER.POINTER == 0L)
             throw new NullPointerException();
-        else if (index < 0L || index >= POINTER.PLENGTH / 2)
+        else if (index < 0L || (index + 2) > POINTER.PLENGTH)
             throw new IndexOutOfBoundsException();
+        else if ((index & 0x01) != 0)
+            throw new UnalignedParameterException();
         return peek1(POINTER.POINTER + index / 2);
     }
 
     public int peek32(int index)
-        throws IndexOutOfBoundsException, NullPointerException
+        throws IndexOutOfBoundsException, UnalignedParameterException,
+               NullPointerException
     {
         if (POINTER.POINTER == 0L)
             throw new NullPointerException();
-        else if (index < 0L || index >= POINTER.PLENGTH / 4)
+        else if (index < 0L || (index + 4) > POINTER.PLENGTH)
             throw new IndexOutOfBoundsException();
+        else if ((index & 0x03) != 0)
+            throw new UnalignedParameterException();
         return peek2(POINTER.POINTER + index / 4);
     }
 
     public long peek64(int index)
-        throws IndexOutOfBoundsException, NullPointerException
+        throws IndexOutOfBoundsException, UnalignedParameterException,
+               NullPointerException
     {
         if (POINTER.POINTER == 0L)
             throw new NullPointerException();
-        else if (index < 0L || index >= POINTER.PLENGTH / 8)
+        else if (index < 0L || (index + 8) > POINTER.PLENGTH)
             throw new IndexOutOfBoundsException();
+        else if ((index & 0x07) != 0)
+            throw new UnalignedParameterException();
         return peek3(POINTER.POINTER + index / 8);
     }
 
     public float peek32f(int index)
-        throws IndexOutOfBoundsException, NullPointerException
+        throws IndexOutOfBoundsException, UnalignedParameterException,
+               NullPointerException
     {
         if (POINTER.POINTER == 0L)
             throw new NullPointerException();
-        else if (index < 0L || index >= POINTER.PLENGTH / 4)
+        else if (index < 0L || (index + 4) > POINTER.PLENGTH)
             throw new IndexOutOfBoundsException();
+        else if ((index & 0x03) != 0)
+            throw new UnalignedParameterException();
         return peek4(POINTER.POINTER + index / 4);
     }
 
     public double peek64f(int index)
-        throws IndexOutOfBoundsException, NullPointerException
+        throws IndexOutOfBoundsException, UnalignedParameterException,
+               NullPointerException
     {
         if (POINTER.POINTER == 0L)
             throw new NullPointerException();
-        else if (index < 0L || index >= POINTER.PLENGTH / 8)
+        else if (index < 0L || (index + 8) > POINTER.PLENGTH)
             throw new IndexOutOfBoundsException();
+        else if ((index & 0x07) != 0)
+            throw new UnalignedParameterException();
         return peek5(POINTER.POINTER + index / 8);
     }
 
@@ -126,58 +142,73 @@
     {
         if (POINTER.POINTER == 0L)
             throw new NullPointerException();
-        else if (index < 0 || index >= POINTER.PLENGTH)
+        else if (index < 0 || (index + 1) > POINTER.PLENGTH)
             throw new IndexOutOfBoundsException();
         poke0(POINTER.POINTER + index, value);
     }
 
     public void poke16(int index, int value)
-        throws IndexOutOfBoundsException, NullPointerException
+        throws IndexOutOfBoundsException, UnalignedParameterException,
+               NullPointerException
     {
         if (POINTER.POINTER == 0L)
             throw new NullPointerException();
-        else if (index < 0L || index >= POINTER.PLENGTH / 2)
+        else if (index < 0L || (index + 2) > POINTER.PLENGTH)
             throw new IndexOutOfBoundsException();
+        else if ((index & 0x01) != 0)
+            throw new UnalignedParameterException();
         poke1(POINTER.POINTER + index / 2, value);
     }
 
     public void poke32(int index, int value)
-        throws IndexOutOfBoundsException, NullPointerException
+        throws IndexOutOfBoundsException, UnalignedParameterException,
+               NullPointerException
     {
         if (POINTER.POINTER == 0L)
             throw new NullPointerException();
-        else if (index < 0L || index >= POINTER.PLENGTH / 4)
+        else if (index < 0L || (index + 4) > POINTER.PLENGTH)
             throw new IndexOutOfBoundsException();
+        else if ((index & 0x03) != 0)
+            throw new UnalignedParameterException();
         poke2(POINTER.POINTER + index / 4, value);
     }
 
     public void poke32(int index, float value)
-        throws IndexOutOfBoundsException, NullPointerException
+        throws IndexOutOfBoundsException, UnalignedParameterException,
+               NullPointerException
     {
         if (POINTER.POINTER == 0L)
             throw new NullPointerException();
-        else if (index < 0L || index >= POINTER.PLENGTH / 4)
+        else if (index < 0L || (index + 4) > POINTER.PLENGTH)
             throw new IndexOutOfBoundsException();
+        else if ((index & 0x03) != 0)
+            throw new UnalignedParameterException();
         poke4(POINTER.POINTER + index / 4, value);
     }
 
     public void poke64(int index, long value)
-        throws IndexOutOfBoundsException, NullPointerException
+        throws IndexOutOfBoundsException, UnalignedParameterException,
+               NullPointerException
     {
         if (POINTER.POINTER == 0L)
             throw new NullPointerException();
-        else if (index < 0L || index >= POINTER.PLENGTH / 8)
+        else if (index < 0L || (index + 8) > POINTER.PLENGTH)
             throw new IndexOutOfBoundsException();
+        else if ((index & 0x07) != 0)
+            throw new UnalignedParameterException();
         poke3(POINTER.POINTER + index / 8, value);
     }
 
     public void poke64(int index, double value)
-        throws IndexOutOfBoundsException, NullPointerException
+        throws IndexOutOfBoundsException, UnalignedParameterException,
+               NullPointerException
     {
         if (POINTER.POINTER == 0L)
             throw new NullPointerException();
-        else if (index < 0L || index >= POINTER.PLENGTH / 8)
+        else if (index < 0L || (index + 8) > POINTER.PLENGTH)
             throw new IndexOutOfBoundsException();
+        else if ((index & 0x07) != 0)
+            throw new UnalignedParameterException();
         poke5(POINTER.POINTER + index / 8, value);
     }
 

Added: 
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/exception/UnalignedParameterException.java
URL: 
http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/exception/UnalignedParameterException.java?rev=786765&view=auto
==============================================================================
--- 
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/exception/UnalignedParameterException.java
 (added)
+++ 
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/exception/UnalignedParameterException.java
 Sat Jun 20 07:40:33 2009
@@ -0,0 +1,38 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.runtime.exception;
+
+/**
+ * UnalignedParameterException thrown when an attempt is made to
+ * invoke an operation on unaligned memory location.
+ *
+ * @since Runtime 1.0
+ */
+
+public class UnalignedParameterException extends IllegalArgumentException
+{
+
+    public UnalignedParameterException()
+    {
+        super();
+    }
+
+    public UnalignedParameterException(String msg)
+    {
+        super(msg);
+    }
+}

Propchange: 
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/exception/UnalignedParameterException.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: 
commons/sandbox/runtime/trunk/src/test/org/apache/commons/runtime/TestAll.java
URL: 
http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/test/org/apache/commons/runtime/TestAll.java?rev=786765&r1=786764&r2=786765&view=diff
==============================================================================
--- 
commons/sandbox/runtime/trunk/src/test/org/apache/commons/runtime/TestAll.java 
(original)
+++ 
commons/sandbox/runtime/trunk/src/test/org/apache/commons/runtime/TestAll.java 
Sat Jun 20 07:40:33 2009
@@ -43,6 +43,7 @@
         suite.addTest(TestDirectByteBuffer.suite());
         suite.addTest(TestPrivate.suite());
         suite.addTest(TestFile.suite());
+        suite.addTest(TestStructure.suite());
         return suite;
     }
 

Modified: 
commons/sandbox/runtime/trunk/src/test/org/apache/commons/runtime/TestMemory.java
URL: 
http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/test/org/apache/commons/runtime/TestMemory.java?rev=786765&r1=786764&r2=786765&view=diff
==============================================================================
--- 
commons/sandbox/runtime/trunk/src/test/org/apache/commons/runtime/TestMemory.java
 (original)
+++ 
commons/sandbox/runtime/trunk/src/test/org/apache/commons/runtime/TestMemory.java
 Sat Jun 20 07:40:33 2009
@@ -16,8 +16,10 @@
 
 package org.apache.commons.runtime;
 
+import org.apache.commons.runtime.exception.*;
 import java.lang.System;
 import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
 import junit.framework.*;
 
 /**
@@ -322,8 +324,30 @@
         Pointer p = Memory.calloc(1000);
         assertNotNull("Pointer", p);
         Structure s = p.asStructure();
-        s.poke16(498, 2303);
-        assertEquals("Value", 2303, s.peek16(498));
+        s.poke16(998, 2303);
+        assertEquals("Value", 2303, s.peek16(998));
+
+        p.free();
+    }
+
+    public void testPoke16Unaligned()
+        throws Throwable
+    {
+        Pointer p = Memory.calloc(1000);
+        assertNotNull("Pointer", p);
+        Structure s = p.asStructure();
+        try {
+            s.poke16(997, 2303);
+               fail("UnalignedParameterException not thrown");
+           }
+           catch (UnalignedParameterException u)
+           {
+               // success
+        }
+           catch (Exception e)
+           {
+               fail("Wrong exception thrown " + e);
+        }
 
         p.free();
     }
@@ -334,9 +358,24 @@
         Pointer p = Memory.calloc(1000);
         assertNotNull("Pointer", p);
         Structure s = p.asStructure();
-        s.poke32(246, 230364);
-        assertEquals("Value", 230364, s.peek32(246));
+        s.poke32(996, 230364);
+        assertEquals("Value", 230364, s.peek32(996));
+
+        p.free();
+    }
 
+    public void testPeek32Endian()
+        throws Throwable
+    {
+        Pointer p = Memory.calloc(1000);
+        assertNotNull("Pointer", p);
+        Structure s = p.asStructure();
+        s.poke32(996, 0xAA55AA55);
+        assertEquals("Value", 0xAA55AA55, s.peek32(996));
+        if (ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN)
+            assertEquals("EndianValue", (byte)0xAA, s.peek(996));
+        else
+            assertEquals("EndianValue", (byte)0x55, s.peek(996));
         p.free();
     }
 
@@ -346,8 +385,8 @@
         Pointer p = Memory.calloc(1000);
         assertNotNull("Pointer", p);
         Structure s = p.asStructure();
-        s.poke64(117, 23031964L);
-        assertEquals("Value", 23031964L, s.peek64(117));
+        s.poke64(992, 23031964L);
+        assertEquals("Value", 23031964L, s.peek64(992));
 
         p.free();
     }
@@ -358,8 +397,8 @@
         Pointer p = Memory.calloc(1000);
         assertNotNull("Pointer", p);
         Structure s = p.asStructure();
-        s.poke32(246, 2303.64F);
-        assertEquals("Value", 2303.64F, s.peek32f(246));
+        s.poke32(996, 2303.64F);
+        assertEquals("Value", 2303.64F, s.peek32f(996));
 
         p.free();
     }
@@ -370,8 +409,8 @@
         Pointer p = Memory.calloc(1000);
         assertNotNull("Pointer", p);
         Structure s = p.asStructure();
-        s.poke64(117, 2303.1964);
-        assertEquals("Value", 2303.1964, s.peek64f(117));
+        s.poke64(992, 2303.1964);
+        assertEquals("Value", 2303.1964, s.peek64f(992));
 
         p.free();
     }

Added: 
commons/sandbox/runtime/trunk/src/test/org/apache/commons/runtime/TestStructure.java
URL: 
http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/test/org/apache/commons/runtime/TestStructure.java?rev=786765&view=auto
==============================================================================
--- 
commons/sandbox/runtime/trunk/src/test/org/apache/commons/runtime/TestStructure.java
 (added)
+++ 
commons/sandbox/runtime/trunk/src/test/org/apache/commons/runtime/TestStructure.java
 Sat Jun 20 07:40:33 2009
@@ -0,0 +1,141 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.runtime;
+
+import java.lang.annotation.*;
+import java.lang.reflect.*;
+import java.lang.System;
+import java.nio.ByteBuffer;
+import junit.framework.*;
+
+/**
+ * Structure tests
+ */
+public class TestStructure extends TestCase
+{
+
+
+    public static Test suite() {
+        TestSuite suite = new TestSuite(TestStructure.class);
+        return suite;
+    }
+
+    protected void setUp()
+        throws Exception
+    {
+        System.loadLibrary("acr");
+    }
+    
+
+    protected class My1Structure extends AbstractStructure
+    {
+
+        @OffsetOf(0)
+        public int IFIELD;
+        
+        // This field has no annotation, so not visible
+        public int SFIELD;
+
+        // This field is non public, so not visible
+        protected int PFIELD;
+    }
+
+    protected class My2Structure extends AbstractStructure
+    {
+
+        @OffsetOf(0)
+        public int IFIELD;
+        
+        @OffsetOf(4)
+        public Pointer P1FIELD;
+
+        @OffsetOf(8)
+        public Pointer P2FIELD;
+    }
+
+    protected class MyUStructure extends AbstractStructure
+    {
+
+        @OffsetOf(0)
+        public int   I1FIELD;
+        @OffsetOf(4)  // 8
+        public long  L1FIELD;        
+        @OffsetOf(8)  // 16
+        public long  L2FIELD;        
+        @OffsetOf(12) // 20
+        public char  C1FIELD;        
+    }
+
+    protected class MyAStructure extends AbstractStructure
+    {
+
+        @OffsetOf(0)
+        public int      I1FIELD;
+        @OffsetOf(1)
+        public byte []  BAFIELD = new byte[10];        
+        @OffsetOf(2)
+        public int  []  AAFIELD;        
+    }
+
+    public void testAnnotation()
+        throws Throwable
+    {
+        My1Structure s = new My1Structure();
+        assertEquals("Fields", 1, s.count());
+        assertEquals("Sizeof", 4, s.sizeof());
+    }
+
+    public void testSize()
+        throws Throwable
+    {
+        My2Structure s = new My2Structure();
+        assertEquals("Fields",  3, s.count());
+        if (Pointer.SIZEOF == 4) {
+            assertEquals("Sizeof", 12, s.sizeof());
+        }
+        else {
+            assertEquals("Sizeof", 24, s.sizeof());        
+        }
+    }
+
+
+    public void testAlignment()
+        throws Throwable
+    {
+        MyUStructure s = new MyUStructure();
+        assertEquals("Fields",  4, s.count());
+        assertEquals("Sizeof", 32, s.sizeof());
+    }
+
+    public void testOffset()
+        throws Throwable
+    {
+        MyUStructure s = new MyUStructure();
+        assertEquals("Fields",  4, s.count());
+        assertEquals("OffsetOf", 24, s.offsetof("C1FIELD"));
+        assertEquals("OffsetOf", -1, s.offsetof("Unknown"));
+    }
+
+    public void testArray()
+        throws Throwable
+    {
+        MyAStructure s = new MyAStructure();
+        assertEquals("Fields",  3, s.count());
+    }
+
+}
+

Propchange: 
commons/sandbox/runtime/trunk/src/test/org/apache/commons/runtime/TestStructure.java
------------------------------------------------------------------------------
    svn:eol-style = native


Reply via email to