Subversion Repositories delphiutils

Rev

Rev 12 | Details | Compare with Previous | Last modification | View Log | RSS feed

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