Search code examples
javaarraysmqttbytearrayoutputstreamandroid-open-accessory

Initializing ByteArrayOutputStream?


I am new to the MQTT and Android Open Accessory "AOA". while reading a tutorial I realized that, before any attempt to write to the variable of the type ByteArrayOutputStream,however, 0 or 0x00 should be written to that variable first.

Is this some kind of initialisation? Below is an example of that:

EX_1

variableHeader.write(0x00);
variableHeader.write(PROTOCOL_NAME.getBytes("UTF-8").length);
variableHeader.write(PROTOCOL_NAME.getBytes("UTF-8"));

EX_2

public static byte[] connect() throws UnsupportedEncodingException, IOException {
   String identifier = "android";
   ByteArrayOutputStream payload = new ByteArrayOutputStream();
   payload.write(0);
   payload.write(identifier.length());
}

Solution

  • This is not any kind of initialization needed by the ByteArrayOutputStream. Calling write(0) simply inserts a 0-byte as a the first byte in the byte array.

    Instead, the byte must have meaning to the MQTT protocol. I'm not familiar with it, but a quick look at the MQTT protocol specification reveals that strings are encoded by writing the string bytes in UTF-8, prefixed by a 2-byte length field, upper byte first.

    In both the examples you give, strings are being written, but it is only writing one length byte. The 0 byte, then, must be the other length byte. I'm sure that's what it is. The code is a bit sloppy: it assumes that the strings in your case are less than 256 bytes long, so it can always assume the upper length byte is 0.

    If there is any possibility of the "protocol name" being 256 bytes or longer, then the proper way to write this code:

    variableHeader.write(0x00);
    variableHeader.write(PROTOCOL_NAME.getBytes("UTF-8").length);
    variableHeader.write(PROTOCOL_NAME.getBytes("UTF-8"));
    

    would be:

    byte[] stringBytes = PROTOCOL_NAME.getBytes("UTF-8");
    variableHeader.write(stringBytes.length >> 8); // upper length byte
    variableHeader.write(stringBytes.length & 0xFF); // lower length byte
    variableHeader.write(stringBytes); // actual data