I want to replace every occurrence of one of those magic 2-byte packages in my List<byte> with a single byte:
{ 0xF8, 0x00 } -> Replace with 0xF8
{ 0xF8, 0x01 } -> Replace with 0xFB
{ 0xF8, 0x02 } -> Replace with 0xFD
{ 0xF8, 0x03 } -> Replace with 0xFE
For example:
List<byte> message 
    = new List<byte> { 0xFF, 0xFF, 0xFB, 0xF8, 0x00, 0xF8, 0x01, 0xF8, 0x02, 0xF8, 0x03, 0xFE };
// will be converted to:
List<byte> expected 
    = new List<byte> { 0xFF, 0xFF, 0xFB, 0xF8, 0xFB, 0xFD, 0xFE, 0xFE };
This is my solution so far, which works but I don't like it because its readability is quite bad:
public static void RemoveEscapeSequences(List<byte> message)
{
    // skipped parameter checks
    for (int index = 0; index < message.Count - 1; ++index)
    {
        if (message[index] == 0xF8)
        {
            // found an escaped byte, look at the following byte to determine replacement
            switch (message[index + 1])
            {
                case 0x0:
                    message[index] = 0xF8;
                    message.RemoveAt(index + 1);
                    break;
                case 0x1:
                    message[index] = 0xFB;
                    message.RemoveAt(index + 1);
                    break;
                case 0x2:
                    message[index] = 0xFD;
                    message.RemoveAt(index + 1);
                    break;
                case 0x3:
                    message[index] = 0xFE;
                    message.RemoveAt(index + 1);
                    break;
            }
        }
    }
}       
Is there a shorter solution with improved readability?
You can do something like this - it'll be slightly slower, though:
public static void RemoveEscapeSequences(List<byte> message)
{
    var replaceBytes = new Dictionary<byte, byte>()
    {
        {0x00, 0xF8}, {0x01, 0xFB}, {0x02, 0xFD}, {0x03, 0xFE}
    };
    // skipped parameter checks
    for (int index = 0; index < message.Count - 1; ++index)
    {
        if (message[index] == 0xF8)
        {
            if(replaceBytes.ContainsKey(message[index + 1]))
            {
                message[index] = replaceBytes[message[index + 1]];
                message.RemoveAt(index + 1);
            }
        }
    }
}  
                        You can use following extension method:
public static IEnumerable<byte> Escape(this IEnumerable<byte> source)
{
    if (source == null)     
        throw new ArgumentNullException("source");
    using (var enumerator = source.GetEnumerator())
    {
        while (enumerator.MoveNext())
        {
            byte current = enumerator.Current;
            if (current != 0xF8)
            {
                yield return current;
                continue;
            }
            if (!enumerator.MoveNext())
                yield return current;
            byte next = enumerator.Current;
            switch (next)
            {
                case 0x00: yield return 0xF8; break;
                case 0x01: yield return 0xFB; break;
                case 0x02: yield return 0xFD; break;
                case 0x03: yield return 0xFE; break;
                default:
                    yield return current;
                    yield return next;
                    break;
            }
        }
    }
}
Usage:
List<byte> result = message.Escape().ToList();
foreach(var b in message.Escape())
     Console.Write("0x{0:x} ", b);
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With