summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2011-07-20 08:14:40 +0200
committerSven Gothel <[email protected]>2011-07-20 08:14:40 +0200
commit8b3057585930357bb16546f584d998953b084034 (patch)
tree5d7ffb74a36da6076d05657f2867c68c47068c7b
parent0a8e1566c766f3b5a5e71b5d80500034f1a614a8 (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.java216
-rw-r--r--src/java/com/jogamp/gluegen/JavaEmitter.java41
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);