bits.inc 8.5 KB

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