code_junkie

Bit fields in C#

Nov 10th, 2011
341
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.39 KB | None | 0 0
  1. byte-6
  2. bit0 - original_or_copy
  3. bit1 - copyright
  4. bit2 - data_alignment_indicator
  5. bit3 - PES_priority
  6. bit4-bit5 - PES_scrambling control.
  7. bit6-bit7 - reserved
  8.  
  9. struct PESHeader {
  10. unsigned reserved:2;
  11. unsigned scrambling_control:2;
  12. unsigned priority:1;
  13. unsigned data_alignment_indicator:1;
  14. unsigned copyright:1;
  15. unsigned original_or_copy:1;
  16. };
  17.  
  18. using System;
  19.  
  20. namespace BitfieldTest
  21. {
  22. [global::System.AttributeUsage(AttributeTargets.Field, AllowMultiple = false)]
  23. sealed class BitfieldLengthAttribute : Attribute
  24. {
  25. uint length;
  26.  
  27. public BitfieldLengthAttribute(uint length)
  28. {
  29. this.length = length;
  30. }
  31.  
  32. public uint Length { get { return length; } }
  33. }
  34.  
  35. static class PrimitiveConversion
  36. {
  37. public static long ToLong<T>(T t) where T : struct
  38. {
  39. long r = 0;
  40. int offset = 0;
  41.  
  42. // For every field suitably attributed with a BitfieldLength
  43. foreach (System.Reflection.FieldInfo f in t.GetType().GetFields())
  44. {
  45. object[] attrs = f.GetCustomAttributes(typeof(BitfieldLengthAttribute), false);
  46. if (attrs.Length == 1)
  47. {
  48. uint fieldLength = ((BitfieldLengthAttribute)attrs[0]).Length;
  49.  
  50. // Calculate a bitmask of the desired length
  51. long mask = 0;
  52. for (int i = 0; i < fieldLength; i++)
  53. mask |= 1 << i;
  54.  
  55. r |= ((UInt32)f.GetValue(t) & mask) << offset;
  56.  
  57. offset += (int)fieldLength;
  58. }
  59. }
  60.  
  61. return r;
  62. }
  63. }
  64.  
  65. struct PESHeader
  66. {
  67. [BitfieldLength(2)]
  68. public uint reserved;
  69. [BitfieldLength(2)]
  70. public uint scrambling_control;
  71. [BitfieldLength(1)]
  72. public uint priority;
  73. [BitfieldLength(1)]
  74. public uint data_alignment_indicator;
  75. [BitfieldLength(1)]
  76. public uint copyright;
  77. [BitfieldLength(1)]
  78. public uint original_or_copy;
  79. };
  80.  
  81. public class MainClass
  82. {
  83. public static void Main(string[] args)
  84. {
  85. PESHeader p = new PESHeader();
  86.  
  87. p.reserved = 3;
  88. p.scrambling_control = 2;
  89. p.data_alignment_indicator = 1;
  90.  
  91. long l = PrimitiveConversion.ToLong(p);
  92.  
  93.  
  94. for (int i = 63; i >= 0; i--)
  95. {
  96. Console.Write( ((l & (1l << i)) > 0) ? "1" : "0");
  97. }
  98.  
  99. Console.WriteLine();
  100.  
  101. return;
  102. }
  103. }
  104. }
  105.  
  106. [StructLayout(LayoutKind.Explicit, Size=1, CharSet=CharSet.Ansi)]
  107. public struct Foo
  108. { [FieldOffset(0)]public byte original_or_copy;
  109. [FieldOffset(0)]public byte copyright;
  110. [FieldOffset(0)]public byte data_alignment_indicator;
  111. [FieldOffset(0)]public byte PES_priority;
  112. [FieldOffset(0)]public byte PES_scrambling_control;
  113. [FieldOffset(0)]public byte reserved;
  114. }
  115.  
  116. const byte _original_or_copy = 1;
  117. const byte _copyright = 2;
  118.  
  119. //bool ooo = foo.original_or_copy();
  120. static bool original_or_copy(this Foo foo)
  121. { return (foo.original_or_copy & _original_or_copy) == original_or_copy;
  122. }
  123.  
  124. [Flags]
  125. public enum PESHeaderFlags
  126. {
  127. IsCopy = 1, // implied that if not present, then it is an original
  128. IsCopyrighted = 2,
  129. IsDataAligned = 4,
  130. Priority = 8,
  131. ScramblingControlType1 = 0,
  132. ScramblingControlType2 = 16,
  133. ScramblingControlType3 = 32,
  134. ScramblingControlType4 = 16+32,
  135. ScramblingControlFlags = ScramblingControlType1 | ScramblingControlType2 | ... ype4
  136. etc.
  137. }
  138.  
  139. [Flags] enum PesHeaders : byte { /* ... */ }
Add Comment
Please, Sign In to add comment