diff options
author | Sven Gothel <[email protected]> | 2011-07-20 08:14:40 +0200 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2011-07-20 08:14:40 +0200 |
commit | 8b3057585930357bb16546f584d998953b084034 (patch) | |
tree | 5d7ffb74a36da6076d05657f2867c68c47068c7b | |
parent | 0a8e1566c766f3b5a5e71b5d80500034f1a614a8 (diff) |
FIX StructAccessor / JavaEmitter's struct-emitter: Using byte offsets
Problem:
typedef struct {
int8_t bits1; // +1 - 0
// +3 (p32)
int32_t id; // +4 - 4
int8_t bits2; // +1 - 8
// +3 (p32) -
int64_t long0; // +8 - 12
"longBuffer.get(<type-sized index>)" is invalid,
but "byteBuffer.getLong(<byte index>)" must be done.
The actual impl. doesn't matter, hence dropping the other nio type mappings is good.
FIXES 32bit unit test, works well (static) on 32/64 bit (unix).
TODO: Respect diff alignment for OS/ARCH either by offset tables for all, or runtime computing.
-rw-r--r-- | src/java/com/jogamp/common/nio/StructAccessor.java | 216 | ||||
-rw-r--r-- | src/java/com/jogamp/gluegen/JavaEmitter.java | 41 |
2 files changed, 90 insertions, 167 deletions
diff --git a/src/java/com/jogamp/common/nio/StructAccessor.java b/src/java/com/jogamp/common/nio/StructAccessor.java index c641d79..0f88551 100644 --- a/src/java/com/jogamp/common/nio/StructAccessor.java +++ b/src/java/com/jogamp/common/nio/StructAccessor.java @@ -43,17 +43,10 @@ import java.nio.*; /** * @author Kenneth Russel - * @author Michael Bien */ public class StructAccessor { private ByteBuffer bb; - private FloatBuffer fb; - private IntBuffer ib; - private ShortBuffer sb; - private CharBuffer cb; - private DoubleBuffer db; - private LongBuffer lb; public StructAccessor(ByteBuffer bb) { // Setting of byte order is concession to native code which needs @@ -74,202 +67,161 @@ public class StructAccessor { public ByteBuffer slice(int byteOffset, int byteLength) { bb.position(byteOffset); bb.limit(byteOffset + byteLength); - ByteBuffer newBuf = bb.slice(); + final ByteBuffer newBuf = bb.slice().order(bb.order()); // slice and duplicate may change byte order bb.position(0); bb.limit(bb.capacity()); return newBuf; } - /** Retrieves the byte at the specified slot (byte offset). */ - public byte getByteAt(int slot) { - return bb.get(slot); + /** Retrieves the byte at the specified byteOffset. */ + public byte getByteAt(int byteOffset) { + return bb.get(byteOffset); } - /** Puts a byte at the specified slot (byte offset). */ - public void setByteAt(int slot, byte v) { - bb.put(slot, v); + /** Puts a byte at the specified byteOffset. */ + public void setByteAt(int byteOffset, byte v) { + bb.put(byteOffset, v); } - /** Retrieves the char at the specified slot (2-byte offset). */ - public char getCharAt(int slot) { - return charBuffer().get(slot); + /** Retrieves the char at the specified byteOffset. */ + public char getCharAt(int byteOffset) { + return bb.getChar(byteOffset); } - /** Puts a char at the specified slot (2-byte offset). */ - public void setCharAt(int slot, char v) { - charBuffer().put(slot, v); + /** Puts a char at the specified byteOffset. */ + public void setCharAt(int byteOffset, char v) { + bb.putChar(byteOffset, v); } - /** Retrieves the double at the specified slot (8-byte offset). */ - public double getDoubleAt(int slot) { - return doubleBuffer().get(slot); + /** Retrieves the short at the specified byteOffset. */ + public short getShortAt(int byteOffset) { + return bb.getShort(byteOffset); } - /** Puts a double at the specified slot (8-byte offset). */ - public void setDoubleAt(int slot, double v) { - doubleBuffer().put(slot, v); + /** Puts a short at the specified byteOffset. */ + public void setShortAt(int byteOffset, short v) { + bb.putShort(byteOffset, v); } - /** Retrieves the float at the specified slot (4-byte offset). */ - public float getFloatAt(int slot) { - return floatBuffer().get(slot); + /** Retrieves the int at the specified byteOffset. */ + public int getIntAt(int byteOffset) { + return bb.getInt(byteOffset); } - /** Puts a float at the specified slot (4-byte offset). */ - public void setFloatAt(int slot, float v) { - floatBuffer().put(slot, v); + /** Puts a int at the specified byteOffset. */ + public void setIntAt(int byteOffset, int v) { + bb.putInt(byteOffset, v); } - /** Retrieves the int at the specified slot (4-byte offset). */ - public int getIntAt(int slot) { - return intBuffer().get(slot); + /** Retrieves the float at the specified byteOffset. */ + public float getFloatAt(int byteOffset) { + return bb.getFloat(byteOffset); } - /** Puts a int at the specified slot (4-byte offset). */ - public void setIntAt(int slot, int v) { - intBuffer().put(slot, v); + /** Puts a float at the specified byteOffset. */ + public void setFloatAt(int byteOffset, float v) { + bb.putFloat(byteOffset, v); } - /** Retrieves the short at the specified slot (2-byte offset). */ - public short getShortAt(int slot) { - return shortBuffer().get(slot); + /** Retrieves the double at the specified byteOffset. */ + public double getDoubleAt(int byteOffset) { + return bb.getDouble(byteOffset); } - /** Puts a short at the specified slot (2-byte offset). */ - public void setShortAt(int slot, short v) { - shortBuffer().put(slot, v); + /** Puts a double at the specified byteOffset. */ + public void setDoubleAt(int byteOffset, double v) { + bb.putDouble(byteOffset, v); } - public void setBytesAt(int slot, byte[] v) { - for (int i = 0; i < v.length; i++) { - bb.put(slot++, v[i]); - } + /** + * Retrieves the long at the specified byteOffset. + */ + public long getLongAt(int byteOffset) { + return bb.getLong(byteOffset); } - public byte[] getBytesAt(int slot, byte[] v) { - for (int i = 0; i < v.length; i++) { - v[i] = bb.get(slot++); - } - return v; + /** + * Puts a long at the specified byteOffset. + */ + public void setLongAt(int byteOffset, long v) { + bb.putLong(byteOffset, v); } - - public void setCharsAt(int slot, char[] v) { + + public void setBytesAt(int byteOffset, byte[] v) { for (int i = 0; i < v.length; i++) { - charBuffer().put(slot++, v[i]); + bb.put(byteOffset++, v[i]); } } - public char[] getCharsAt(int slot, char[] v) { + public byte[] getBytesAt(int byteOffset, byte[] v) { for (int i = 0; i < v.length; i++) { - v[i] = charBuffer().get(slot++); + v[i] = bb.get(byteOffset++); } return v; } - public void setIntsAt(int slot, int[] v) { - for (int i = 0; i < v.length; i++) { - intBuffer().put(slot++, v[i]); + public void setCharsAt(int byteOffset, char[] v) { + for (int i = 0; i < v.length; i++, byteOffset+=2) { + bb.putChar(byteOffset, v[i]); } } - public int[] getIntsAt(int slot, int[] v) { - for (int i = 0; i < v.length; i++) { - v[i] = intBuffer().get(slot++); + public char[] getCharsAt(int byteOffset, char[] v) { + for (int i = 0; i < v.length; i++, byteOffset+=2) { + v[i] = bb.getChar(byteOffset); } return v; } - public void setFloatsAt(int slot, float[] v) { - for (int i = 0; i < v.length; i++) { - floatBuffer().put(slot++, v[i]); + public void setIntsAt(int byteOffset, int[] v) { + for (int i = 0; i < v.length; i++, byteOffset+=4) { + bb.putInt(byteOffset, v[i]); } } - public float[] getFloatsAt(int slot, float[] v) { - for (int i = 0; i < v.length; i++) { - v[i] = floatBuffer().get(slot++); + public int[] getIntsAt(int byteOffset, int[] v) { + for (int i = 0; i < v.length; i++, byteOffset+=4) { + v[i] = bb.getInt(byteOffset); } return v; } - /** - * Puts a double at the specified slot (8-byte offset). - * May throw an {@link UnsupportedOperationException} - */ - public void setDoublesAt(int slot, double[] v) { - for (int i = 0; i < v.length; i++) { - doubleBuffer().put(slot++, v[i]); + public void setFloatsAt(int byteOffset, float[] v) { + for (int i = 0; i < v.length; i++, byteOffset+=4) { + bb.putFloat(byteOffset, v[i]); } } - /** - * Retrieves the long at the specified slot (8-byte offset). - * May throw an {@link UnsupportedOperationException} - */ - public double[] getDoublesAt(int slot, double[] v) { - for (int i = 0; i < v.length; i++) { - v[i] = doubleBuffer().get(slot++); + public float[] getFloatsAt(int byteOffset, float[] v) { + for (int i = 0; i < v.length; i++, byteOffset+=4) { + v[i] = bb.getFloat(byteOffset); } return v; } - /** - * Retrieves the long at the specified slot (8-byte offset). - */ - public long getLongAt(int slot) { - return longBuffer().get(slot); - } - - /** - * Puts a long at the specified slot (8-byte offset). - */ - public void setLongAt(int slot, long v) { - longBuffer().put(slot, v); - } - - //---------------------------------------------------------------------- - // Internals only below this point - // - - private final FloatBuffer floatBuffer() { - if (fb == null) { - fb = bb.asFloatBuffer(); + public void setDoublesAt(int byteOffset, double[] v) { + for (int i = 0; i < v.length; i++, byteOffset+=8) { + bb.putDouble(byteOffset, v[i]); } - return fb; } - private final IntBuffer intBuffer() { - if (ib == null) { - ib = bb.asIntBuffer(); + public double[] getDoublesAt(int byteOffset, double[] v) { + for (int i = 0; i < v.length; i++, byteOffset+=8) { + v[i] = bb.getDouble(byteOffset); } - return ib; - } - - private final ShortBuffer shortBuffer() { - if (sb == null) { - sb = bb.asShortBuffer(); - } - return sb; - } - - private final LongBuffer longBuffer() { - if (lb == null) { - lb = bb.asLongBuffer(); - } - return lb; + return v; } - private final DoubleBuffer doubleBuffer() { - if (db == null) { - db = bb.asDoubleBuffer(); + public void setLongsAt(int byteOffset, long[] v) { + for (int i = 0; i < v.length; i++, byteOffset+=8) { + bb.putLong(byteOffset, v[i]); } - return db; } - private final CharBuffer charBuffer() { - if (cb == null) { - cb = bb.asCharBuffer(); + public long[] getLongsAt(int byteOffset, long[] v) { + for (int i = 0; i < v.length; i++, byteOffset+=8) { + v[i] = bb.getLong(byteOffset); } - return cb; + return v; } } diff --git a/src/java/com/jogamp/gluegen/JavaEmitter.java b/src/java/com/jogamp/gluegen/JavaEmitter.java index 770db38..dfa7594 100644 --- a/src/java/com/jogamp/gluegen/JavaEmitter.java +++ b/src/java/com/jogamp/gluegen/JavaEmitter.java @@ -1062,10 +1062,7 @@ public class JavaEmitter implements GlueEmitter { String paramType = typeToJavaType(baseElementType, false, extMachDesc).getName(); String capitalized = capitalizeString(fieldName); - int slot = -1; - if(!doBaseClass) { - slot = slot(fieldType, (int) field.getOffset(intMachDesc), intMachDesc); - } + final int byteOffset = doBaseClass ? -1 : (int) field.getOffset(intMachDesc); // Setter writer.println(); @@ -1074,7 +1071,7 @@ public class JavaEmitter implements GlueEmitter { writer.println(";"); } else { writer.println(" {"); - writer.print (" accessor.set" + capitalizeString(paramType) + "sAt(" + slot + ", "); + writer.print (" accessor.set" + capitalizeString(paramType) + "sAt(" + byteOffset + ", "); writer.println("val);"); writer.println(" return this;"); writer.println(" }"); @@ -1087,7 +1084,7 @@ public class JavaEmitter implements GlueEmitter { } else { writer.println(" {"); writer.print (" return "); - writer.println("accessor.get" + capitalizeString(paramType) + "sAt(" + slot + ", new " +paramType+"["+fieldType.asArray().getLength()+"]);"); + writer.println("accessor.get" + capitalizeString(paramType) + "sAt(" + byteOffset + ", new " +paramType+"["+fieldType.asArray().getLength()+"]);"); writer.println(" }"); } @@ -1123,10 +1120,7 @@ public class JavaEmitter implements GlueEmitter { if (!doBaseClass) { capitalized = capitalizeString(internalJavaTypeName); } - int slot = -1; - if (!doBaseClass) { - slot = slot(fieldType, (int) field.getOffset(intMachDesc), intMachDesc); - } + final int byteOffset = doBaseClass ? -1 : (int) field.getOffset(intMachDesc); writer.println(); String capitalizedFieldName = capitalizeString(fieldName); // Setter @@ -1135,7 +1129,7 @@ public class JavaEmitter implements GlueEmitter { writer.println(";"); } else { writer.println(" {"); - writer.print (" accessor.set" + capitalized + "At(" + slot + ", "); + writer.print (" accessor.set" + capitalized + "At(" + byteOffset + ", "); if (!externalJavaTypeName.equals(internalJavaTypeName)) { writer.print("(" + internalJavaTypeName + ") "); } @@ -1154,7 +1148,7 @@ public class JavaEmitter implements GlueEmitter { if (!externalJavaTypeName.equals(internalJavaTypeName)) { writer.print("(" + externalJavaTypeName + ") "); } - writer.println("accessor.get" + capitalized + "At(" + slot + ");"); + writer.println("accessor.get" + capitalized + "At(" + byteOffset + ");"); writer.println(" }"); } } else { @@ -1408,29 +1402,6 @@ public class JavaEmitter implements GlueEmitter { (c == Long.TYPE)); } - private int slot(Type t, int byteOffset, MachineDescription curMachDesc) { - if (t.isInt()) { - final int tsz = (int) t.getSize(curMachDesc); - switch (tsz) { - case 1: - case 2: - case 4: - case 8: return byteOffset / tsz; - default: throw new RuntimeException("Illegal type"); - } - } else if (t.isFloat()) { - return byteOffset / 4; - } else if (t.isDouble()) { - return byteOffset / 8; - } else if (t.isPointer()) { - return byteOffset / curMachDesc.pointerSizeInBytes(); - } else if (t.isArray()) { - return slot(t.asArray().getBaseElementType(), byteOffset, curMachDesc); - } else { - throw new RuntimeException("Illegal type " + t); - } - } - private StructLayout getLayout() { if (layout == null) { layout = StructLayout.create(0); |