Search code examples
c#parsingarraysbyte

Parsing byte array that contains different types of data


I have a fixed-length byte array that is 1250 bytes long. It may contain the following types of data:

  • Object A which consists of 5 bytes. The first byte contains the letter "A" and the next four bytes store an integer from 1 - 100000.

  • Object B which consists of 2 bytes. The first byte contains the letter "B" and the next byte contains an integer from 1 - 100.

  • Object C which consists of 50 bytes. All 50 bytes are used to store an ASCII-encoded string which will only consist of numbers and the following characters: - + ( and )

I don't know how many of each object type are in the byte array but I do know that they are grouped together (Object B, Object B, Object A, Object A, Object A, Object C, etc.). Most of the time when I parse a byte array, the array contains data of one type (all items are Object A, for example) so I know exactly how many bytes each item is comprised of and I just loop through the array processing the bytes. In this case, I have three different types of data that are all different lengths. I was thinking that I would need to do something like this:

int offset = 0;
while (offset <= 1250)
{
    string objectHeader = Encoding.ASCII.GetString(byteArray, offset, 1);

    if (objectHeader.Equals("A"))
    {
        // read 4 more bytes and then convert into int value (1 - 100000)
        index += 5;
    }
    else if (objectHeader.Equals("B"))
    {
        // read 1 more byte and then convert into int value (1 - 100)
        index += 2;
    }
    else
    {
        // read 49 more bytes and then convert into a string
        index += 50;
    }
}

Is there a better way of doing this?


Solution

  • Well, there seems to be a little confusion with offset and index, maybe you should be using a for-loop:

    for(int index = 0; index < 1250; index++)
    {
        switch(byteArray[index])
        {
             case (byte)'A':
                 index++;
                 int value = BitConverter.ToInt32(byteArray, index);
                 index += 4;
                 break;
    
           case (byte)'B':
                 index++;
                 // Read the next byte as integer.
                 int value = (int)byteArray[index];
                 index++;
                 break;
    
           case (byte)'C':  // string.
                 index++;
                 // Read the next 49 bytes as an string.
                 StringBuilder value = new StringBuilder(49);
                 for(int i = index; i < index + 49; index++)
                 {
                     if (byteArray[i] == 0) break;
                     value.Append(Converter.ToChar(byteArray[i]));
                 }
                 index+= 49;
                 break;
    
           case 0:  // Finished.
                 index = 1250;
                 break;
           default:
                 throw new InvalidArgumentException("Invalid byte array format");
        }
    }
    

    How do you see if there is no more objects? In my example I suggest it ends with a '\0'.

    Good luck with your quest.