I have a string value:
Example:
string msg = "array('B', [255, 216, 255, 224, 0, 16, 74, 70, 73, 70, 0, 1, 1, 0, 0,
1, 0, 1, 0, 0, 255, 219, 0, 67, 0, 2, 1, 1, 1, 1, 1, 2, 1, 1, 1, 2, 2,
2, 2, 2, 4, 3, 2, 2, 2, 2, 5, 4, 4, 3, 4, 6, 5, 6, 6, 6, 5, 6, 6, 6,
7, 9, 8, 6, 7, 9, 7, 6, 6, 8, 11, 8, 9, 10, 10, 10, 10, 10, 6, 8, 11,
12, 11, 10, 12, 9, 10, 10, 10, 255, 219, 0, 67, 1, 2, 2, 2, 2, 2, 2,
5, 3, 3, 5, 10, 7, 6, 7, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10])"
I want to convert this string value to type byte[].
private byte[] data;
//after type conversion from string to byte array
Debug.Log("data in byte array is: " data);
Output should be:
data in byte array is: [255, 216, 255, 224, 0, 16, 74, 70, 73, 70, 0, 1, 1, 0, 0, 1, 0, 1, 0, 0, 255, 219, 0, 67, 0, 2, 1, 1, 1, 1, 1, 2, 1, 1, 1, 2, 2, 2, 2, 2, 4, 3, 2, 2, 2, 2, 5, 4, 4, 3, 4, 6, 5, 6, 6, 6, 5, 6, 6, 6, 7, 9, 8, 6, 7, 9, 7, 6, 6, 8, 11, 8, 9, 10, 10, 10, 10, 10, 6, 8, 11, 12, 11, 10, 12, 9, 10, 10, 10, 255, 219, 0, 67, 1, 2, 2, 2, 2, 2, 2, 5, 3, 3, 5, 10, 7, 6, 7, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10]
Since the actual string msg is a very large value, I want to do this with minimum execution time possible.
CodePudding user response:
Looks like a fairly simple parsing problem. We could run up a full parser for the format, but that's probably well beyond your needs.
Let's assume instead that your msg
is always going to be in the format shown, starting with "array('B', ["
, ending with "])"
and having 0 or more comma-separated decimal values. Since any option you choose is going to scan the string at least once, we can design code around doing exactly that.
The actual content contains only 4 types of characters:
- digit (
0
-9
) - comma (
,
) - space (
- end-array (
]
)
We can iterate through the characters starting at the first character after the start-array ([
at offset 11) and do something with each of those character types: ignore it, update the current value, yield the current value and/or exit.
If all of the assumptions are correct then this is a simple process. One scan through the characters, no allocations in the parser itself. Here's a sample:
IEnumerable<byte> ParseArrayMsg(string msg)
{
if (!msg.StartsWith("array('B', [") || !msg.EndsWith("])"))
yield break;
int value = 0;
for (int i = msg.IndexOf('[') 1; i < msg.Length; i )
{
var c = msg[i];
if (c == ',' || c == ']')
{
yield return (byte)value;
value = 0;
if (c == ']')
break;
}
else if (char.IsDigit(c))
value = value * 10 (int)(c - '0');
else if (c != ' ')
throw new Exception($"Invalid character '{c}' at index '{i}'.");
}
}
The returned enumerable can then be processed however you like.
Your code won't actually produce the output you want, but this will:
var data = ParseArrayMsg(msg).ToArray();
Console.WriteLine($"Data in byte array is: [{string.Join(", ", data.Select(b => b.ToString()))}]");
Data in byte array is: [255, 216, 255, 224, 0, 16, 74, 70, 73, 70, 0, 1, 1, 0, 0, 1, 0, 1, 0, 0, 255, 219, 0, 67, 0, 2, 1, 1, 1, 1, 1, 2, 1, 1, 1, 2, 2, 2, 2, 2, 4, 3, 2, 2, 2, 2, 5, 4, 4, 3, 4, 6, 5, 6, 6, 6, 5, 6, 6, 6, 7, 9, 8, 6, 7, 9, 7, 6, 6, 8, 11, 8, 9, 10, 10, 10, 10, 10, 6, 8, 11, 12, 11, 10, 12, 9, 10, 10, 10, 255, 219, 0, 67, 1, 2, 2, 2, 2, 2, 2, 5, 3, 3, 5, 10, 7, 6, 7, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10]
CodePudding user response:
You can try like the following:
string yourString= "Your String";
// Convert a C# string to a byte array
byte[] bytes = Encoding.ASCII.GetBytes(yourString);