Skip to content

Auto Growable Byte Buffer like a ByteBuilder

RichardHightower edited this page Oct 24, 2013 · 15 revisions

Boon Home | Boon Source | If you are new to boon, you might want to start here. Simple opinionated Java for the novice to expert level Java Programmer. Low Ceremony. High Productivity. A real boon to Java to developers!

Java Boon - Auto Growable Byte Buffer like a ByteBuilder

Many languages have slice notation (Ruby, Groovy and Python). Boon adds this to Java.####

Have you ever wanted an easy to use buffer array that grow automatically and/or you can give it a fix size and just add stuff to it? I have. I wrote one too.

Look.. I can write strings to it (it converts them to UTF-8).

        ByteBuf buf = new ByteBuf();
        buf.add(bytes("0123456789\n"));
        buf.add("0123456789\n");
        buf.add("0123456789\n");
        buf.add("0123456789\n");
        buf.add("0123456789\n");
        buf.add("0123456END\n");


    }

Then later I can read the String out of the buffer:

        String out = new String(buf.readAndReset(), 0, buf.len());
        assertEquals(66, buf.len());
        assertTrue(out.endsWith("END\n"));

I never have to set the size of the array. It will auto-grow as needed in an efficient manner.

If I know exactly how large my data is going to be than I can save some bounds checking by using createExact.

        ByteBuf buf = ByteBuf.createExact(66);
        buf.add(bytes("0123456789\n"));
        buf.add("0123456789\n");
        buf.add("0123456789\n");
        buf.add("0123456789\n");
        buf.add("0123456789\n");
        buf.add("0123456END\n");
        assertEquals(66, buf.len());

If I use create exact, then I am saying... hey.. I know exactly how big it can grow to and it will never go over this number and if it does...you can hit me over the head with a sack of rocks!

THROWS AN EXCEPTION!!!!

        ByteBuf buf = ByteBuf.createExact(22);
        buf.add(bytes("0123456789\n"));
        buf.add("0123456789\n");
        buf.add("0123456789\n");
        buf.add("0123456789\n");
        buf.add("0123456789\n");
        buf.add("0123456END\n");

It works with doubles.

        ByteBuf buf = ByteBuf.createExact(8);

        //add the double
        buf.add(10.0000000000001);

        byte[] bytes = buf.readAndReset();
        boolean worked = true;

        worked |= idxDouble(bytes, 0) == 10.0000000000001 || die("Double worked");

It works with float.

        ByteBuf buf = ByteBuf.createExact(8);

        //add the float
        buf.add(10.001f);

        byte[] bytes = buf.readAndReset();
        boolean worked = true;

        worked |= buf.len() == 4 || die("Float worked");


        //read the float
        float flt = idxFloat(bytes, 0);

        worked |= flt == 10.001f || die("Float worked");

It works with int.

        ByteBuf buf = ByteBuf.createExact(8);

        //Add the int to the array
        buf.add(99);

        byte[] bytes = buf.readAndReset();
        boolean worked = true;


        //Read the int back
        int value = idxInt(bytes, 0);

        worked |= buf.len() == 4 || die("Int worked length = 4");
        worked |= value == 99 || die("Int worked value was 99");

It works with char.

        ByteBuf buf = ByteBuf.createExact(8);

        //Add the char to the array
        buf.add('c');

        byte[] bytes = buf.readAndReset();
        boolean worked = true;


        //Read the char back
        int value = idxChar(bytes, 0);

        worked |= buf.len() == 2 || die("char worked length = 4");
        worked |= value == 'c' || die("char worked value was 'c'");

It works with short.

        ByteBuf buf = ByteBuf.createExact(8);

        //Add the short to the array
        buf.add((short)77);

        byte[] bytes = buf.readAndReset();
        boolean worked = true;


        //Read the short back
        int value = idxShort(bytes, 0);

        worked |= buf.len() == 2 || die("short worked length = 2");
        worked |= value == 77 || die("short worked value was 77");

It even works with bytes.

        ByteBuf buf = ByteBuf.createExact(8);

        //Add the byte to the array
        buf.add( (byte)33 );

        byte[] bytes = buf.readAndReset();
        boolean worked = true;


        //Read the byte back
        int value = idx(bytes, 0);

        worked |= buf.len() == 1 || die("byte worked length = 1");
        worked |= value == 33 || die("byte worked value was 33");

You can add all sorts of primitives to your byte array.

        boolean worked = true;
        ByteBuf buf = ByteBuf.create(1);

        //Add the various to the array
        buf.add( (byte)  1 );
        buf.add( (short) 2 );
        buf.add( (char)  3 );
        buf.add(         4 );
        buf.add( (float) 5 );
        buf.add( (long)  6 );
        buf.add( (double)7 );

        worked |= buf.len() == 29 || die("length = 29");


        byte[] bytes = buf.readAndReset();

        byte myByte;
        short myShort;
        char myChar;
        int myInt;
        float myFloat;
        long myLong;
        double myDouble;

        myByte    =   idx       ( bytes, 0 );
        myShort   =   idxShort  ( bytes, 1 );
        myChar    =   idxChar   ( bytes, 3 );
        myInt     =   idxInt    ( bytes, 5 );
        myFloat   =   idxFloat  ( bytes, 9 );
        myLong   =    idxLong   ( bytes, 13 );
        myDouble  =   idxDouble ( bytes, 21 );

        worked |= myByte   == 1 || die("value was 1");
        worked |= myShort  == 2 || die("value was 2");
        worked |= myChar   == 3 || die("value was 3");
        worked |= myInt    == 4 || die("value was 4");
        worked |= myFloat  == 5 || die("value was 5");
        worked |= myLong   == 6 || die("value was 6");
        worked |= myDouble == 7 || die("value was 7");

Once you call byte[] bytes = buf.readAndReset() then you are done with buf. Once you ask for the bytes, it becomes useless as it sets the internal byte array to nothing. It is ok. Just create another!

You can even use the buffer you were just using as in

    ByteBuf buf2 = new ByteBuf.create(bytes); 

This is because no buffer gets copied. ByteBuf writes to the buffer you give it. If you want another copy to be given to ByteBuf then do this:

    ByteBuf buf2 = new ByteBuf.create( copy(bytes) ); 

This is boon after all. :)

Clone this wiki locally