Interesting.. Thanks for your input Elliot.. I do want to clarify
things as you allude that the byte order switch occurs on duplicate()
and other methods is a specific regression with Honeycomb; is this
correct?

Elliott:
"allocate/allocateDirect/map/wrap/duplicate/slice always return a big-
endian buffer."

I had a feeling it was byte order related with the 65536 to 256
change.

I ask because duplicate() on the desktop / J2SE 5.0 and the G2x /
Android 2.2 maintain byte order and here is what I get:

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

So my understanding is that Honeycomb has a defect for duplicate(),
slice(), etc.

I was able to update the buffer creation in my extended NIO buffer API
to create them like this:

      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();

--------------

It does suck that one needs to have a ByteBuffer to change the order.
There are copy constructors in my NIO API (that don't appear to be
used or don't cause any problems presently on Honeycomb) that only
have access to the specific buffer (FloatBuffer, etc.) and order(<byte
order>) can't be called on them. Only ByteBuffer.

However with the above change now things work well on Honeycomb and
Auriga3D is fully back working.. phew..

Thanks for mentioning that this will be fixed in ICS and providing the
last little missing link I needed to get things working again
regardless of the regression and maintain the contract of my extended
API.

Regards,
--Mike


On Apr 28, 3:13 pm, Elliott Hughes <e...@google.com> wrote:
> from the unit tests:
>
>         // duplicate always returns a big-endian buffer.
>         b.order(ByteOrder.BIG_ENDIAN);
>         assertEquals(ByteOrder.BIG_ENDIAN, b.duplicate().order());
>         b.order(ByteOrder.LITTLE_ENDIAN);
>         assertEquals(ByteOrder.BIG_ENDIAN, b.duplicate().order());
>
> allocate/allocateDirect/map/wrap/duplicate/slice always return a big-
> endian buffer.
> asXBuffer (asCharBuffer et cetera) always returns a buffer with the
> same endian as the source.
> ...except for asReadOnlyBuffer, which always returns a big-endian
> buffer. (note that this is broken in Honeycomb; ICS gets it right.)
>
> the API's sufficiently unfriendly that any time you make a new Buffer
> you should probably call order(ByteOrder), just to preserve your own
> sanity.
>
> (or only ever run your code on a big-endian device, which is
> presumably how the API ended up this way... SPARC lives!)
>
>  --elliott
>
> On Apr 28, 2:59 pm, MichaelEGR <foun...@egrsoftware.com> wrote:
>
>
>
>
>
>
>
> > CRITICAL NIO FLAW FOUND
>
> > And I did the leg work again here and put in ~4 hours to reduce the
> > bug to a most fundamental example that should be a unit test in
> > Android. That it is not and this bug made it to production / shipping
> > is amazing.
>
> > On all Java 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.
>
> > Being that this is a critical flaw.. Do you guys offer rewards or is
> > that only security flaws? I'll take my $1,337 check or a Google I/O
> > ticket.
>
> > You guys do understand that the 4 hours I did to reduce this critical
> > bug to an easily demonstrable level I'd charge more than a Google I/O
> > ticket on an invoice.
>
> > To run on Android simply call com.egrsoftware.niotest.NIOTest.test()
> > from onCreate() of any Activity and check system output via adb logcat
> > or ddms.
>
> > --------------------------------------------------------------------------- 
> > -----------
>
> > 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