bits.inc 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366
  1. {
  2. This file is part of the Free Component Library (FCL)
  3. Copyright (c) 1999-2000 by the Free Pascal development team
  4. See the file COPYING.FPC, included in this distribution,
  5. for details about the copyright.
  6. This program is distributed in the hope that it will be useful,
  7. but WITHOUT ANY WARRANTY; without even the implied warranty of
  8. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  9. **********************************************************************}
  10. {****************************************************************************}
  11. {* TBits *}
  12. {****************************************************************************}
  13. Procedure BitsError (Msg : string);
  14. begin
  15. Raise EBitsError.Create(Msg) at get_caller_addr(get_frame);
  16. end;
  17. Procedure BitsErrorFmt (Msg : string; const Args : array of const);
  18. begin
  19. Raise EBitsError.CreateFmt(Msg,args) at get_caller_addr(get_frame);
  20. end;
  21. procedure TBits.CheckBitIndex (Bit : longint;CurrentSize : Boolean);
  22. begin
  23. if (bit<0) or (CurrentSize and (Bit>Size)) then
  24. BitsErrorFmt(SErrInvalidBitIndex,[bit]);
  25. if (bit>=MaxBitFlags) then
  26. BitsErrorFmt(SErrIndexTooLarge,[bit])
  27. end;
  28. { ************* functions to match TBits class ************* }
  29. function TBits.getSize : longint;
  30. begin
  31. result := (FSize shl BITSHIFT) - 1;
  32. end;
  33. procedure TBits.setSize(value : longint);
  34. begin
  35. grow(value - 1);
  36. end;
  37. procedure TBits.SetBit(bit : longint; value : Boolean);
  38. begin
  39. if value = True then
  40. seton(bit)
  41. else
  42. clear(bit);
  43. end;
  44. function TBits.OpenBit : longint;
  45. var
  46. loop : longint;
  47. loop2 : longint;
  48. startIndex : longint;
  49. begin
  50. result := -1; {should only occur if the whole array is set}
  51. for loop := 0 to FSize - 1 do
  52. begin
  53. if FBits^[loop] <> $FFFFFFFF then
  54. begin
  55. startIndex := loop * 32;
  56. for loop2 := startIndex to startIndex + 31 do
  57. begin
  58. if get(loop2) = False then
  59. begin
  60. result := loop2;
  61. break; { use this as the index to return }
  62. end;
  63. end;
  64. break; {stop looking for empty bit in records }
  65. end;
  66. end;
  67. if result = -1 then
  68. if FSize < MaxBitRec then
  69. result := FSize * 32; {first bit of next record}
  70. end;
  71. { ******************** TBits ***************************** }
  72. constructor TBits.Create(theSize : longint = 0 );
  73. begin
  74. FSize := 0;
  75. FBits := nil;
  76. findIndex := -1;
  77. findState := True; { no reason just setting it to something }
  78. grow(theSize);
  79. end;
  80. destructor TBits.Destroy;
  81. begin
  82. if FBits <> nil then
  83. FreeMem(FBits, FSize * SizeOf(longint));
  84. FBits := nil;
  85. inherited Destroy;
  86. end;
  87. procedure TBits.grow(nbit : longint);
  88. var
  89. newSize : longint;
  90. loop : longint;
  91. begin
  92. CheckBitindex(nbit,false);
  93. newSize := (nbit shr BITSHIFT) + 1;
  94. if newSize > FSize then
  95. begin
  96. ReAllocMem(FBits, newSize * SizeOf(longint));
  97. if FBits <> nil then
  98. begin
  99. if newSize > FSize then
  100. for loop := FSize to newSize - 1 do
  101. FBits^[loop] := 0;
  102. FSize := newSize;
  103. end
  104. else
  105. BitsError(SErrOutOfMemory);
  106. end;
  107. end;
  108. function TBits.getFSize : longint;
  109. begin
  110. result := FSize;
  111. end;
  112. procedure TBits.seton(bit : longint);
  113. var
  114. n : longint;
  115. begin
  116. n := bit shr BITSHIFT;
  117. grow(bit);
  118. FBits^[n] := FBits^[n] or (longint(1) shl (bit and MASK));
  119. end;
  120. procedure TBits.clear(bit : longint);
  121. var
  122. n : longint;
  123. begin
  124. CheckBitIndex(bit,false);
  125. n := bit shr BITSHIFT;
  126. grow(bit);
  127. FBits^[n] := FBits^[n] and not(longint(1) shl (bit and MASK));
  128. end;
  129. procedure TBits.clearall;
  130. var
  131. loop : longint;
  132. begin
  133. for loop := 0 to FSize - 1 do
  134. FBits^[loop] := 0;
  135. end;
  136. function TBits.get(bit : longint) : Boolean;
  137. var
  138. n : longint;
  139. begin
  140. CheckBitIndex(bit,true);
  141. result := False;
  142. n := bit shr BITSHIFT;
  143. if (n < FSize) then
  144. result := (FBits^[n] and (longint(1) shl (bit and MASK))) <> 0;
  145. end;
  146. procedure TBits.andbits(bitset : TBits);
  147. var
  148. n : longint;
  149. loop : longint;
  150. begin
  151. if FSize < bitset.getFSize then
  152. n := FSize - 1
  153. else
  154. n := bitset.getFSize - 1;
  155. for loop := 0 to n do
  156. FBits^[loop] := FBits^[loop] and bitset.FBits^[loop];
  157. for loop := n + 1 to FSize - 1 do
  158. FBits^[loop] := 0;
  159. end;
  160. procedure TBits.notbits(bitset : TBits);
  161. var
  162. n : longint;
  163. jj : longint;
  164. loop : longint;
  165. begin
  166. if FSize < bitset.getFSize then
  167. n := FSize - 1
  168. else
  169. n := bitset.getFSize - 1;
  170. for loop := 0 to n do
  171. begin
  172. jj := FBits^[loop];
  173. FBits^[loop] := FBits^[loop] and (jj xor bitset.FBits^[loop]);
  174. end;
  175. end;
  176. procedure TBits.orbits(bitset : TBits);
  177. var
  178. n : longint;
  179. loop : longint;
  180. begin
  181. if FSize < bitset.getFSize then
  182. n := bitset.getFSize - 1
  183. else
  184. n := FSize - 1;
  185. grow(n shl BITSHIFT);
  186. for loop := 0 to n do
  187. FBits^[loop] := FBits^[loop] or bitset.FBits^[loop];
  188. end;
  189. procedure TBits.xorbits(bitset : TBits);
  190. var
  191. n : longint;
  192. loop : longint;
  193. begin
  194. if FSize < bitset.getFSize then
  195. n := bitset.getFSize - 1
  196. else
  197. n := FSize - 1;
  198. grow(n shl BITSHIFT);
  199. for loop := 0 to n do
  200. FBits^[loop] := FBits^[loop] xor bitset.FBits^[loop];
  201. end;
  202. function TBits.equals(bitset : TBits) : Boolean;
  203. var
  204. n : longint;
  205. loop : longint;
  206. begin
  207. result := False;
  208. if FSize < bitset.getFSize then
  209. n := FSize - 1
  210. else
  211. n := bitset.getFSize - 1;
  212. for loop := 0 to n do
  213. if FBits^[loop] <> bitset.FBits^[loop] then exit;
  214. if FSize - 1 > n then
  215. begin
  216. for loop := n to FSize - 1 do
  217. if FBits^[loop] <> 0 then exit;
  218. end
  219. else if bitset.getFSize - 1 > n then
  220. for loop := n to bitset.getFSize - 1 do
  221. if bitset.FBits^[loop] <> 0 then exit;
  222. result := True; {passed all tests}
  223. end;
  224. { us this in place of calling FindFirstBit. It sets the current }
  225. { index used by FindNextBit and FindPrevBit }
  226. procedure TBits.SetIndex(index : longint);
  227. begin
  228. findIndex := index;
  229. end;
  230. { When state is set to True it looks for bits that are turned On (1) }
  231. { and when it is set to False it looks for bits that are turned }
  232. { off (0). }
  233. function TBits.FindFirstBit(state : boolean) : longint;
  234. var
  235. loop : longint;
  236. loop2 : longint;
  237. startIndex : longint;
  238. compareVal : cardinal;
  239. begin
  240. result := -1; {should only occur if none are set}
  241. findState := state;
  242. if state = False then
  243. compareVal := $FFFFFFFF { looking for off bits }
  244. else
  245. compareVal := $00000000; { looking for on bits }
  246. for loop := 0 to FSize - 1 do
  247. begin
  248. if FBits^[loop] <> compareVal then
  249. begin
  250. startIndex := loop * 32;
  251. for loop2 := startIndex to startIndex + 31 do
  252. begin
  253. if get(loop2) = state then
  254. begin
  255. result := loop2;
  256. break; { use this as the index to return }
  257. end;
  258. end;
  259. break; {stop looking for bit in records }
  260. end;
  261. end;
  262. findIndex := result;
  263. end;
  264. function TBits.FindNextBit : longint;
  265. var
  266. loop : longint;
  267. maxVal : longint;
  268. begin
  269. result := -1; { will occur only if no other bits set to }
  270. { current findState }
  271. if findIndex > -1 then { must have called FindFirstBit first }
  272. begin { or set the start index }
  273. maxVal := (FSize * 32) - 1;
  274. for loop := findIndex + 1 to maxVal do
  275. begin
  276. if get(loop) = findState then
  277. begin
  278. result := loop;
  279. break;
  280. end;
  281. end;
  282. findIndex := result;
  283. end;
  284. end;
  285. function TBits.FindPrevBit : longint;
  286. var
  287. loop : longint;
  288. begin
  289. result := -1; { will occur only if no other bits set to }
  290. { current findState }
  291. if findIndex > -1 then { must have called FindFirstBit first }
  292. begin { or set the start index }
  293. for loop := findIndex - 1 downto 0 do
  294. begin
  295. if get(loop) = findState then
  296. begin
  297. result := loop;
  298. break;
  299. end;
  300. end;
  301. findIndex := result;
  302. end;
  303. end;