/ Published in: C#
<p>This example uses a Swap member to enumerate the struct’s fields and swap multi-byte fields. It doesn’t traverse nested structs.</p>
<p>It would be nice if dot.net has something equivalent to ‘#pragma endian big’ as seen in some compilers. There might be a way to leverage marshaling to automatically endianize multi-byte values.</p>
<p>This example uses:
* System.Net.IPAddress.NetworkToHostOrder for byte swapping
* unchecked() to convert a value of, say, 0 × 87654321 to a Int32 without a runtime error
* foreach (System.Reflection.FieldInfo field in typeof(MyStruct).GetFields()) to enumerate structure members
* TypeCode typeCode = Type.GetTypeCode(fieldValue.GetType()); to get the underlying type enumeration (typeof of verbose).
* SetValue and GetValue to access struct members.
* Boxed object of struct - this was necessary only because SetValue didn’t work on structs. It failed quietly.</p>
<p>It would be nice if dot.net has something equivalent to ‘#pragma endian big’ as seen in some compilers. There might be a way to leverage marshaling to automatically endianize multi-byte values.</p>
<p>This example uses:
* System.Net.IPAddress.NetworkToHostOrder for byte swapping
* unchecked() to convert a value of, say, 0 × 87654321 to a Int32 without a runtime error
* foreach (System.Reflection.FieldInfo field in typeof(MyStruct).GetFields()) to enumerate structure members
* TypeCode typeCode = Type.GetTypeCode(fieldValue.GetType()); to get the underlying type enumeration (typeof of verbose).
* SetValue and GetValue to access struct members.
* Boxed object of struct - this was necessary only because SetValue didn’t work on structs. It failed quietly.</p>
Expand |
Embed | Plain Text
Copy this code and paste it in your HTML
public struct MyStruct { public UInt32 u4; public int s4; public UInt16 u2; public short s2; public UInt64 u8; public Int64 s8; // byte-swap members of this struct. public MyStruct Swap() { // The copy is made becuase SetValue won't work on a struct. // Boxing was used because SetValue works on classes/objects. // Unfortunately, it results in 2 copy operations. object thisBoxed = this; // Why make a copy? // System.Net.IPAddress.NetworkToHostOrder is used to perform byte swapping. // To convert unsigned to signed, 'unchecked()' was used. // See http://stackoverflow.com/questions/1131843/how-do-i-convert-uint-to-int-in-c // Enumerate each structure field using reflection. { // field.Name has the field's name. object fieldValue = field.GetValue(thisBoxed); // Get value // Get the TypeCode enumeration. Multiple types get mapped to a common typecode. TypeCode typeCode = Type.GetTypeCode(fieldValue.GetType()); switch (typeCode) { case TypeCode.Int32: { Int32 i = System.Net.IPAddress.NetworkToHostOrder((Int32)fieldValue); field.SetValue(thisBoxed, (Int32)i); break; } case TypeCode.UInt32: { field.SetValue(thisBoxed, (UInt32)i); break; } case TypeCode.Int16: { Int16 i = System.Net.IPAddress.NetworkToHostOrder((Int16)fieldValue); field.SetValue(thisBoxed, (Int16)i); break; } case TypeCode.UInt16: { field.SetValue(thisBoxed, (UInt16)i); break; } case TypeCode.Int64: { Int64 i = System.Net.IPAddress.NetworkToHostOrder((Int64)fieldValue); field.SetValue(thisBoxed, i); break; } case TypeCode.UInt64: { field.SetValue(thisBoxed, (UInt64)i); break; } default: { System.Diagnostics.Debug.Fail("No conversion provided for this type"); break; } }; // switch } // foreach return (MyStruct)thisBoxed; } // Swap }; // MyStruct // Usage example: s.u4 = 0x78563412; s.s4 = 0x21436587; s.u2 = 0x2143; s.s2 = 0x3412; s.u8 = 0xFF007856341200FF; s.s8 = 0x7700785634120077; s = s.Swap();