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 <foun...@egrsoftware.com> 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 android-developers@googlegroups.com
To unsubscribe from this group, send email to
android-developers+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en

Reply via email to