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