Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Converting a byte array to an array of primitive types with unknown type in C#

I have the following problem. I have an array of bytes that I want to convert intro an array of primitive types. But I don't know the type. (This is given as an array of types). As a result I need an array of objects.

Of course I could use a switch on the types (there are only a limited number of them), but I wonder if there is a better solution for that.

Example:

byte[] byteData = new byte[] {0xa0,0x14,0x72,0xbf,0x72,0x3c,0x21}
Type[] types = new Type[] {typeof(int),typeof(short),typeof(sbyte)};

//some algorithm

object[] primitiveData = {...};
//this array contains an the following elements
//an int converted from 0xa0,0x14,0x72,0xbf
//a short converted from 0x72, 0x3c
//a sbyte converted from 0x21

Is there an algorithm for this or should I use a switch

like image 617
Willem Van Onsem Avatar asked Jul 25 '10 11:07

Willem Van Onsem


1 Answers

Here's my ideas:

object[] primitiveData = new object[byteData.Lenght];
for (int i = 0; i < bytesData.Lenght; i++)
{
     primitiveData[i] = Converter.ChangeType(bytesData[i], types[i]);
}

object[] primitiveData = new object[bytDate.Lenght];
for (int i = 0; i < bytesDate.Lenght; i++)
{
     Type t = types[i];
     if (t == typeof(int))
     {
          primitiveData[i] = Convert.ToInt32(bytesDate[i]);
     }
     else if (t == typeof(short))
     {
          primitiveData[i] = Convert.ToInt16(bytesDate[i]);
     }
     ..
}

var dic = new Dictionary<Type, Func<byte, object>>
{
    { typeof(int), b => Convert.ToInt32(b) },
    { typeof(short), b => Convert.ToInt16(b) },
    ...
};

byte[] byteData = new byte[] { 0xa0, 0x14, 0x72, 0xbf, 0x72, 0x3c, 0x21 };
Type[] types = new Type[] { typeof(int), typeof(short), typeof(sbyte) };

List<object> list = new List<object>(primitiveData.Length);
for (int i = 0; i < primitiveData.Length; i++)
{
     Byte b = byteData[i];
     Type t = types[i];
     Func<byte, object> func = dic[t];
     list.Add(func(b));
}
object[] primitiveData = list.ToArray();

byte[] byteData = new byte[] { 0xa0, 0x14, 0x72, 0xbf, 0x72, 0x3c, 0x21 };
// delegates to converters instead of just appropriate types
Func<byte, object>[] funcs = new Func<byte, object>[]
{
     b => Convert.ToInt32(b),
     b => Convert.ToInt16(b),
     b => Convert.ToSByte(b)
};

List<object> list = new List<object>(primitiveData.Length);
for (int i = 0; i < primitiveData.Length; i++)
{
     Byte b = byteData[i];
     Func<byte, object> func = funcs[i];
     list.Add(func(b));
}
object[] primitiveData = list.ToArray();

Note, that all my solutions above assumes the symmetry between byteData and types.

Otherwise you have to prepare a symmetric array which will contain an index of asymmetric array:

byte[] byteData = new byte[] { 0xa0, 0x14, 0x72, 0xbf, 0x72, 0x3c, 0x21 };
Type[] types = new Type[] { typeof(int), typeof(short), typeof(sbyte) }; // asymmetric 
int[] indexes = new int[] { 0, 0, 0, 0, 1, 2 }; // symmetric 
like image 166
abatishchev Avatar answered Sep 17 '22 03:09

abatishchev