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. |