Some more clarification... The byte order is not preserved with
duplicate(), slice() and potentially other NIO methods, but those two
for sure.
So if you have a FloatBuffer w/ native byte order of LITTLE_ENDIAN
call duplicate() on it will result in a view with BIG_ENDIAN byte
order on Honeycomb.
Be careful. This could break a lot of 3rd party APIs that even
moderately use the functionality of NIO.
Here is the output of the test app above with addition of showing byte
order:
"duplicate()" on the desktop / J2SE 5.0 and the G2x /
Android 2.2 maintain byte order:
NIOTest ----------
Native ByteOrder: LITTLE_ENDIAN
buffer byte order: LITTLE_ENDIAN
buffer2 byte order: LITTLE_ENDIAN
bufferWrite2 byte order: LITTLE_ENDIAN
buffer.get(): 65536
buffer2.get(): 65536
On the G-Slate / Honeycomb:
NIOTest ----------
Native ByteOrder: LITTLE_ENDIAN
buffer byte order: LITTLE_ENDIAN
buffer2 byte order: LITTLE_ENDIAN
bufferWrite2 byte order: BIG_ENDIAN
buffer.get(): 65536
buffer2.get(): 256
If you must call duplicate() you should do it on the ByteBuffer and
explicitly call order(<byte order>). The following code is how I
create a duplicate FloatBuffer now for a "read / write head" on the
buffer
-----------
ByteBuffer tempBuffer = direct ?
ByteBuffer.allocateDirect(capacity * s_SIZE_OF_FLOAT) :
ByteBuffer.allocate(capacity * s_SIZE_OF_FLOAT);;
buffer1 = nativeOrder ?
tempBuffer.order(ByteOrder.nativeOrder()).asFloatBuffer() :
tempBuffer.asFloatBuffer();
read = nativeOrder ?
tempBuffer.asReadOnlyBuffer().order(ByteOrder.nativeOrder()).asFloatBuffer( ) :
tempBuffer.asReadOnlyBuffer().asFloatBuffer();
write = nativeOrder ?
tempBuffer.duplicate().order(ByteOrder.nativeOrder()).asFloatBuffer() :
tempBuffer.duplicate().asFloatBuffer();
-----------
Apparently this will be fixed in ICS. Be warned though this
potentially can break a lot of code that depends on NIO.
Regards,
--Mike
On Apr 28, 3:22 pm, MichaelEGR <[email protected]> wrote:
> Greets,
>
> I found a critical Java NIO flaw in Honeycomb / Android 3.0.
>
> If "duplicate()" is called on a Buffer and that duplicate view is used
> to write to the buffer data integrity is not guaranteed. This is a
> regression for Honeycomb only at this point.
>
> I got stuck with a ~45 hour debug cycle to catch this as it affected
> my usage of the NIO and the OpenGL ES API resulting in no rendering
> due to bad data. Unfortunately any usage of the NIO API and
> duplicate() will cause problems regardless if it's networking, other
> JNI usage, etc. This is a critical NIO flaw.
>
> Please vote for this issue as it's critical and could affect a lot of
> code out there; not just mine...
>
> http://code.google.com/p/android/issues/detail?id=16434&colspec=ID%20...
>
> For fun you can read about the "pain and horror" this caused me:
>
> http://groups.google.com/group/android-developers/browse_thread/threa...
>
> Test Example:
>
> On all Java / J2SE platforms 1.4, 5.0, 6.0 and Android OS version 1.0
> - 2.3 the value of index 1 of buffer & buffer2 is 0x10000 (65535). On
> Android 3.0 / Honeycomb index 1 of buffer is 65535 and buffer 2 is
> 256.. Clearly a major if not critical flaw in Honeycomb for usage of
> the NIO API and calling duplicate() on a Buffer. Any code using NIO
> and duplicate() will likely break on Honeycomb.
>
> ---------------------
>
> package
> com.egrsoftware.niotest;
>
> import
> java.nio.ByteBuffer;
> import
> java.nio.ByteOrder;
> import
> java.nio.IntBuffer;
>
> /
> **
> * NIOTest - Extremely simple unit test that Google should include in
> Android because it catches a bug in NIO that is
> * found in Android 3.0 / Honeycomb. This is a really nefarious bug as
> the affected code could be networking code, any
> * native JNI code, or in my case 3D rendering via the Android OpenGL
> ES API. Any code using NIO and "duplicate()" is
> *
> broken.
>
> *
> * On all Java platforms with NIO and Android versions 1.0 to 2.3 both
> buffers should print out 65535. On Android /
> * Honeycomb the 1st value in buffer 1 is 65535 and buffer 2 is
> 256!!!! Clearly a bug that any simple unit testing
> * should have found. This bug affects _ALL_ code that uses the NIO
> duplicate() method on a Buffer. The fall out of
> * this is immense! This is a critical
> bug!
>
> */
> public class
> NIOTest
> {
> private static int s_SIZE_OF_INT =
> 4;
>
> public static void
> test()
>
> {
> IntBuffer buffer = ByteBuffer.allocateDirect(1 *
> s_SIZE_OF_INT).order(
>
> ByteOrder.nativeOrder()).asIntBuffer();
>
> IntBuffer buffer2 = ByteBuffer.allocateDirect(1 *
> s_SIZE_OF_INT).order(
>
> ByteOrder.nativeOrder()).asIntBuffer();
>
> IntBuffer bufferWrite2 =
> buffer2.duplicate();
>
> buffer.put(0, 0x10000); //put
> 65535
> bufferWrite2.put(0,
> 0x10000);
>
> System.err.println("NIOTest
> ----------");
> System.err.println("buffer.get(): "
> +buffer.get());
> System.err.println("buffer2.get(): "
> +buffer2.get());
> }
>
> public static void main(String
> args[])
>
> {
>
> test();
> }
>
>
>
>
>
>
>
> }
--
You received this message because you are subscribed to the Google
Groups "Android Developers" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en