Subversion Repositories delphiutils

Rev

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