I am working on a serial commnuication protocol. In this protocol, the packt consists of bytes, and it should start and end with 0x7E.
The protocol indicates that any byte which is 0x7E or 0x7D should be escaped to 0x7D 0x5E or 0x7d 0x5D accordingly.
Here is a sample packet:
7E 40 09 00 BE EF 05 7E 06 01 02 03 04 05 7E
As you can see, byte[7] in this packet should be replaced by 2 bytes 0x7D 0x5E. To this I wrote the method below but it fails to do this task:
private List<byte> Finalize(List<byte> packet)
{
int u = 1; //keep track of end of pack
//because if escape characters are present
//end bit will be shifted to right
//Walk through list and fix escape bytes
for (int i = 1; i < packet.Count; i++)
{
if (packet[i] == 0x7D)
{
packet[u] = 0x7D;
packet[u + 1] = 0x5D;
u += 2;
}
else if (packet[i] == 0x7E) //Sync Byte
{
packet[u] = 0x7D;
packet[u + 1] = 0x5E;
u += 2;
}
else
{
packet[u] = packet[i]; //Exception here!!
u++;
}
}
return packet;
}
The method throws an ArgumentOutOfRangeException. Can someone tell me what can be the problem!? I guess I implemented a correct logic but it seems I didn’t handle indexes properly!
The loop is starting at index 1, because its the start byte and it shouldnt be changed. it also shouldn’t change the last byte in the list which is 0x7E, the end byte!
First of all you are loosing the data when you overwrite your byte next to bytes with values
0x7Dand0x7E. Second, you are changingufaster thaniwhich produces the Exception mentioned. When you escape your bytes, you add 2 toubut in that iteration of theforloop, i is only incremented. Third, the better approach for this would definitely be while loop.To handle the first problem you should add more elements to the list.
Insertwould do the trick instead of shifting everything manually to the right. The second problem you can solve by using only one counter. Check the code:The other solution would be creating new list within the method and adding appropriate values to it.
while (i < packet.Count-1)is because I think that you don’t want to escape the ending byte. Have in mind that the last byte in your list ispacket[packet.Count-1]notpacket[packet.Count]