1

I have a task. From InputStream I should receive multi part message. First four bytes it is message length, and other bytes it is message body. At the same time can receive many messages. For example: 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16

there is

1,2,3,4 - length(in this case 4), 3,4,5,6 - body
7,8,9,10 - length (6), 11,12,13,14,15,16 - body

and so on

Length I compute by this method:

public static int byteArrayToInt(byte[] paRawBytes, int piOffset, boolean pbBigEndian) {

    int iRetVal = -1;

    if(paRawBytes.length < piOffset + 4)
        return iRetVal;

    int iLowest;
    int iLow;
    int iMid;
    int iHigh;

    if(pbBigEndian)
    {
        iLowest = paRawBytes[piOffset + 3];
        iLow    = paRawBytes[piOffset + 2];
        iMid    = paRawBytes[piOffset + 1];
        iHigh   = paRawBytes[piOffset];
    }
    else
    {
        iLowest = paRawBytes[piOffset];
        iLow    = paRawBytes[piOffset + 1];
        iMid    = paRawBytes[piOffset + 2];
        iHigh   = paRawBytes[piOffset + 3];
    }

    // Merge four bytes to form a 32-bit int value.
    iRetVal = (iHigh << 24) | (iMid << 16) | (iLow << 8) | (0xFF & iLowest);

    return iRetVal;
}

And more:

private static void getEventsList(byte[] bytesFromInputStream) {


    int start = 4;

    int end = getLength(bytesFromInputStream) + 4;

    byte[] tmp;

    tmp = Arrays.copyOfRange(bytesFromInputStream, start, end);


    eventsArrayList.add(tmp);

    if (bytesFromInputStream.length > end) {

        byte[] newArray = Arrays.copyOfRange(bytesFromInputStream, end, bytesFromInputStream.length);


        getEventsList(newArray);
    }


}

private static short getLength(byte[] bytes) {
    return ByteUtils.byteArrayToInt(Arrays.copyOfRange(bytes, 0, 4), 0, true);
}

But it is not working and I have not more idea. Help me please

NikedLab
  • 883
  • 4
  • 11
  • 31
  • What is the output right now (that is wrong)? Might help in debugging... – justderb Oct 22 '12 at 20:41
  • First, have you tested your `byteArrayToInt` method with some example inputs? The bitwise operations don't look quite right to me. There are some example implementations in the answers to [this question](http://stackoverflow.com/questions/7619058/convert-a-byte-array-to-integer-in-java-and-vise-versa) – DNA Oct 22 '12 at 20:43
  • byteArrayToInt work fine, first two messages read good, but other has incorrect length – NikedLab Oct 22 '12 at 20:47
  • I need recursive function. I never know how many parts I receive in time – NikedLab Oct 22 '12 at 20:50
  • It's possible to do this either recursively or iteratively, though doing it recursively is a bad idea if there may be a very large number of messages, as you may cause a stack overflow. – DNA Oct 22 '12 at 20:52
  • This doesn't compile, unless you have another implementation of byteArrayToInt()? The method takes an offset, but the invocation doesn't provide one... – DNA Oct 22 '12 at 20:56
  • Sorry, I forget )) I update getLength() method, offset should be zero – NikedLab Oct 22 '12 at 21:09

1 Answers1

1

The code you originally provided doesn't quite seem to compile (maybe that was the problem you were having, but you didn't really specify)?

To fix it, I had to get getLength() to return a short by casting the result of byteArrayToInt to short. Or you could just return an int instead. I removed the static reference to ByteUtils because I put all the methods into one class.

I also added an offset of 0 to the call to byteArrayToInt so the method signatures match.

After that, your code seems to work, at least for a few simple cases, e.g:

byte[] message = new byte[]{0,0,0,1, 1, 0,0,0,2, 2,3};
getEventsList(message);

produces:

Got a message of length: 1
Content 1
Got a message of length: 2
Content 2
Content 3

(I added some println statements too)

Your byteArrayToInt method does not seem to work correctly for large values (more than 16 bits). There are some example implementations (including some one-liners) in the answers to this question.

Community
  • 1
  • 1
DNA
  • 42,007
  • 12
  • 107
  • 146