Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bit fields in C#

Tags:

c#

bit-fields

I have a structure which I need to populate and write to disk (several actually).

An example is:

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

In C I might do something like the following:

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; }; 

Is there any way to do this in C# that would enable me to access the bits using the struct dereferencing dot operator?

For a couple of structures, I can just do bit shifting wrapped in an accessor function.

I have loads of structures to handle in this way, so I'm looking for something that's easier to read and quicker to write.

like image 659
Rob Avatar asked Aug 18 '08 11:08

Rob


People also ask

What is bit fields give an example?

Bit fields can be used to reduce memory consumption when a program requires a number of integer variables which always will have low values. For example, in many systems storing an integer value requires two bytes (16-bits) of memory; sometimes the values to be stored actually need only one or two bits.

How are bit fields stored in memory C?

Again, storage of bit fields in memory is done with a byte-by-byte, rather than bit-by-bit, transfer.

What are bit fields what the limitation of bit fields is as implemented in C language?

Limitations of a bit-fieldBit-fields do not have address, so & operator cannot be applied on them. So, they cannot be read using a scanf() function also. Bit-fields cannot be accessed using pointers. So indirection operator (*) cannot be applied on them.

What is bit and byte in C?

Utilities Operating System Computer Hardware OS Designer End user Programmer Page 4 Copyright @ 2008 Ananda Gunawardena Bits, Bytes and Data Types A bit is the smallest unit of storage represented by 0 or 1. A byte is typically 8 bits. C character data type requires one byte of storage. A file is a sequence of bytes.


1 Answers

I'd probably knock together something using attributes, then a conversion class to convert suitably attributed structures to the bitfield primitives. Something like...

using System;  namespace BitfieldTest {     [global::System.AttributeUsage(AttributeTargets.Field, AllowMultiple = false)]     sealed class BitfieldLengthAttribute : Attribute     {         uint length;          public BitfieldLengthAttribute(uint length)         {             this.length = length;         }          public uint Length { get { return length; } }     }      static class PrimitiveConversion     {         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(BitfieldLengthAttribute), false);                 if (attrs.Length == 1)                 {                     uint fieldLength  = ((BitfieldLengthAttribute)attrs[0]).Length;                      // Calculate a bitmask of the desired 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 PESHeader     {         [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;     };      public class MainClass     {         public static void Main(string[] args)         {             PESHeader p = new PESHeader();              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.Write( ((l & (1l << i)) > 0) ? "1" : "0");             }              Console.WriteLine();              return;         }     } } 

Which produces the expected ...000101011. Of course, it needs more error checking and a slightly saner typing, but the concept is (I think) sound, reusable, and lets you knock out easily maintained structures by the dozen.

adamw

like image 174
Adam Wright Avatar answered Oct 07 '22 15:10

Adam Wright