/******************************************************************************
Welcome to GDB Online.
GDB online is an online compiler and debugger tool for C, C++, Python, Java, PHP, Ruby, Perl,
C#, OCaml, VB, Swift, Pascal, Fortran, Haskell, Objective-C, Assembly, HTML, CSS, JS, SQLite, Prolog.
Code, Compile, Run and Debug online from anywhere in world.
*******************************************************************************/
using System;
using System.Reflection;
public class BitFieldsAttribute : Attribute
{
uint length;
public BitFieldsAttribute(uint length)
{
this.length = length;
}
public uint Length
{
get { return length; }
}
public static class Convertion {
public static long ToLong<T>(T t) where T :
struct
{
long r = 0;
int offset = 0;
// For every field suitably attributed with a BitfieldLength
foreach (System.Reflection.FieldInfo f in t.GetType().GetFields())
{
object[] attrs = f.GetCustomAttributes(typeof(BitFieldsAttribute), false);
if (attrs.Length == 1)
{
uint fieldLength = ((BitFieldsAttribute)attrs[0]).Length;
// Calculate a bitmask of the desired length
long mask = 0;
for (int i = 0; i < fieldLength; i++)
mask |= (uint)(1 << i);
//mask |= 1 << i;
r |= ((UInt32)f.GetValue(t) & mask) << offset;
offset += (int)fieldLength;
}
}
return r;
}
public static T FromLong<T>(long l) where T :
struct
{
T t = new T();
Object boxed = t;
int offset = 0;
// For every field suitably attributed with a BitfieldLength
foreach (System.Reflection.FieldInfo f in t.GetType().GetFields())
{
object[] attrs = f.GetCustomAttributes(typeof(BitFieldsAttribute), false);
if (attrs.Length == 1)
{
uint fieldLength = ((BitFieldsAttribute)attrs[0]).Length;
// Calculate a bitmask of the desired length
long mask = 0;
for (int i = 0; i < fieldLength; i++)
mask |= (uint)(1 << i);
var value = Convert.ChangeType((l >> offset) & mask, f.FieldType);
var fieldAttribute = typeof(T).GetField(f.Name, BindingFlags.Instance | BindingFlags.Public);
fieldAttribute.SetValue(boxed, value);
t = (T)boxed;
offset += (int)fieldLength;
}
}
return t;
}
}
}
struct Status
{
[BitFields(1)]
public uint IsOn;
[BitFields(3)]
public uint IsRunning;
[BitFields(4)]
public uint IsFinish;
};
class HelloWorld {
static void Main() {
Status s = new Status();
s.IsOn = 1;
s.IsRunning = 5;
s.IsFinish = 7;
int size = System.Runtime.InteropServices.Marshal.SizeOf(typeof(Status));
Console.WriteLine("Bytes:" + size);
long l = BitFieldsAttribute.Convertion.ToLong(s);
Console.WriteLine("Convert to long:" + l);
Status s2 = BitFieldsAttribute.Convertion.FromLong<Status>(l);
Console.WriteLine("Convert from long:" + string.Format("IsOn:{0}, IsRunning:{1}, IsFinish:{2}", s2.IsOn, s2.IsRunning, s2.IsFinish));
}
}