BitFlagsGenerator.cs 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. //-----------------------------------------------------------------------------
  2. // Copyright (c) Microsoft Corporation. All rights reserved.
  3. //-----------------------------------------------------------------------------
  4. namespace System.Runtime.Serialization
  5. {
  6. using System;
  7. using System.Reflection;
  8. #if !NO_DYNAMIC_CODEGEN
  9. using System.Reflection.Emit;
  10. #endif
  11. using System.Security;
  12. [Fx.Tag.SecurityNote(Miscellaneous = "RequiresReview (Critical) - works on CodeGenerator objects, which require Critical access.")]
  13. class BitFlagsGenerator
  14. {
  15. #if !NO_DYNAMIC_CODEGEN
  16. int bitCount;
  17. CodeGenerator ilg;
  18. LocalBuilder[] locals;
  19. public BitFlagsGenerator(int bitCount, CodeGenerator ilg, string localName)
  20. {
  21. this.ilg = ilg;
  22. this.bitCount = bitCount;
  23. int localCount = (bitCount + 7) / 8;
  24. locals = new LocalBuilder[localCount];
  25. for (int i = 0; i < locals.Length; i++)
  26. {
  27. locals[i] = ilg.DeclareLocal(typeof(byte), localName + i, (byte) 0);
  28. }
  29. }
  30. #endif
  31. public static bool IsBitSet(byte[] bytes, int bitIndex)
  32. {
  33. int byteIndex = GetByteIndex(bitIndex);
  34. byte bitValue = GetBitValue(bitIndex);
  35. return (bytes[byteIndex] & bitValue) == bitValue;
  36. }
  37. public static void SetBit(byte[] bytes, int bitIndex)
  38. {
  39. int byteIndex = GetByteIndex(bitIndex);
  40. byte bitValue = GetBitValue(bitIndex);
  41. bytes[byteIndex] |= bitValue;
  42. }
  43. #if !NO_DYNAMIC_CODEGEN
  44. public int GetBitCount()
  45. {
  46. return bitCount;
  47. }
  48. public LocalBuilder GetLocal(int i)
  49. {
  50. return locals[i];
  51. }
  52. public int GetLocalCount()
  53. {
  54. return locals.Length;
  55. }
  56. public void Load(int bitIndex)
  57. {
  58. LocalBuilder local = locals[GetByteIndex(bitIndex)];
  59. byte bitValue = GetBitValue(bitIndex);
  60. ilg.Load(local);
  61. ilg.Load(bitValue);
  62. ilg.And();
  63. ilg.Load(bitValue);
  64. ilg.Ceq();
  65. }
  66. public void LoadArray()
  67. {
  68. LocalBuilder localArray = ilg.DeclareLocal(Globals.TypeOfByteArray, "localArray");
  69. ilg.NewArray(typeof(byte), locals.Length);
  70. ilg.Store(localArray);
  71. for (int i = 0; i < locals.Length; i++)
  72. {
  73. ilg.StoreArrayElement(localArray, i, locals[i]);
  74. }
  75. ilg.Load(localArray);
  76. }
  77. public void Store(int bitIndex, bool value)
  78. {
  79. LocalBuilder local = locals[GetByteIndex(bitIndex)];
  80. byte bitValue = GetBitValue(bitIndex);
  81. if (value)
  82. {
  83. ilg.Load(local);
  84. ilg.Load(bitValue);
  85. ilg.Or();
  86. ilg.Stloc(local);
  87. }
  88. else
  89. {
  90. ilg.Load(local);
  91. ilg.Load(bitValue);
  92. ilg.Not();
  93. ilg.And();
  94. ilg.Stloc(local);
  95. }
  96. }
  97. #endif
  98. static byte GetBitValue(int bitIndex)
  99. {
  100. return (byte)(1 << (bitIndex & 7));
  101. }
  102. static int GetByteIndex(int bitIndex)
  103. {
  104. return bitIndex >> 3;
  105. }
  106. }
  107. }