`

c# - Bit fields in C#

    博客分类:
  • C#
c# 
阅读更多

this is a thread that is inspired by the thoght and discusson from the stackoverflow. and hte original post is here:  Bit fields in C#.

 

 

As a background/foundamental knowledge,or the first question to ask: what is bit fields?

 

 

Bit Fields is a extremely space saving technique which is quit commonly used in C++ proramms

 

 

here is one example of the BitField in C++:

 

 

 

class BitFields { 
  public:
    int mode : 2;
	int full_flag : 1;
	int empty_flag : 1;

  };

 

 and you can use it this way:

 

 

enum { On = 0, Off = 1 } ;
enum { Yes = 0, No = 1 };

int main() { 
    BitFields bitFields;
	bitFields.mode |= On;
	bitFields.full_flag &= ~Yes;
}

 

 

 

 

Why do we need the Bit Fields classes, it is space effecient, and it is easy to manipulate. But they are not natively built inside the C# language. 

 

 

 

 

Given an example.

 

 

suppose that we are going to model a flag as this: 

 

 

byte-6    
bit0 - original_or_copy  
bit1 - copyright  
bit2 - data_alignment_indicator  
bit3 - PES_priority  
bit4-bit5 - PES_scrambling control.  
bit6-bit7 - reserved

 

 

 

and you can do this in C

 

 

struct PESHeader  {
    unsigned reserved:2;
    unsigned scrambling_control:2;
    unsigned priority:1;
    unsigned data_alignment_indicator:1;
    unsigned copyright:1;
    unsigned original_or_copy:1;
};

 

 

 

Let's first examine some solution that has been discussed.

 

The StructLayoutAttribute solution

 

 

 

static class StructLayoutResolution
  {
    // the Fool structure is using a union approach.
    // or you can change the Explicit location so that they can aligh with each other sequentially
    // or you can try the LayoutKind.Sequential
    public void DemoStructLayoutResolution()
    {
      
      Foo foo = new Foo();
      Console.WriteLine("foo.original_or_copy = {0}", foo.original_or_copy);

    }

    const byte _original_or_copy = 1;
    const byte _copyright = 2;

    static bool original_or_copy(this Foo foo)
    {
      return (foo.original_or_copy & _original_or_copy) == _original_or_copy;
    }
  }

  // you can use the StructlayoutAttribute 
  //   http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.structlayoutattribute%28VS.71%29.aspx
  [StructLayout(LayoutKind.Explicit, Size = 1, CharSet=CharSet.Ansi)]
  public struct Foo
  {
    [FieldOffset(0)]
    public byte original_or_copy;
    [FieldOffset(0)]
    public byte copyright;
    [FieldOffset(0)]
    public byte data_alignment_indicator;
    [FieldOffset(0)]
    public byte PES_prioirty;
    [FieldOffset(0)]
    public byte reserved;
  }
 

 

The code shown above is the union approach, but you can use the bit fields approach, by changing the Layoutkind from LayoutKind.Explicit to LayoutKind.Sequential.

 

 

The custom attributes solution

 

 

 

// this is using a custmo attribute , where you can decorate the fields just as you can do with the StructLayoutAttribute
  class CustomAttributeResoltuion
  {
    public static void DemoCustomAttributeTechnique()
    {
      PSEHeader p = new PSEHeader();
      p.reserved = 3;
      p.scrambling_control = 2;
      p.data_alignment_indicator = 1;

      long l = PrimitiveConversion.ToLong(p);

      for (int i = 63; i >= 0; i--)
      {
        Console.WriteLine(((l & (1L << i)) > 0) ? "1" : "0");
      }
      Console.WriteLine();
      return;
    }
  }

  [AttributeUsage(AttributeTargets.Field, AllowMultiple=false)]
  sealed class BitfieldLengthAttribute : Attribute
  {
    uint length;

    public BitfieldLengthAttribute(uint length)
    {
      this.length = length;
    }

    public uint Length { get { return this.length; } }
  }

  // this is a helper class that helps you to convert a structure that is decorated with BitfieldLengthAttribute 
  // to a long value
  static class PrimitiveConversion
  {
    public static long ToLong<T>(T t) where T : struct
    {
      long r = 0;
      int offset = 0;

      foreach (var f in t.GetType().GetFields())
      {
        var attrs = f.GetCustomAttributes(typeof(BitfieldLengthAttribute), false);
        if (attrs.Length == 1)
        {
          uint fieldlength = ((BitfieldLengthAttribute)attrs[0]).Length;

          long mask = 0;
          for (int i = 0; i < fieldlength; i++)
            mask |= 1 << i;

          r |=( (UInt32)f.GetValue(t) & mask) << offset;

          offset += (int)fieldlength;
        }

      }
      return r;
    }
  }

  struct PSEHeader
  {
    [BitfieldLength(2)]
    public uint reserved;
    [BitfieldLength(2)]
    public uint scrambling_control;
    [BitfieldLength(1)]
    public uint priority;
    [BitfieldLength(1)]
    public uint data_alignment_indicator;
    [BitfieldLength(1)]
    public uint copyright;
    [BitfieldLength(1)]
    public uint original_or_copy;
  }

 

 

 

However, be cautions that this approach uses the Type.GetFields() call, which, according to the MSDN, does not guarantee to return the fields in the order that they are declared.

 

 

So you have to use it with caution.

 

 

BitVector approach

This is probably the most native one, the bit vector is a managed class and it is natural to use. 

 

public static class BitVectorMethod
  {
    public static void BitVectorDemo()
    {
      rcSpan rcspan = new rcSpan();
      rcspan.smin = 13;

      rcSpan2 rcspan2 = new rcSpan2();
      rcspan2.smin = 13;
    }
  }


  public struct rcSpan
  {
    internal static readonly BitVector32.Section sminSection = BitVector32.CreateSection(0x1FFF);
    internal static readonly BitVector32.Section smaxSection = BitVector32.CreateSection(0x1FFF, sminSection);
    internal static readonly BitVector32.Section areaSection = BitVector32.CreateSection(0x3F, smaxSection);

    // the internal storage class object.
    internal BitVector32 data;


    // public uint smin: 13;
    public uint smin
    {
      get { return (uint)data[sminSection]; }
      set { data[sminSection] = (int)value; }
    }

    // public uint smax: 13;
    public uint smax
    {
      get { return (uint)data[smaxSection]; }
      set { data[smaxSection] = (int)value; }
    }
    // public uint area: 6;
    public uint area
    {
      get { return (uint)data[areaSection]; }
      set { data[areaSection] = (int)value; } 
    }

    


  }

  // or you can do some handmade access this way

  public struct rcSpan2
  {
    // andyou can do more
    // such as provide the handmade accessors for every fields

    internal uint data;

    // pulbic uint smin: 13
    public uint smin
    {
      get { return (uint)data & 0x1FFFF; }
      set { data = (data & ~0x1FFFFu) | (value & 0x1FFFF); }
    }

    //public uint smax : 13; 
    public uint smax
    {
      get { return (data >> 13) & 0x1FFF; }
      set { data = (data & ~(0x1FFFu << 13)) | (value & 0x1FFF) << 13; }
    }

    //public uint area : 6; 
    public uint area
    {
      get { return (data >> 26) & 0x3F; }
      set { data = (data & ~(0x3F << 26)) | (value & 0x3F) << 26; }
    }
  }
 

As you can see, that in the code above, we are not only show the native bitvector approach, we are actually using some custom handmade bitvector acesss, but the priciple is the same.

 

 

 

 

分享到:
评论

相关推荐

    c#-ymodem-update

    标题"C#-ymodem-update"指的是一个使用C#编程语言开发的YMODEM协议实现,主要功能是用于设备固件的升级,特别是针对bootloader的更新。YMODEM是一种流行的串行通信协议,用于在计算机之间传输文件,尤其是在低带宽和...

    C# - CSharp 12 in a Nutshell The Definitive Reference

    ### C# 12 in a Nutshell:The Definitive Reference #### 1. Introducing C# and .NET **Object Orientation** C# is an object-oriented programming (OOP) language, which means that it structures code ...

    C#-串口示例demo源代码-SerialPortHelper.rar

    C#-串口示例demo源代码-SerialPortHelper.rar,C#-串口示例demo源代码-SerialPortHelper.rar,C#-串口示例demo源代码-SerialPortHelper.rar

    大恒-双相机开发-C#-多线程-项目开源

    《大恒双相机开发-C#-多线程项目开源解析》 在当今信息化时代,高效、稳定的图像处理系统成为许多领域不可或缺的技术支持。本项目"大恒-双相机开发-C#-多线程"正是这样的一个实例,它利用C#语言进行编程,实现了对...

    C#--PPT_c#PPT_C#_源码.rar

    C#--PPT_c#PPT_C#_源码.rar

    C# 5.0 All-in-One For Dummies

    Everything you need to make the move to C# programming is right here, in C# 2012 All-in-One For Dummies. From the Back Cover 7 books in 1 C# Programming Basics Object-Oriented C# Programming ...

    Exam 70-483 Programming In C#

    ### Exam 70-483 Programming in C# 关键知识点概述 #### 一、考试简介与背景 《Exam 70-483 Programming in C#》是微软官方认证的一项重要考试,主要针对那些希望证明自己具备使用C#语言进行高效编程能力的专业...

    C#-经典教材 C#大学教程第一部分(中文版,deitel著)

    C#-经典教材 C#大学教程(中文版,deitel著)

    C#-经典教材 C#大学教程第二部分(中文版,deitel著)

    C#-经典教材 C#大学教程(中文版,deitel著)

    protobuf实例-C#-聊天服务器

    在本实例中,“protobuf实例-C#-聊天服务器”是基于C#语言实现的一个聊天服务项目,利用protobuf进行数据序列化和反序列化,以便于在网络通信中高效地传输聊天消息。 在C#环境下,protobuf提供了编译器工具,可以将...

    C#-wxpay微信支付模板

    C#-wxpay微信支付模板

    C#-WPF实现抽屉效果SplitView-炫酷漂亮的侧边菜单效果+MD主题重绘原生控件的美观效果-源码Demo下载

    1. **导入Material Design库**:首先,你需要在项目中引入Material Design In XAML Toolkit库,它为WPF提供了许多预定义的MD样式和控件。 2. **设置全局资源**:将库提供的ThemeDictionary添加到应用程序的资源字典...

    C# - 模拟开心农场

    名称: “C# - 模拟开心农场” 说明: C#模拟开心农场,经历播种、生长、开花、结果、收获的过程; 源代码分为两个版本: 一是手动实现成长收获的过程,另一版本是后台线程自动实现成长收获的过程 ^_^

    C#版USB-HID范例

    【标题】"C#版USB-HID范例" 涉及的是在C#编程环境中与USB设备进行Human Interface Device (HID)通信的技术。USB-HID类库允许开发者直接与各种类型的输入设备(如键盘、鼠标、游戏控制器等)进行交互,而无需关心具体...

    C# - 简易聊天室实现网页

    在IT行业中,C#是一种广泛使用的编程语言,尤其在开发Web应用程序时,它与ASP.NET框架结合,可以创建高效、动态的网站。本教程将深入探讨如何使用C#和ASP.NET构建一个简易的聊天室网页。 首先,让我们理解标题"**C#...

    ACCP5.0-S1-C#教程PPT

    ACCP5.0-S1-C#教程PPTACCP5.0-S1-C#教程PPTACCP5.0-S1-C#教程PPTACCP5.0-S1-C#教程PPTACCP5.0-S1-C#教程PPTACCP5.0-S1-C#教程PPTACCP5.0-S1-C#教程PPTACCP5.0-S1-C#教程PPTACCP5.0-S1-C#教程PPTACCP5.0-S1-C#教程...

    中英文手机短信PDU编码(UCS2)解码(UCS2,7-Bit) C# 程序

    实例32 &lt;br&gt;稿件名称:中英文手机短信PDU编码(UCS2)解码(UCS2,7-Bit) C# 程序 &lt;br&gt;稿件作者:李仓海 &lt;br&gt;程序名称:TC35iSMS &lt;br&gt;运行环境:TC35iSMS &lt;br&gt;注意事项:

    32bit程序调用64bit dll解决办法的例子程序

    32bit程序调用64bit dll 的解决办法 32bit程序不能直接调用64bit的dll,我们采用COM进程外组件的方式来实现间接调用。具体参考: http://blog.csdn.net/shakesky/article/details/23265811

    c# NB-IOT北向接入demo

    本"**c# NB-IOT北向接入demo**"是为了展示如何使用C#语言与NB-IoT网络进行交互,实现设备的北向接入功能。以下是这个demo涉及的关键知识点: 1. **Token验证**:在NB-IoT通信中,安全是至关重要的。Token验证是身份...

Global site tag (gtag.js) - Google Analytics