/// <summary> /// Creates a struct of a specified type by an array of bytes. /// </summary> /// <param name="structType">The struct type</param> /// <param name="bytes">The array of bytes</param> /// <returns>The object depending on the struct type or null if fails(array-length != struct-length</returns> public static object FromBytes(Type structType, byte[] bytes) { if (bytes == null) { return(null); } if (bytes.Length != GetStructSize(structType)) { return(null); } // and decode it int bytePos = 0; int bitPos = 0; double numBytes = 0.0; object structValue = Activator.CreateInstance(structType); System.Reflection.FieldInfo[] infos = structValue.GetType().GetFields(); foreach (System.Reflection.FieldInfo info in infos) { switch (info.FieldType.Name) { case "Boolean": // get the value bytePos = (int)Math.Floor(numBytes); bitPos = (int)((numBytes - (double)bytePos) / 0.125); if ((bytes[bytePos] & (int)Math.Pow(2, bitPos)) != 0) { info.SetValue(structValue, true); } else { info.SetValue(structValue, false); } numBytes += 0.125; break; case "Byte": numBytes = Math.Ceiling(numBytes); info.SetValue(structValue, (byte)(bytes[(int)numBytes])); numBytes++; break; case "Int16": numBytes = Math.Ceiling(numBytes); if ((numBytes / 2 - Math.Floor(numBytes / 2.0)) > 0) { numBytes++; } // hier auswerten ushort source = Word.FromBytes(bytes[(int)numBytes + 1], bytes[(int)numBytes]); info.SetValue(structValue, source.ConvertToShort()); numBytes += 2; break; case "UInt16": numBytes = Math.Ceiling(numBytes); if ((numBytes / 2 - Math.Floor(numBytes / 2.0)) > 0) { numBytes++; } // hier auswerten info.SetValue(structValue, Word.FromBytes(bytes[(int)numBytes + 1], bytes[(int)numBytes])); numBytes += 2; break; case "Int32": numBytes = Math.Ceiling(numBytes); if ((numBytes / 2 - Math.Floor(numBytes / 2.0)) > 0) { numBytes++; } // hier auswerten uint sourceUInt = DWord.FromBytes(bytes[(int)numBytes + 3], bytes[(int)numBytes + 2], bytes[(int)numBytes + 1], bytes[(int)numBytes + 0]); info.SetValue(structValue, sourceUInt.ConvertToInt()); numBytes += 4; break; case "UInt32": numBytes = Math.Ceiling(numBytes); if ((numBytes / 2 - Math.Floor(numBytes / 2.0)) > 0) { numBytes++; } // hier auswerten info.SetValue(structValue, DWord.FromBytes(bytes[(int)numBytes], bytes[(int)numBytes + 1], bytes[(int)numBytes + 2], bytes[(int)numBytes + 3])); numBytes += 4; break; case "Double": numBytes = Math.Ceiling(numBytes); if ((numBytes / 2 - Math.Floor(numBytes / 2.0)) > 0) { numBytes++; } // hier auswerten info.SetValue(structValue, Double.FromByteArray(new byte[] { bytes[(int)numBytes], bytes[(int)numBytes + 1], bytes[(int)numBytes + 2], bytes[(int)numBytes + 3] })); numBytes += 4; break; default: var buffer = new byte[GetStructSize(info.FieldType)]; if (buffer.Length == 0) { continue; } Buffer.BlockCopy(bytes, (int)Math.Ceiling(numBytes), buffer, 0, buffer.Length); info.SetValue(structValue, FromBytes(info.FieldType, buffer)); numBytes += buffer.Length; break; } } return(structValue); }
/// <summary> /// Creates a struct of a specified type by an array of bytes. /// </summary> /// <param name="sourceClass"></param> /// <param name="classType">The struct type</param> /// <param name="bytes">The array of bytes</param> /// <returns>The object depending on the struct type or null if fails(array-length != struct-length</returns> public static void FromBytes(object sourceClass, Type classType, byte[] bytes) { if (bytes == null) { return; } if (bytes.Length != GetClassSize(classType)) { return; } // and decode it int bytePos = 0; int bitPos = 0; double numBytes = 0.0; var properties = sourceClass.GetType().GetProperties(); foreach (var property in properties) { switch (property.PropertyType.Name) { case "Boolean": // get the value bytePos = (int)Math.Floor(numBytes); bitPos = (int)((numBytes - (double)bytePos) / 0.125); if ((bytes[bytePos] & (int)Math.Pow(2, bitPos)) != 0) { property.SetValue(sourceClass, true, null); } else { property.SetValue(sourceClass, false, null); } numBytes += 0.125; break; case "Byte": numBytes = Math.Ceiling(numBytes); property.SetValue(sourceClass, (byte)(bytes[(int)numBytes]), null); numBytes++; break; case "Int16": numBytes = Math.Ceiling(numBytes); if ((numBytes / 2 - Math.Floor(numBytes / 2.0)) > 0) { numBytes++; } // hier auswerten ushort source = Word.FromBytes(bytes[(int)numBytes + 1], bytes[(int)numBytes]); property.SetValue(sourceClass, source.ConvertToShort(), null); numBytes += 2; break; case "UInt16": numBytes = Math.Ceiling(numBytes); if ((numBytes / 2 - Math.Floor(numBytes / 2.0)) > 0) { numBytes++; } // hier auswerten property.SetValue(sourceClass, Word.FromBytes(bytes[(int)numBytes + 1], bytes[(int)numBytes]), null); numBytes += 2; break; case "Int32": numBytes = Math.Ceiling(numBytes); if ((numBytes / 2 - Math.Floor(numBytes / 2.0)) > 0) { numBytes++; } // hier auswerten uint sourceUInt = DWord.FromBytes(bytes[(int)numBytes + 3], bytes[(int)numBytes + 2], bytes[(int)numBytes + 1], bytes[(int)numBytes + 0]); property.SetValue(sourceClass, sourceUInt.ConvertToInt(), null); numBytes += 4; break; case "UInt32": numBytes = Math.Ceiling(numBytes); if ((numBytes / 2 - Math.Floor(numBytes / 2.0)) > 0) { numBytes++; } // hier auswerten property.SetValue(sourceClass, DWord.FromBytes(bytes[(int)numBytes], bytes[(int)numBytes + 1], bytes[(int)numBytes + 2], bytes[(int)numBytes + 3]), null); numBytes += 4; break; case "Double": numBytes = Math.Ceiling(numBytes); if ((numBytes / 2 - Math.Floor(numBytes / 2.0)) > 0) { numBytes++; } // hier auswerten property.SetValue(sourceClass, Double.FromByteArray(new byte[] { bytes[(int)numBytes], bytes[(int)numBytes + 1], bytes[(int)numBytes + 2], bytes[(int)numBytes + 3] }), null); numBytes += 4; break; default: var buffer = new byte[GetClassSize(property.PropertyType)]; if (buffer.Length == 0) { continue; } Buffer.BlockCopy(bytes, (int)Math.Ceiling(numBytes), buffer, 0, buffer.Length); var propClass = Activator.CreateInstance(property.PropertyType); FromBytes(propClass, property.PropertyType, buffer); property.SetValue(sourceClass, propClass, null); numBytes += buffer.Length; break; } } }