Subversion Repositories delphiutils

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

  1. unit BitOps;
  2.  
  3. (*************************************************************
  4.  
  5.     BitOps.pas
  6.     Bit- Byte- and Nibbleoperations
  7.     64 Bit Edition; Rev 21 March 2010
  8.  
  9.     (C) 2010 ViaThinkSoft [www.viathinksoft.com]
  10.     Developed by Daniel Marschall [www.daniel-marschall.de]
  11.  
  12.     Source:
  13.     http://home.viathinksoft.de/daniel-marschall/code/delphi/BitOps.pas
  14.  
  15. *************************************************************)
  16.  
  17. interface
  18.  
  19. uses
  20.   SysUtils;
  21.  
  22. // * TYPES *
  23.  
  24. type
  25.   Nibble = 0..127;
  26.   THexNibble = $0..$F;
  27.   T4BitPos = 0..3;
  28.   T8BitPos = 0..7;
  29.   T16BitPos = 0..15;
  30.   T32BitPos = 0..31;
  31.   T64BitPos = 0..63;
  32.  
  33.   // Maximum amount of bytes in the biggest data type (int64)
  34.   TBytePos = 0..7;
  35.   // Maximum amount of nibbles in the biggest data type (int64)
  36.   THexNibblePos = 0..15;
  37.  
  38.   TBit = Boolean;
  39.   THexNibbleBitArray = array[Low(T4BitPos)..High(T4BitPos)] of TBit;
  40.   TByteBitArray = array[Low(T8BitPos)..High(T8BitPos)] of TBit;
  41.   TBitString = type string;
  42.   TByteBitString = type TBitString;
  43.   THexNibbleBitString = type TBitString;
  44.  
  45. // ******************
  46. // * BYTE FUNCTIONS *
  47. // ******************
  48.  
  49. // Build a byte.
  50. // Either you combine two nibbles...
  51. function BuildByte(AUpperNibble, ALowerNibble: THexNibble): Byte; overload;
  52. // ...or you define an array of 8 bits.
  53. function BuildByte(ABitArray: TByteBitArray): Byte; overload;
  54. // ...or you define a bitstring (e.g. '00011100')
  55. function BuildByte(ABits: TByteBitString): Byte; overload;
  56. // ...or you define the bits as parameters
  57. function BuildByte(ABit1, ABit2, ABit3, ABit4, ABit5, ABit6, ABit7,
  58.   ABit8: TBit): Byte; overload;
  59.  
  60. // Converts a byte into a array of 8 bits
  61. function GetByteBitArray(AByte: Byte): TByteBitArray;
  62.  
  63. // Getting and setting the lower nibble of a byte.
  64. function GetLowerNibble(AByte: Byte): THexNibble;
  65. function SetLowerNibble(AByte: Byte; ANewNibble: THexNibble): Byte;
  66.  
  67. // Getting and setting the upper nibble of a byte.
  68. function GetUpperNibble(AByte: Byte): THexNibble;
  69. function SetUpperNibble(AByte: Byte; ANewNibble: THexNibble): Byte;
  70.  
  71. // Interchanges upper and lower Nibble in a byte
  72. function InterchangeNibbles(AByte: Byte): Byte;
  73.  
  74. // Creates an 8-bit-array from a 8-bit-string
  75. // Throws EBitStringTooLong and EBitStringInvalidCharacter
  76. function ByteBitArrayFromBitString(const ABits: TByteBitString):
  77.   TByteBitArray;
  78.  
  79. // Getting and setting of a bit in a byte
  80. function GetByteBit(AByte: Byte; ABitPos: T8BitPos): TBit;
  81. function SetByteBit(AByte: Byte; ABitPos: T8BitPos; ANewBit: TBit): Byte;
  82.  
  83. // Logical operations for the 8 bit arrays.
  84. function ByteBitArrayShr(ABitArray: TByteBitArray;
  85.   AVal: Longword): TByteBitArray;
  86. function ByteBitArrayShl(ABitArray: TByteBitArray;
  87.   AVal: Longword): TByteBitArray;
  88. function ByteBitArrayAnd(ABitArray, ABitArray2: TByteBitArray): TByteBitArray;
  89. function ByteBitArrayOr(ABitArray, ABitArray2: TByteBitArray): TByteBitArray;
  90. function ByteBitArrayXor(ABitArray, ABitArray2: TByteBitArray): TByteBitArray;
  91. function ByteBitArrayNot(ABitArray: TByteBitArray): TByteBitArray;
  92.  
  93. // Inverse the bits of a byte
  94. function InverseByteBits(x: Byte): Byte;
  95.  
  96. // Reverses the bit sequence of a byte
  97. function ReverseByteBitSequence(AByte: Byte): Byte;
  98.  
  99. // ********************
  100. // * NIBBLE FUNCTIONS *
  101. // ********************
  102.  
  103. // Build a Nibble.
  104. // You can define an array of 4 bits.
  105. function BuildNibble(ABitArray: THexNibbleBitArray): Nibble; overload;
  106. // ...or you define a bitstring (e.g. '0001')
  107. function BuildNibble(ABits: THexNibbleBitString): Nibble; overload;
  108. // ...or you define the bits as parameters
  109. function BuildNibble(ABit1, ABit2, ABit3, ABit4: TBit): Nibble; overload;
  110.  
  111. // Converts a nibble into a array of 4 bits
  112. function GetNibbleBitArray(ANibble: Nibble): THexNibbleBitArray;
  113.  
  114. // Creates an 4-bit-array from a 4-bit-string
  115. // Throws EBitStringTooLong and EBitStringInvalidCharacter
  116. function NibbleBitArrayFromBitString(const ABits: THexNibbleBitString):
  117.   THexNibbleBitArray;
  118.  
  119. // Getting and setting of a bit in a nibble
  120. function GetNibbleBit(ANibble: Nibble; ABitPos: T4BitPos): TBit;
  121. function SetNibbleBit(ANibble: Nibble; ABitPos: T4BitPos;
  122.   ANewBit: TBit): Nibble;
  123.  
  124. // Logical operations for the 4 bit arrays.
  125. function NibbleBitArrayShr(ABitArray: THexNibbleBitArray; AVal: Longword):
  126.   THexNibbleBitArray;
  127. function NibbleBitArrayShl(ABitArray: THexNibbleBitArray; AVal: Longword):
  128.   THexNibbleBitArray;
  129. function NibbleBitArrayAnd(ABitArray, ABitArray2: THexNibbleBitArray):
  130.   THexNibbleBitArray;
  131. function NibbleBitArrayOr(ABitArray, ABitArray2: THexNibbleBitArray):
  132.   THexNibbleBitArray;
  133. function NibbleBitArrayXor(ABitArray, ABitArray2: THexNibbleBitArray):
  134.   THexNibbleBitArray;
  135. function NibbleBitArrayNot(ABitArray: THexNibbleBitArray): THexNibbleBitArray;
  136.  
  137. // Inverse the bits of a nibble
  138. function InverseNibbleBits(x: Nibble): Nibble;
  139.  
  140. // Reverses the bit sequence of a nibble
  141. function ReverseNibbleBitSequence(ANibble: Nibble): Nibble;
  142.  
  143. // * EXCEPTIONS *
  144.  
  145. type
  146.   EInvalidBitString = class(Exception);
  147.   EBitStringTooLong = class(EInvalidBitString);
  148.   EBitStringInvalidCharacter = class(EInvalidBitString);
  149.  
  150. // * CONSTANTS *
  151.  
  152. // Lookup tables to avoid calculation each time
  153. const
  154.   AllSetBitsBytes: array[TBytePos] of int64 =
  155.    ($00000000000000FF,
  156.     $000000000000FFFF,
  157.     $0000000000FFFFFF,
  158.     $00000000FFFFFFFF,
  159.     $000000FFFFFFFFFF,
  160.     $0000FFFFFFFFFFFF,
  161.     $00FFFFFFFFFFFFFF,
  162.     $FFFFFFFFFFFFFFFF);
  163.  
  164.   AllSetBitsNibbles: array[THexNibblePos] of int64 =
  165.    ($000000000000000F,
  166.     $00000000000000FF,
  167.     $0000000000000FFF,
  168.     $000000000000FFFF,
  169.     $00000000000FFFFF,
  170.     $0000000000FFFFFF,
  171.     $000000000FFFFFFF,
  172.     $00000000FFFFFFFF,
  173.     $0000000FFFFFFFFF,
  174.     $000000FFFFFFFFFF,
  175.     $00000FFFFFFFFFFF,
  176.     $0000FFFFFFFFFFFF,
  177.     $000FFFFFFFFFFFFF,
  178.     $00FFFFFFFFFFFFFF,
  179.     $0FFFFFFFFFFFFFFF,
  180.     $FFFFFFFFFFFFFFFF);
  181.  
  182.   AllSetBitsNibble: array[THexNibblePos] of int64 =
  183.    ($000000000000000F,
  184.     $00000000000000F0,
  185.     $0000000000000F00,
  186.     $000000000000F000,
  187.     $00000000000F0000,
  188.     $0000000000F00000,
  189.     $000000000F000000,
  190.     $00000000F0000000,
  191.     $0000000F00000000,
  192.     $000000F000000000,
  193.     $00000F0000000000,
  194.     $0000F00000000000,
  195.     $000F000000000000,
  196.     $00F0000000000000,
  197.     $0F00000000000000,
  198.     $F000000000000000);
  199.  
  200.   // Deprecated function:
  201.   // function GetSingleBit(ABit: T64BitPos): Int64;
  202.   //
  203.   // Gives you a 64 bit datatype which is representing the binary coding
  204.   //
  205.   // 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001,
  206.   // 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000010,
  207.   // 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000100,
  208.   // 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00001000,
  209.   // 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00010000,
  210.   // 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00100000,
  211.   // 00000000 00000000 00000000 00000000 00000000 00000000 00000000 01000000,
  212.   // 00000000 00000000 00000000 00000000 00000000 00000000 00000000 10000000,
  213.   // 00000000 00000000 00000000 00000000 00000000 00000000 00000001 00000000,
  214.   // ...
  215.   // 10000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000.
  216.   //
  217.   // Limitation because of the data type: 64 Bit
  218.   //
  219.   // For the GetByteBit() and SetByteBit functions we only need this array to
  220.   // be max at $80 (128).
  221.   // Manual calculation (not 64 bit useable) would be
  222.   // result := Math.Floor(Math.Power(2, ABit));
  223.   SingleBitArray: array[T64BitPos] of int64 =
  224.    ($0000000000000001, $0000000000000002, $0000000000000004, $0000000000000008,
  225.     $0000000000000010, $0000000000000020, $0000000000000040, $0000000000000080,
  226.     $0000000000000100, $0000000000000200, $0000000000000400, $0000000000000800,
  227.     $0000000000001000, $0000000000002000, $0000000000004000, $0000000000008000,
  228.     $0000000000010000, $0000000000020000, $0000000000040000, $0000000000080000,
  229.     $0000000000100000, $0000000000200000, $0000000000400000, $0000000000800000,
  230.     $0000000001000000, $0000000002000000, $0000000004000000, $0000000008000000,
  231.     $0000000010000000, $0000000020000000, $0000000040000000, $0000000080000000,
  232.     $0000000100000000, $0000000200000000, $0000000400000000, $0000000800000000,
  233.     $0000001000000000, $0000002000000000, $0000004000000000, $0000008000000000,
  234.     $0000010000000000, $0000020000000000, $0000040000000000, $0000080000000000,
  235.     $0000100000000000, $0000200000000000, $0000400000000000, $0000800000000000,
  236.     $0001000000000000, $0002000000000000, $0004000000000000, $0008000000000000,
  237.     $0010000000000000, $0020000000000000, $0040000000000000, $0080000000000000,
  238.     $0100000000000000, $0200000000000000, $0400000000000000, $0800000000000000,
  239.     $1000000000000000, $2000000000000000, $4000000000000000, $8000000000000000);
  240.  
  241.   // Deprecated function:
  242.   // function GetSingleBitDynamicInversed(ABit: T64BitPos): Int64;
  243.   //
  244.   // Gives you a 64 bit datatype which is representing the dynamic inversed
  245.   // binary encoding. (Dynamic inversed means, that only the used bytes get
  246.   // inverted, so this is NOT the same as "NOT GetSingleBit(ABit)"!)
  247.   //
  248.   // 00000000 00000000 00000000 00000000 00000000 00000000 00000000 11111110,
  249.   // 00000000 00000000 00000000 00000000 00000000 00000000 00000000 11111101,
  250.   // 00000000 00000000 00000000 00000000 00000000 00000000 00000000 11111011,
  251.   // 00000000 00000000 00000000 00000000 00000000 00000000 00000000 11110111,
  252.   // 00000000 00000000 00000000 00000000 00000000 00000000 00000000 11101111,
  253.   // 00000000 00000000 00000000 00000000 00000000 00000000 00000000 11011111,
  254.   // 00000000 00000000 00000000 00000000 00000000 00000000 00000000 10111111,
  255.   // 00000000 00000000 00000000 00000000 00000000 00000000 00000000 01111111,
  256.   // 00000000 00000000 00000000 00000000 00000000 00000000 11111110 11111111,
  257.   // ...
  258.   // 01111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111.
  259.   //
  260.   // Limitation because of the data type: 64 Bit
  261.   //
  262.   // Manual calculation (not 64 bit useable) would be
  263.   // result := MathFloor(
  264.   //   Math.Power(256, Math.Floor(ABit / 8)+1)-1 {***} -
  265.   //   Math.Power(2, ABit));
  266.   //
  267.   // *** is the maximal value of the byte amount we were requesting.
  268.   // Example:
  269.   // If ABit in [ 0.. 7] => 1 Byte  used => (256^1-1) = $FF
  270.   // If ABit in [ 8..15] => 2 Bytes used => (256^2-1) = $FF FF
  271.   // If ABit in [16..23] => 3 Bytes used => (256^3-1) = $FF FF FF
  272.   // If ABit in [24..31] => 4 Bytes used => (256^3-1) = $FF FF FF FF
  273.   // ...
  274.   SingleBitArrayDynamicInversed: array[T64BitPos] of int64 =
  275.    ($00000000000000FE, $00000000000000FD, $00000000000000FB, $00000000000000F7,
  276.     $00000000000000EF, $00000000000000DF, $00000000000000BF, $000000000000007F,
  277.     $000000000000FEFF, $000000000000FDFF, $000000000000FBFF, $000000000000F7FF,
  278.     $000000000000EFFF, $000000000000DFFF, $000000000000BFFF, $0000000000007FFF,
  279.     $0000000000FEFFFF, $0000000000FDFFFF, $0000000000FBFFFF, $0000000000F7FFFF,
  280.     $0000000000EFFFFF, $0000000000DFFFFF, $0000000000BFFFFF, $00000000007FFFFF,
  281.     $00000000FEFFFFFF, $00000000FDFFFFFF, $00000000FBFFFFFF, $00000000F7FFFFFF,
  282.     $00000000EFFFFFFF, $00000000DFFFFFFF, $00000000BFFFFFFF, $000000007FFFFFFF,
  283.     $000000FEFFFFFFFF, $000000FDFFFFFFFF, $000000FBFFFFFFFF, $000000F7FFFFFFFF,
  284.     $000000EFFFFFFFFF, $000000DFFFFFFFFF, $000000BFFFFFFFFF, $0000007FFFFFFFFF,
  285.     $0000FEFFFFFFFFFF, $0000FDFFFFFFFFFF, $0000FBFFFFFFFFFF, $0000F7FFFFFFFFFF,
  286.     $0000EFFFFFFFFFFF, $0000DFFFFFFFFFFF, $0000BFFFFFFFFFFF, $00007FFFFFFFFFFF,
  287.     $00FEFFFFFFFFFFFF, $00FDFFFFFFFFFFFF, $00FBFFFFFFFFFFFF, $00F7FFFFFFFFFFFF,
  288.     $00EFFFFFFFFFFFFF, $00DFFFFFFFFFFFFF, $00BFFFFFFFFFFFFF, $007FFFFFFFFFFFFF,
  289.     $FEFFFFFFFFFFFFFF, $FDFFFFFFFFFFFFFF, $FBFFFFFFFFFFFFFF, $F7FFFFFFFFFFFFFF,
  290.     $EFFFFFFFFFFFFFFF, $DFFFFFFFFFFFFFFF, $BFFFFFFFFFFFFFFF, $7FFFFFFFFFFFFFFF);
  291.  
  292.   // Gives you a 64 bit datatype which is representing the inversed
  293.   // binary encoding.
  294.   //
  295.   // 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111110,
  296.   // 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111101,
  297.   // 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111011,
  298.   // 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11110111,
  299.   // 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11101111,
  300.   // 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11011111,
  301.   // 11111111 11111111 11111111 11111111 11111111 11111111 11111111 10111111,
  302.   // 11111111 11111111 11111111 11111111 11111111 11111111 11111111 01111111,
  303.   // 11111111 11111111 11111111 11111111 11111111 11111111 11111110 11111111,
  304.   // ...
  305.   // 01111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111.
  306.   //
  307.   // Limitation because of the data type: 64 Bit
  308.   //
  309.   // Manual calculation (not 64 bit useable) would be
  310.   // result := NOT GetSingleBit(ABit)
  311.   //
  312.   SingleBitArrayInversed: array[T64BitPos] of int64 =
  313.    ($FFFFFFFFFFFFFFFE, $FFFFFFFFFFFFFFFD, $FFFFFFFFFFFFFFFB, $FFFFFFFFFFFFFFF7,
  314.     $FFFFFFFFFFFFFFEF, $FFFFFFFFFFFFFFDF, $FFFFFFFFFFFFFFBF, $FFFFFFFFFFFFFF7F,
  315.     $FFFFFFFFFFFFFEFF, $FFFFFFFFFFFFFDFF, $FFFFFFFFFFFFFBFF, $FFFFFFFFFFFFF7FF,
  316.     $FFFFFFFFFFFFEFFF, $FFFFFFFFFFFFDFFF, $FFFFFFFFFFFFBFFF, $FFFFFFFFFFFF7FFF,
  317.     $FFFFFFFFFFFEFFFF, $FFFFFFFFFFFDFFFF, $FFFFFFFFFFFBFFFF, $FFFFFFFFFFF7FFFF,
  318.     $FFFFFFFFFFEFFFFF, $FFFFFFFFFFDFFFFF, $FFFFFFFFFFBFFFFF, $FFFFFFFFFF7FFFFF,
  319.     $FFFFFFFFFEFFFFFF, $FFFFFFFFFDFFFFFF, $FFFFFFFFFBFFFFFF, $FFFFFFFFF7FFFFFF,
  320.     $FFFFFFFFEFFFFFFF, $FFFFFFFFDFFFFFFF, $FFFFFFFFBFFFFFFF, $FFFFFFFF7FFFFFFF,
  321.     $FFFFFFFEFFFFFFFF, $FFFFFFFDFFFFFFFF, $FFFFFFFBFFFFFFFF, $FFFFFFF7FFFFFFFF,
  322.     $FFFFFFEFFFFFFFFF, $FFFFFFDFFFFFFFFF, $FFFFFFBFFFFFFFFF, $FFFFFF7FFFFFFFFF,
  323.     $FFFFFEFFFFFFFFFF, $FFFFFDFFFFFFFFFF, $FFFFFBFFFFFFFFFF, $FFFFF7FFFFFFFFFF,
  324.     $FFFFEFFFFFFFFFFF, $FFFFDFFFFFFFFFFF, $FFFFBFFFFFFFFFFF, $FFFF7FFFFFFFFFFF,
  325.     $FFFEFFFFFFFFFFFF, $FFFDFFFFFFFFFFFF, $FFFBFFFFFFFFFFFF, $FFF7FFFFFFFFFFFF,
  326.     $FFEFFFFFFFFFFFFF, $FFDFFFFFFFFFFFFF, $FFBFFFFFFFFFFFFF, $FF7FFFFFFFFFFFFF,
  327.     $FEFFFFFFFFFFFFFF, $FDFFFFFFFFFFFFFF, $FBFFFFFFFFFFFFFF, $F7FFFFFFFFFFFFFF,
  328.     $EFFFFFFFFFFFFFFF, $DFFFFFFFFFFFFFFF, $BFFFFFFFFFFFFFFF, $7FFFFFFFFFFFFFFF);
  329.  
  330. implementation
  331.  
  332. resourcestring
  333.   LngEBitStringInvalidCharacter = 'The bitstring "%s" contains a invalid ' +
  334.     'character. Unexpected character "%s" at position "%d".';
  335.   LngEBitStringTooLong = 'The bitstring "%s" is too long. Expected: %d byte.';
  336.  
  337. function GetByteBitArray(AByte: Byte): TByteBitArray;
  338. var
  339.   i: T8BitPos;
  340. begin
  341.   for i := Low(T8BitPos) to High(T8BitPos) do
  342.   begin
  343.     // result[i] := GetByteBit(AByte, i);
  344.     result[i] := AByte and SingleBitArray[i] = SingleBitArray[i];
  345.   end;
  346. end;
  347.  
  348. function GetNibbleBitArray(ANibble: Nibble): THexNibbleBitArray;
  349. var
  350.   i: T4BitPos;
  351. begin
  352.   for i := Low(T4BitPos) to High(T4BitPos) do
  353.   begin
  354.     // result[i] := GetNibbleBit(ANibble, i);
  355.     result[i] := ANibble and SingleBitArray[i] = SingleBitArray[i];
  356.   end;
  357. end;
  358.  
  359. function BuildByte(AUpperNibble, ALowerNibble: THexNibble): Byte;
  360. begin
  361.   // result := $10 * AUpperNibble + ALowerNibble;
  362.   result := (AUpperNibble shl 4) + ALowerNibble;
  363. end;
  364.  
  365. function BuildByte(ABitArray: TByteBitArray): Byte;
  366. var
  367.   i: T8BitPos;
  368. begin
  369.   result := 0;
  370.   for i := Low(T8BitPos) to High(T8BitPos) do
  371.   begin
  372.     // SetByteBit(result, i, ABitArray[i]);
  373.  
  374.     if not ABitArray[i] then
  375.       result := result and SingleBitArrayDynamicInversed[i]
  376.     else
  377.       result := result or SingleBitArray[i];
  378.   end;
  379. end;
  380.  
  381. function BuildByte(ABits: TByteBitString): Byte;
  382. begin
  383.   result := BuildByte(ByteBitArrayFromBitString(ABits));
  384. end;
  385.  
  386. function BuildByte(ABit1, ABit2, ABit3, ABit4, ABit5, ABit6, ABit7,
  387.   ABit8: TBit): Byte; overload;
  388. var
  389.   ba: TByteBitArray;
  390. begin
  391.   ba[0] := ABit1;
  392.   ba[1] := ABit2;
  393.   ba[2] := ABit3;
  394.   ba[3] := ABit4;
  395.   ba[4] := ABit5;
  396.   ba[5] := ABit6;
  397.   ba[6] := ABit7;
  398.   ba[7] := ABit8;
  399.   result := BuildByte(ba);
  400. end;
  401.  
  402. function ByteBitArrayFromBitString(const ABits: TByteBitString): TByteBitArray;
  403. var
  404.   i: integer;
  405. begin
  406.   if Length(ABits) <> 8 then
  407.   begin
  408.     raise EBitStringTooLong.CreateFmt(LngEBitStringTooLong, [ABits, 8]);
  409.     exit;
  410.   end;
  411.  
  412.   for i := 1 to Length(ABits) do
  413.   begin
  414.     case ABits[i] of
  415.       '0': result[i-1] := false;
  416.       '1': result[i-1] := true;
  417.     else
  418.       raise EBitStringInvalidCharacter.CreateFmt(LngEBitStringInvalidCharacter,
  419.         [ABits, ABits[i], i]);
  420.     end;
  421.   end;
  422. end;
  423.  
  424. function NibbleBitArrayFromBitString(const ABits: THexNibbleBitString):
  425.   THexNibbleBitArray;
  426. var
  427.   i: integer;
  428. begin
  429.   if Length(ABits) <> 4 then
  430.   begin
  431.     raise EBitStringTooLong.CreateFmt(LngEBitStringTooLong, [ABits, 4]);
  432.     exit;
  433.   end;
  434.  
  435.   for i := 1 to Length(ABits) do
  436.   begin
  437.     case ABits[i] of
  438.       '0': result[i-1] := false;
  439.       '1': result[i-1] := true;
  440.     else
  441.       raise EBitStringInvalidCharacter.CreateFmt(LngEBitStringInvalidCharacter,
  442.         [ABits, ABits[i], i]);
  443.     end;
  444.   end;
  445. end;
  446.  
  447. function BuildNibble(ABit1, ABit2, ABit3, ABit4: TBit): Nibble;
  448. var
  449.   ba: THexNibbleBitArray;
  450. begin
  451.   ba[0] := ABit1;
  452.   ba[1] := ABit2;
  453.   ba[2] := ABit3;
  454.   ba[3] := ABit4;
  455.   result := BuildNibble(ba);
  456. end;
  457.  
  458. function BuildNibble(ABitArray: THexNibbleBitArray): Nibble;
  459. var
  460.   i: T4BitPos;
  461. begin
  462.   result := 0;
  463.   for i := Low(T4BitPos) to High(T4BitPos) do
  464.   begin
  465.     // SetNibbleBit(result, i, ABitArray[i]);
  466.  
  467.     if not ABitArray[i] then
  468.       result := result and SingleBitArrayDynamicInversed[i]
  469.     else
  470.       result := result or SingleBitArray[i];
  471.   end;
  472. end;
  473.  
  474. function BuildNibble(ABits: THexNibbleBitString): Nibble;
  475. begin
  476.   result := BuildNibble(NibbleBitArrayFromBitString(ABits));
  477. end;
  478.  
  479. function GetLowerNibble(AByte: Byte): THexNibble;
  480. begin
  481.   result := AByte and AllSetBitsNibble[0];
  482. end;
  483.  
  484. function SetLowerNibble(AByte: Byte; ANewNibble: THexNibble): Byte;
  485. begin
  486.   // result := BuildByte(GetUpperNibble(AByte), ANewNibble);
  487.   // result := $10 * (AByte and AllSetBitsNibble[1] shr 4) + ANewNibble;
  488.   // result := (AByte and AllSetBitsNibble[1] shr 4) shl 4 + ANewNibble;
  489.  
  490.   // Optimized: "shr 4 shl 4" removed
  491.   result := (AByte and AllSetBitsNibble[1]) + ANewNibble;
  492. end;
  493.  
  494. function GetUpperNibble(AByte: Byte): THexNibble;
  495. begin
  496.   result := AByte and AllSetBitsNibble[1] shr 4;
  497. end;
  498.  
  499. function SetUpperNibble(AByte: Byte; ANewNibble: THexNibble): Byte;
  500. begin
  501.   // result := BuildByte(ANewNibble, GetLowerNibble(AByte));
  502.   // result := ($10 * ANewNibble) + (AByte and AllSetBitsNibble[0]);
  503.   result := (ANewNibble shl 4) + (AByte and AllSetBitsNibble[0]);
  504. end;
  505.  
  506. function GetByteBit(AByte: Byte; ABitPos: T8BitPos): TBit;
  507. begin
  508.   // result := AByte and SingleBitArray[ABitPos] shr ABitPos = 1;
  509.   // result := AByte and Math.Power(2, ABitPos) shr ABitPos = 1;
  510.   // result := AByte and SingleBitArray[ABitPos] shr ABitPos = 1;
  511.   result := AByte and SingleBitArray[ABitPos] = SingleBitArray[ABitPos];
  512. end;
  513.  
  514. function SetByteBit(AByte: Byte; ABitPos: T8BitPos; ANewBit: TBit): Byte;
  515. begin
  516.   if not ANewBit then
  517.   begin
  518.     // Set a bit to 0.
  519.     // Example: abcdefgh AND 11111011 = abcde0gh
  520.  
  521.     // result := AByte and (AllSetBitsBytes[0] - SingleBitArray[ABitPos]);
  522.     // result := AByte and (AllSetBitsBytes[0] - Math.Power(2, ABitPos));
  523.     result := AByte and SingleBitArrayDynamicInversed[ABitPos]
  524.   end
  525.   else
  526.   begin
  527.     // Set a bit to 1.
  528.     // Example: abcdefgh OR 00000100 = abcde1gh
  529.  
  530.     // result := AByte or Math.Power(2, ABitPos);
  531.     result := AByte or SingleBitArray[ABitPos];
  532.   end;
  533. end;
  534.  
  535. function GetNibbleBit(ANibble: Nibble; ABitPos: T4BitPos): TBit;
  536. begin
  537.   result := GetByteBit(ANibble, ABitPos);
  538. end;
  539.  
  540. function SetNibbleBit(ANibble: Nibble; ABitPos: T4BitPos;
  541.   ANewBit: TBit): Nibble;
  542. begin
  543.   result := SetByteBit(ANibble, ABitPos, ANewBit);
  544. end;
  545.  
  546. function ByteBitArrayShr(ABitArray: TByteBitArray;
  547.   AVal: Longword): TByteBitArray;
  548. var
  549.   b: Byte;
  550. begin
  551.   b := BuildByte(ABitArray);
  552.   result := GetByteBitArray(b shr AVal);
  553. end;
  554.  
  555. function ByteBitArrayShl(ABitArray: TByteBitArray;
  556.   AVal: Longword): TByteBitArray;
  557. var
  558.   b: Byte;
  559. begin
  560.   b := BuildByte(ABitArray);
  561.   result := GetByteBitArray(b shl AVal);
  562. end;
  563.  
  564. function ByteBitArrayAnd(ABitArray, ABitArray2: TByteBitArray): TByteBitArray;
  565. var
  566.   b, b2: Byte;
  567. begin
  568.   b  := BuildByte(ABitArray);
  569.   b2 := BuildByte(ABitArray2);
  570.   result := GetByteBitArray(b and b2);
  571. end;
  572.  
  573. function ByteBitArrayOr(ABitArray, ABitArray2: TByteBitArray): TByteBitArray;
  574. var
  575.   b, b2: Byte;
  576. begin
  577.   b  := BuildByte(ABitArray);
  578.   b2 := BuildByte(ABitArray2);
  579.   result := GetByteBitArray(b or b2);
  580. end;
  581.  
  582. function ByteBitArrayXor(ABitArray, ABitArray2: TByteBitArray): TByteBitArray;
  583. var
  584.   b, b2: Byte;
  585. begin
  586.   b  := BuildByte(ABitArray);
  587.   b2 := BuildByte(ABitArray2);
  588.   result := GetByteBitArray(b xor b2);
  589. end;
  590.  
  591. function ByteBitArrayNot(ABitArray: TByteBitArray): TByteBitArray;
  592. var
  593.   b: Byte;
  594. begin
  595.   b := BuildByte(ABitArray);
  596.   result := GetByteBitArray(not b);
  597. end;
  598.  
  599. function NibbleBitArrayShr(ABitArray: THexNibbleBitArray; AVal: Longword):
  600.   THexNibbleBitArray;
  601. var
  602.   b: Nibble;
  603. begin
  604.   b := BuildNibble(ABitArray);
  605.   result := GetNibbleBitArray(b shr AVal);
  606. end;
  607.  
  608. function NibbleBitArrayShl(ABitArray: THexNibbleBitArray; AVal: Longword):
  609.   THexNibbleBitArray;
  610. var
  611.   b: Nibble;
  612. begin
  613.   b := BuildNibble(ABitArray);
  614.   result := GetNibbleBitArray(b shl AVal);
  615. end;
  616.  
  617. function NibbleBitArrayAnd(ABitArray, ABitArray2: THexNibbleBitArray):
  618.   THexNibbleBitArray;
  619. var
  620.   b, b2: Nibble;
  621. begin
  622.   b  := BuildNibble(ABitArray);
  623.   b2 := BuildNibble(ABitArray2);
  624.   result := GetNibbleBitArray(b and b2);
  625. end;
  626.  
  627. function NibbleBitArrayOr(ABitArray, ABitArray2: THexNibbleBitArray):
  628.   THexNibbleBitArray;
  629. var
  630.   b, b2: Nibble;
  631. begin
  632.   b  := BuildNibble(ABitArray);
  633.   b2 := BuildNibble(ABitArray2);
  634.   result := GetNibbleBitArray(b or b2);
  635. end;
  636.  
  637. function NibbleBitArrayXor(ABitArray, ABitArray2: THexNibbleBitArray):
  638.   THexNibbleBitArray;
  639. var
  640.   b, b2: Nibble;
  641. begin
  642.   b  := BuildNibble(ABitArray);
  643.   b2 := BuildNibble(ABitArray2);
  644.   result := GetNibbleBitArray(b xor b2);
  645. end;
  646.  
  647. function NibbleBitArrayNot(ABitArray: THexNibbleBitArray): THexNibbleBitArray;
  648. var
  649.   b: Nibble;
  650. begin
  651.   b := BuildNibble(ABitArray);
  652.   result := GetNibbleBitArray(not b);
  653. end;
  654.  
  655. function InverseByteBits(x: Byte): Byte;
  656. begin
  657.   //     10110001
  658.   // xor 11111111
  659.   //   = 01001110
  660.   result := x xor AllSetBitsBytes[0];
  661. end;
  662.  
  663. function InverseNibbleBits(x: Nibble): Nibble;
  664. begin
  665.   //         0001
  666.   // xor     1111
  667.   //   =     1110
  668.   result := x xor AllSetBitsNibbles[0];
  669. end;
  670.  
  671. function InterchangeNibbles(AByte: Byte): Byte;
  672. begin
  673.   // result := BuildByte(GetLowerNibble(AByte), GetUpperNibble(AByte));
  674.   result := (AByte and AllSetBitsNibble[0] shl 4) +
  675.             (AByte and AllSetBitsNibble[1] shr 4)
  676. end;
  677.  
  678. function ReverseByteBitSequence(AByte: Byte): Byte;
  679. var
  680.   ba: TByteBitArray;
  681. begin
  682.   ba := GetByteBitArray(AByte);
  683.   result := BuildByte(ba[7], ba[6], ba[5], ba[4], ba[3], ba[2], ba[1], ba[0]);
  684. end;
  685.  
  686. function ReverseNibbleBitSequence(ANibble: Nibble): Nibble;
  687. var
  688.   ba: THexNibbleBitArray;
  689. begin
  690.   ba := GetNibbleBitArray(ANibble);
  691.   result := BuildNibble(ba[3], ba[2], ba[1], ba[0]);
  692. end;
  693.  
  694. end.