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