PageRenderTime 59ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/KOLadd.pas

http://github.com/rofl0r/KOL
Pascal | 3354 lines | 2461 code | 282 blank | 611 comment | 200 complexity | 64e8546006bd38acfbf63fccf873ecc9 MD5 | raw file

Large files files are truncated, but you can click here to view the full file

  1. //[START OF KOL.pas]
  2. {****************************************************************
  3. d d
  4. KKKKK KKKKK OOOOOOOOO LLLLL d d
  5. KKKKK KKKKK OOOOOOOOOOOOO LLLLL d d
  6. KKKKK KKKKK OOOOO OOOOO LLLLL aaaa d d
  7. KKKKK KKKKK OOOOO OOOOO LLLLL a d d
  8. KKKKKKKKKK OOOOO OOOOO LLLLL a d d
  9. KKKKK KKKKK OOOOO OOOOO LLLLL aaaaa dddddd dddddd
  10. KKKKK KKKKK OOOOO OOOOO LLLLL a a d d d d
  11. KKKKK KKKKK OOOOOOOOOOOOO LLLLLLLLLLLLL a a d d d d
  12. KKKKK KKKKK OOOOOOOOO LLLLLLLLLLLLL aaaaa aa dddddd dddddd
  13. Key Objects Library (C) 2000 by Kladov Vladimir.
  14. //[VERSION]
  15. ****************************************************************
  16. * VERSION 2.04
  17. ****************************************************************
  18. //[END OF VERSION]
  19. The only reason why this part of KOL separated into another unit is that
  20. Delphi has a restriction to DCU size exceeding which it is failed to debug
  21. it normally and in attempt to execute code step by step an internal error
  22. is occur which stops Delphi from working at all.
  23. Version indicated above is a version of KOL, having place when KOLadd.pas was
  24. modified last time, this is not a version of KOLadd itself.
  25. }
  26. unit KOLadd;
  27. interface
  28. {$I KOLDEF.INC}
  29. uses Windows, KOL;
  30. {------------------------------------------------------------------------------)
  31. | |
  32. | T L i s t E x |
  33. | |
  34. (------------------------------------------------------------------------------}
  35. type
  36. //[TListEx DEFINITION]
  37. {++}(*TListEx = class;*){--}
  38. PListEx = {-}^{+}TListEx;
  39. TListEx = object( TObj )
  40. {* Extended list, with Objects[ ] property. Created calling NewListEx function. }
  41. protected
  42. fList: PList;
  43. fObjects: PList;
  44. function GetEx(Idx: Integer): Pointer;
  45. procedure PutEx(Idx: Integer; const Value: Pointer);
  46. function GetCount: Integer;
  47. function GetAddBy: Integer;
  48. procedure Set_AddBy(const Value: Integer);
  49. public
  50. destructor Destroy; {-}virtual;{+}{++}(*override;*){--}
  51. {* }
  52. property AddBy: Integer read GetAddBy write Set_AddBy;
  53. {* }
  54. property Items[ Idx: Integer ]: Pointer read GetEx write PutEx;
  55. {* }
  56. property Count: Integer read GetCount;
  57. {* }
  58. procedure Clear;
  59. {* }
  60. procedure Add( Value: Pointer );
  61. {* }
  62. procedure AddObj( Value, Obj: Pointer );
  63. {* }
  64. procedure Insert( Idx: Integer; Value: Pointer );
  65. {* }
  66. procedure InsertObj( Idx: Integer; Value, Obj: Pointer );
  67. {* }
  68. procedure Delete( Idx: Integer );
  69. {* }
  70. procedure DeleteRange( Idx, Len: Integer );
  71. {* }
  72. function IndexOf( Value: Pointer ): Integer;
  73. {* }
  74. function IndexOfObj( Obj: Pointer ): Integer;
  75. {* }
  76. procedure Swap( Idx1, Idx2: Integer );
  77. {* }
  78. procedure MoveItem( OldIdx, NewIdx: Integer );
  79. {* }
  80. property ItemsList: PList read fList;
  81. {* }
  82. property ObjList: PList read fObjects;
  83. {* }
  84. function Last: Pointer;
  85. {* }
  86. function LastObj: Pointer;
  87. {* }
  88. end;
  89. //[END OF TListEx DEFINITION]
  90. //[NewListEx DECLARATION]
  91. function NewListEx: PListEx;
  92. {* Creates extended list. }
  93. {------------------------------------------------------------------------------)
  94. | |
  95. | T B i t s |
  96. | |
  97. (------------------------------------------------------------------------------}
  98. type
  99. //[TBits DEFINITION]
  100. {++}(*TBits = class;*){--}
  101. PBits = {-}^{+}TBits;
  102. TBits = object( TObj )
  103. {* Variable-length bits array object. Created using function NewBits. See also
  104. |<a href="kol_pas.htm#Small bit arrays (max 32 bits in array)">
  105. Small bit arrays (max 32 bits in array)
  106. |</a>. }
  107. protected
  108. fList: PList;
  109. fCount: Integer;
  110. function GetBit(Idx: Integer): Boolean;
  111. procedure SetBit(Idx: Integer; const Value: Boolean);
  112. function GetCapacity: Integer;
  113. function GetSize: Integer;
  114. procedure SetCapacity(const Value: Integer);
  115. public
  116. destructor Destroy; {-}virtual;{+}{++}(*override;*){--}
  117. {* }
  118. property Bits[ Idx: Integer ]: Boolean read GetBit write SetBit;
  119. {* }
  120. property Size: Integer read GetSize;
  121. {* Size in bytes of the array. To get know number of bits, use property Count. }
  122. property Count: Integer read fCount;
  123. {* Number of bits an the array. }
  124. property Capacity: Integer read GetCapacity write SetCapacity;
  125. {* Number of bytes allocated. Can be set before assigning bit values
  126. to improve performance (minimizing amount of memory allocation
  127. operations). }
  128. function Copy( From, BitsCount: Integer ): PBits;
  129. {* Use this property to get a sub-range of bits starting from given bit
  130. and of BitsCount bits count. }
  131. function IndexOf( Value: Boolean ): Integer;
  132. {* Returns index of first bit with given value (True or False). }
  133. function OpenBit: Integer;
  134. {* Returns index of the first bit not set to true. }
  135. procedure Clear;
  136. {* Clears bits array. Count, Size and Capacity become 0. }
  137. function LoadFromStream( strm: PStream ): Integer;
  138. {* Loads bits from the stream. Data should be stored in the stream
  139. earlier using SaveToStream method. While loading, previous bits
  140. data are discarded and replaced with new one totally. In part,
  141. Count of bits also is changed. Count of bytes read from the stream
  142. while loading data is returned. }
  143. function SaveToStream( strm: PStream ): Integer;
  144. {* Saves entire array of bits to the stream. First, Count of bits
  145. in the array is saved, then all bytes containing bits data. }
  146. function Range( Idx, N: Integer ): PBits;
  147. {* Creates and returns new TBits object instance containing N bits
  148. starting from index Idx. If you call this method, you are responsible
  149. for destroying returned object when it become not neccessary. }
  150. procedure AssignBits( ToIdx: Integer; FromBits: PBits; FromIdx, N: Integer );
  151. {* Assigns bits from another bits array object. N bits are assigned
  152. starting at index ToIdx. }
  153. end;
  154. //[END OF TBits DEFINITION]
  155. //[NewBits DECLARATION]
  156. function NewBits: PBits;
  157. {* Creates variable-length bits array object. }
  158. {------------------------------------------------------------------------------)
  159. | |
  160. | T F a s t S t r L i s t |
  161. | |
  162. (------------------------------------------------------------------------------}
  163. type
  164. PFastStrListEx = ^TFastStrListEx;
  165. TFastStrListEx = object( TObj )
  166. private
  167. function GetItemLen(Idx: Integer): Integer;
  168. function GetObject(Idx: Integer): DWORD;
  169. procedure SetObject(Idx: Integer; const Value: DWORD);
  170. function GetValues(AName: PChar): PChar;
  171. protected
  172. procedure Init; virtual;
  173. protected
  174. fList: PList;
  175. fCount: Integer;
  176. fCaseSensitiveSort: Boolean;
  177. fTextBuf: PChar;
  178. fTextSiz: DWORD;
  179. fUsedSiz: DWORD;
  180. protected
  181. procedure ProvideSpace( AddSize: DWORD );
  182. function Get(Idx: integer): string;
  183. function GetTextStr: string;
  184. procedure Put(Idx: integer; const Value: string);
  185. procedure SetTextStr(const Value: string);
  186. function GetPChars( Idx: Integer ): PChar;
  187. {++}(*public*){--}
  188. destructor Destroy; {-}virtual;{+}{++}(*override;*){--}
  189. public
  190. function AddAnsi( const S: String ): Integer;
  191. {* Adds Ansi String to a list. }
  192. function AddAnsiObject( const S: String; Obj: DWORD ): Integer;
  193. {* Adds Ansi String and correspondent object to a list. }
  194. function Add(S: PChar): integer;
  195. {* Adds a string to list. }
  196. function AddLen(S: PChar; Len: Integer): integer;
  197. {* Adds a string to list. The string can contain #0 characters. }
  198. public
  199. FastClear: Boolean;
  200. {* }
  201. procedure Clear;
  202. {* Makes string list empty. }
  203. procedure Delete(Idx: integer);
  204. {* Deletes string with given index (it *must* exist). }
  205. function IndexOf(const S: string): integer;
  206. {* Returns index of first string, equal to given one. }
  207. function IndexOf_NoCase(const S: string): integer;
  208. {* Returns index of first string, equal to given one (while comparing it
  209. without case sensitivity). }
  210. function IndexOfStrL_NoCase( Str: PChar; L: Integer ): integer;
  211. {* Returns index of first string, equal to given one (while comparing it
  212. without case sensitivity). }
  213. function Find(const S: String; var Index: Integer): Boolean;
  214. {* Returns Index of the first string, equal or greater to given pattern, but
  215. works only for sorted TFastStrListEx object. Returns TRUE if exact string found,
  216. otherwise nearest (greater then a pattern) string index is returned,
  217. and the result is FALSE. }
  218. procedure InsertAnsi(Idx: integer; const S: String);
  219. {* Inserts ANSI string before one with given index. }
  220. procedure InsertAnsiObject(Idx: integer; const S: String; Obj: DWORD);
  221. {* Inserts ANSI string before one with given index. }
  222. procedure Insert(Idx: integer; S: PChar);
  223. {* Inserts string before one with given index. }
  224. procedure InsertLen( Idx: Integer; S: PChar; Len: Integer );
  225. {* Inserts string from given PChar. It can contain #0 characters. }
  226. function LoadFromFile(const FileName: string): Boolean;
  227. {* Loads string list from a file. (If file does not exist, nothing
  228. happens). Very fast even for huge text files. }
  229. procedure LoadFromStream(Stream: PStream; Append2List: boolean);
  230. {* Loads string list from a stream (from current position to the end of
  231. a stream). Very fast even for huge text. }
  232. procedure MergeFromFile(const FileName: string);
  233. {* Merges string list with strings in a file. Fast. }
  234. procedure Move(CurIndex, NewIndex: integer);
  235. {* Moves string to another location. }
  236. procedure SetText(const S: string; Append2List: boolean);
  237. {* Allows to set strings of string list from given string (in which
  238. strings are separated by $0D,$0A or $0D characters). Text can
  239. contain #0 characters. Works very fast. This method is used in
  240. all others, working with text arrays (LoadFromFile, MergeFromFile,
  241. Assign, AddStrings). }
  242. function SaveToFile(const FileName: string): Boolean;
  243. {* Stores string list to a file. }
  244. procedure SaveToStream(Stream: PStream);
  245. {* Saves string list to a stream (from current position). }
  246. function AppendToFile(const FileName: string): Boolean;
  247. {* Appends strings of string list to the end of a file. }
  248. property Count: integer read fCount;
  249. {* Number of strings in a string list. }
  250. property Items[Idx: integer]: string read Get write Put; default;
  251. {* Strings array items. If item does not exist, empty string is returned.
  252. But for assign to property, string with given index *must* exist. }
  253. property ItemPtrs[ Idx: Integer ]: PChar read GetPChars;
  254. {* Fast access to item strings as PChars. }
  255. property ItemLen[ Idx: Integer ]: Integer read GetItemLen;
  256. {* Length of string item. }
  257. function Last: String;
  258. {* Last item (or '', if string list is empty). }
  259. property Text: string read GetTextStr write SetTextStr;
  260. {* Content of string list as a single string (where strings are separated
  261. by characters $0D,$0A). }
  262. procedure Swap( Idx1, Idx2 : Integer );
  263. {* Swaps to strings with given indeces. }
  264. procedure Sort( CaseSensitive: Boolean );
  265. {* Call it to sort string list. }
  266. public
  267. function AddObject( S: PChar; Obj: DWORD ): Integer;
  268. {* Adds string S (null-terminated) with associated object Obj. }
  269. function AddObjectLen( S: PChar; Len: Integer; Obj: DWORD ): Integer;
  270. {* Adds string S of length Len with associated object Obj. }
  271. procedure InsertObject( Idx: Integer; S: PChar; Obj: DWORD );
  272. {* Inserts string S (null-terminated) at position Idx in the list,
  273. associating it with object Obj. }
  274. procedure InsertObjectLen( Idx: Integer; S: PChar; Len: Integer; Obj: DWORD );
  275. {* Inserts string S of length Len at position Idx in the list,
  276. associating it with object Obj. }
  277. property Objects[ Idx: Integer ]: DWORD read GetObject write SetObject;
  278. {* Access to objects associated with strings in the list. }
  279. public
  280. procedure Append( S: PChar );
  281. {* Appends S (null-terminated) to the last string in FastStrListEx object, very fast. }
  282. procedure AppendLen( S: PChar; Len: Integer );
  283. {* Appends S of length Len to the last string in FastStrListEx object, very fast. }
  284. procedure AppendInt2Hex( N: DWORD; MinDigits: Integer );
  285. {* Converts N to hexadecimal and appends resulting string to the last
  286. string, very fast. }
  287. public
  288. property Values[ Name: PChar ]: PChar read GetValues;
  289. {* Returns a value correspondent to the Name an ini-file-like string list
  290. (having Name1=Value1 Name2=Value2 etc. in each string). }
  291. function IndexOfName( AName: PChar ): Integer;
  292. {* Searches string starting from 'AName=' in string list like ini-file. }
  293. end;
  294. function NewFastStrListEx: PFastStrListEx;
  295. {* Creates FastStrListEx object. }
  296. var Upper: array[ Char ] of Char;
  297. {* An table to convert char to uppercase very fast. First call InitUpper. }
  298. Upper_Initialized: Boolean;
  299. procedure InitUpper;
  300. {* Call this fuction ones to fill Upper[ ] table before using it. }
  301. //[TWStrList]
  302. {-}
  303. {$IFNDEF _FPC}
  304. procedure WStrCopy( Dest, Src: PWideChar );
  305. {* Copies null-terminated Unicode string (terminated null also copied). }
  306. function WStrCmp( W1, W2: PWideChar ): Integer;
  307. {* Compares two null-terminated Unicode strings. }
  308. {$ENDIF _FPC}
  309. {$IFNDEF _D2} //------------------ WideString is not supported in D2 -----------
  310. type
  311. PWStrList = ^TWstrList;
  312. {* }
  313. //[TWstrList DEFINITION]
  314. TWStrList = object( TObj )
  315. {* String list to store Unicode (null-terminated) strings. }
  316. protected
  317. function GetCount: Integer;
  318. function GetItems(Idx: Integer): WideString;
  319. procedure SetItems(Idx: Integer; const Value: WideString);
  320. function GetPtrs(Idx: Integer): PWideChar;
  321. function GetText: WideString;
  322. protected
  323. fList: PList;
  324. fText: PWideChar;
  325. fTextBufSz: Integer;
  326. fTmp1, fTmp2: WideString;
  327. procedure Init; virtual;
  328. public
  329. procedure SetText(const Value: WideString);
  330. {* See also TStrList.SetText }
  331. destructor Destroy; virtual;
  332. {* }
  333. procedure Clear;
  334. {* See also TStrList.Clear }
  335. property Items[ Idx: Integer ]: WideString read GetItems write SetItems;
  336. {* See also TStrList.Items }
  337. property ItemPtrs[ Idx: Integer ]: PWideChar read GetPtrs;
  338. {* See also TStrList.ItemPtrs }
  339. property Count: Integer read GetCount;
  340. {* See also TStrList.Count }
  341. function Add( const W: WideString ): Integer;
  342. {* See also TStrList.Add }
  343. procedure Insert( Idx: Integer; const W: WideString );
  344. {* See also TStrList.Insert }
  345. procedure Delete( Idx: Integer );
  346. {* See also TStrList.Delete }
  347. property Text: WideString read GetText write SetText;
  348. {* See also TStrList.Text }
  349. procedure AddWStrings( WL: PWStrList );
  350. {* See also TStrList.AddStrings }
  351. procedure Assign( WL: PWStrList );
  352. {* See also TStrList.Assign }
  353. function LoadFromFile( const Filename: String ): Boolean;
  354. {* See also TStrList.LoadFromFile }
  355. procedure LoadFromStream( Strm: PStream );
  356. {* See also TStrList.LoadFromStream }
  357. function MergeFromFile( const Filename: String ): Boolean;
  358. {* See also TStrList.MergeFromFile }
  359. procedure MergeFromStream( Strm: PStream );
  360. {* See also TStrList.MergeFromStream }
  361. function SaveToFile( const Filename: String ): Boolean;
  362. {* See also TStrList.SaveToFile }
  363. procedure SaveToStream( Strm: PStream );
  364. {* See also TStrList.SaveToStream }
  365. function AppendToFile( const Filename: String ): Boolean;
  366. {* See also TStrList.AppendToFile }
  367. procedure Swap( Idx1, Idx2: Integer );
  368. {* See also TStrList.Swap }
  369. procedure Sort( CaseSensitive: Boolean );
  370. {* See also TStrList.Sort }
  371. procedure Move( IdxOld, IdxNew: Integer );
  372. {* See also TStrList.Move }
  373. end;
  374. //[END OF TWStrList DEFINITION]
  375. //[TWStrListEx]
  376. PWStrListEx = ^TWStrListEx;
  377. //[TWStrListEx DEFINITION]
  378. TWStrListEx = object( TWStrList )
  379. {* Extended Unicode string list (with Objects). }
  380. protected
  381. function GetObjects(Idx: Integer): DWORD;
  382. procedure SetObjects(Idx: Integer; const Value: DWORD);
  383. procedure ProvideObjectsCapacity( NewCap: Integer );
  384. protected
  385. fObjects: PList;
  386. procedure Init; virtual;
  387. public
  388. destructor Destroy; virtual;
  389. {* }
  390. property Objects[ Idx: Integer ]: DWORD read GetObjects write SetObjects;
  391. {* }
  392. procedure AddWStrings( WL: PWStrListEx );
  393. {* }
  394. procedure Assign( WL: PWStrListEx );
  395. {* }
  396. procedure Clear;
  397. {* }
  398. procedure Delete( Idx: Integer );
  399. {* }
  400. procedure Move( IdxOld, IdxNew: Integer );
  401. {* }
  402. function AddObject( const S: WideString; Obj: DWORD ): Integer;
  403. {* Adds a string and associates given number with it. Index of the item added
  404. is returned. }
  405. procedure InsertObject( Before: Integer; const S: WideString; Obj: DWORD );
  406. {* Inserts a string together with object associated. }
  407. function IndexOfObj( Obj: Pointer ): Integer;
  408. {* Returns an index of a string associated with the object passed as a
  409. parameter. If there are no such strings, -1 is returned. }
  410. end;
  411. //[END OF TWStrListEx DEFINITION]
  412. //[NewWStrList DECLARATION]
  413. function NewWStrList: PWStrList;
  414. {* Creates new TWStrList object and returns a pointer to it. }
  415. //[NewWStrListEx DECLARATION]
  416. function NewWStrListEx: PWStrListEx;
  417. {* Creates new TWStrListEx objects and returns a pointer to it. }
  418. {$ENDIF}
  419. //[CABINET FILES OBJECT]
  420. type
  421. {++}(*TCabFile = class;*){--}
  422. PCABFile = {-}^{+}TCABFile;
  423. TOnNextCAB = function( Sender: PCABFile ): String of object;
  424. TOnCABFile = function( Sender: PCABFile; var FileName: String ): Boolean of object;
  425. { ----------------------------------------------------------------------
  426. TCabFile - windows cabinet files
  427. ----------------------------------------------------------------------- }
  428. //[TCabFile DEFINITION]
  429. TCABFile = object( TObj )
  430. {* An object to simplify extracting files from a cabinet (.CAB) files.
  431. The only what need to use this object, setupapi.dll. It is provided
  432. with all latest versions of Windows. }
  433. protected
  434. FPaths: PStrList;
  435. FNames: PStrList;
  436. FOnNextCAB: TOnNextCAB;
  437. FOnFile: TOnCABFile;
  438. FTargetPath: String;
  439. FSetupapi: THandle;
  440. function GetNames(Idx: Integer): String;
  441. function GetCount: Integer;
  442. function GetPaths(Idx: Integer): String;
  443. function GetTargetPath: String;
  444. protected
  445. FGettingNames: Boolean;
  446. FCurCAB: Integer;
  447. public
  448. destructor Destroy; {-}virtual;{+}{++}(*override;*){--}
  449. {* }
  450. property Paths[ Idx: Integer ]: String read GetPaths;
  451. {* A list of CAB-files. It is stored, when constructing function
  452. OpenCABFile called. }
  453. property Names[ Idx: Integer ]: String read GetNames;
  454. {* A list of file names, stored in a sequence of CAB files. To get know,
  455. how many files are there, check Count property. }
  456. property Count: Integer read GetCount;
  457. {* Number of files stored in a sequence of CAB files. }
  458. function Execute: Boolean;
  459. {* Call this method to extract or enumerate files in CAB. For every
  460. file, found during executing, event OnFile is alled (if assigned).
  461. If the event handler (if any) does not provide full target path for
  462. a file to extract to, property TargetPath is applyed (also if it
  463. is assigned), or file is extracted to the default directory (usually
  464. the same directory there CAB file is located, or current directory
  465. - by a decision of the system).
  466. |<br>
  467. If a sequence of CAB files is used, and not all names for CAB files
  468. are provided (absent or represented by a string '?' ), an event
  469. OnNextCAB is called to obtain the name of the next CAB file.}
  470. property CurCAB: Integer read FCurCAB;
  471. {* Index of current CAB file in a sequence of CAB files. When OnNextCAB
  472. event is called (if any), CurCAB property is already set to the
  473. index of path, what should be provided. }
  474. property OnNextCAB: TOnNextCAB read FOnNextCAB write FOnNextCAB;
  475. {* This event is called, when a series of CAB files is needed and not
  476. all CAB file names are provided (absent or represented by '?' string).
  477. If this event is not assigned, the user is prompted to browse file. }
  478. property OnFile: TOnCABFile read FOnFile write FOnFile;
  479. {* This event is called for every file found during Execute method.
  480. In an event handler (if any assigned), it is possible to return
  481. False to skip file, or to provide another full target path for
  482. file to extract it to, then default. If the event is not assigned,
  483. all files are extracted either to default directory, or to the
  484. directory TargetPath, if it is provided. }
  485. property TargetPath: String read GetTargetPath write FTargetPath;
  486. {* Optional target directory to place there extracted files. }
  487. end;
  488. //[END OF TCABFile DEFINITION]
  489. //[OpenCABFile DECLARATION]
  490. function OpenCABFile( const APaths: array of String ): PCABFile;
  491. {* This function creates TCABFile object, passing a sequence of CAB file names
  492. (fully qualified). It is possible not to provide all names here, or pass '?'
  493. string in place of some of those. For such files, either an event OnNextCAB
  494. will be called, or (and) user will be prompted to browse file during
  495. executing (i.e. Extracting). }
  496. //[DIRCHANGE]
  497. type
  498. {++}(*TDirChange = class;*){--}
  499. PDirChange = {-}^{+}TDirChange;
  500. {* }
  501. TOnDirChange = procedure (Sender: PDirChange; const Path: string) of object;
  502. {* Event type to define OnChange event for folder monitoring objects. }
  503. TFileChangeFilters = (fncFileName, fncDirName, fncAttributes, fncSize,
  504. fncLastWrite, fncLastAccess, fncCreation, fncSecurity);
  505. {* Possible change monitor filters. }
  506. TFileChangeFilter = set of TFileChangeFilters;
  507. {* Set of filters to pass to a constructor of TDirChange object. }
  508. { ----------------------------------------------------------------------
  509. TDirChange object
  510. ----------------------------------------------------------------------- }
  511. //[TDirChange DEFINITION]
  512. TDirChange = object(TObj)
  513. {* Object type to monitor changes in certain folder. }
  514. protected
  515. FOnChange: TOnDirChange;
  516. FHandle: THandle;
  517. FPath: string;
  518. FMonitor: PThread;
  519. function Execute( Sender: PThread ): Integer;
  520. procedure Changed;
  521. protected
  522. {++}(*public*){--}
  523. destructor Destroy; {-}virtual;{+}{++}(*override;*){--}
  524. {*}
  525. public
  526. property Handle: THandle read FHandle;
  527. {* Handle of file change notification object. *}
  528. property Path: String read FPath; //write SetPath;
  529. {* Path to monitored folder (to a root, if tree of folders
  530. is under monitoring). }
  531. end;
  532. //[END OF TDirChange DEFINITION]
  533. //[NewDirChangeNotifier DECLARATION]
  534. function NewDirChangeNotifier( const Path: String; Filter: TFileChangeFilter;
  535. WatchSubtree: Boolean; ChangeProc: TOnDirChange ): PDirChange;
  536. {* Creates notification object TDirChangeNotifier. If something wrong (e.g.,
  537. passed directory does not exist), nil is returned as a result. When change
  538. is notified, ChangeProc is called always in main thread context.
  539. (Please note, that ChangeProc can not be nil).
  540. If empty filter is passed, default filter is used:
  541. [fncFileName..fncLastWrite]. }
  542. //[METAFILES]
  543. type
  544. {++}(*TMetafile = class;*){--}
  545. PMetafile = {-}^{+}TMetafile;
  546. { ----------------------------------------------------------------------
  547. TMetafile - Windows metafile and Enchanced Metafile image
  548. ----------------------------------------------------------------------- }
  549. //[TMetafile DEFINITION]
  550. TMetafile = object( TObj )
  551. {* Object type to incapsulate metafile image. }
  552. protected
  553. function GetHeight: Integer;
  554. function GetWidth: Integer;
  555. procedure SetHandle(const Value: THandle);
  556. protected
  557. fHandle: THandle;
  558. fHeader: PEnhMetaHeader;
  559. procedure RetrieveHeader;
  560. public
  561. destructor Destroy; {-}virtual;{+}{++}(*override;*){--}
  562. {* }
  563. procedure Clear;
  564. {* }
  565. function Empty: Boolean;
  566. {* Returns TRUE if empty}
  567. property Handle: THandle read fHandle write SetHandle;
  568. {* Returns handle of enchanced metafile. }
  569. function LoadFromStream( Strm: PStream ): Boolean;
  570. {* Loads emf or wmf file format from stream. }
  571. function LoadFromFile( const Filename: String ): Boolean;
  572. {* Loads emf or wmf from stream. }
  573. procedure Draw( DC: HDC; X, Y: Integer );
  574. {* Draws enchanced metafile on DC. }
  575. procedure StretchDraw( DC: HDC; const R: TRect );
  576. {* Draws enchanced metafile stretched. }
  577. property Width: Integer read GetWidth;
  578. {* Native width of the metafile. }
  579. property Height: Integer read GetHeight;
  580. {* Native height of the metafile. }
  581. end;
  582. //[END OF TMetafile DEFINITION]
  583. //[NewMetafile DECLARATION]
  584. function NewMetafile: PMetafile;
  585. {* Creates metafile object. }
  586. //[Metafile CONSTANTS, STRUCTURES, ETC.]
  587. const
  588. WMFKey = Integer($9AC6CDD7);
  589. WMFWord = $CDD7;
  590. type
  591. TMetafileHeader = packed record
  592. Key: Longint;
  593. Handle: SmallInt;
  594. Box: TSmallRect;
  595. Inch: Word;
  596. Reserved: Longint;
  597. CheckSum: Word;
  598. end;
  599. function ComputeAldusChecksum(var WMF: TMetafileHeader): Word;
  600. {++}(*
  601. function SetEnhMetaFileBits(p1: UINT; p2: PChar): HENHMETAFILE; stdcall;
  602. function PlayEnhMetaFile(DC: HDC; p2: HENHMETAFILE; const p3: TRect): BOOL; stdcall;
  603. *){--}
  604. // NewActionList, TAction - by Yury Sidorov
  605. //[ACTIONS OBJECT]
  606. { ----------------------------------------------------------------------
  607. TAction and TActionList
  608. ----------------------------------------------------------------------- }
  609. type
  610. PControlRec = ^TControlRec;
  611. TOnUpdateCtrlEvent = procedure(Sender: PControlRec) of object;
  612. TCtrlKind = (ckControl, ckMenu, ckToolbar);
  613. TControlRec = record
  614. Ctrl: PObj;
  615. CtrlKind: TCtrlKind;
  616. ItemID: integer;
  617. UpdateProc: TOnUpdateCtrlEvent;
  618. end;
  619. {++}(* TAction = class;*){--}
  620. PAction = {-}^{+}TAction;
  621. {++}(* TActionList = class;*){--}
  622. PActionList = {-}^{+}TActionList;
  623. //[TAction DEFINITION]
  624. TAction = {-} object( TObj ) {+}{++}(*class*){--}
  625. {*! Use action objects, in conjunction with action lists, to centralize the response
  626. to user commands (actions).
  627. Use AddControl, AddMenuItem, AddToolbarButton methods to link controls to an action.
  628. See also TActionList.
  629. }
  630. protected
  631. FControls: PList;
  632. FCaption: string;
  633. FChecked: boolean;
  634. FVisible: boolean;
  635. FEnabled: boolean;
  636. FHelpContext: integer;
  637. FHint: string;
  638. FOnExecute: TOnEvent;
  639. FAccelerator: TMenuAccelerator;
  640. FShortCut: string;
  641. procedure DoOnMenuItem(Sender: PMenu; Item: Integer);
  642. procedure DoOnToolbarButtonClick(Sender: PControl; BtnID: Integer);
  643. procedure DoOnControlClick(Sender: PObj);
  644. procedure SetCaption(const Value: string);
  645. procedure SetChecked(const Value: boolean);
  646. procedure SetEnabled(const Value: boolean);
  647. procedure SetHelpContext(const Value: integer);
  648. procedure SetHint(const Value: string);
  649. procedure SetVisible(const Value: boolean);
  650. procedure SetAccelerator(const Value: TMenuAccelerator);
  651. procedure UpdateControls;
  652. procedure LinkCtrl(ACtrl: PObj; ACtrlKind: TCtrlKind; AItemID: integer; AUpdateProc: TOnUpdateCtrlEvent);
  653. procedure SetOnExecute(const Value: TOnEvent);
  654. procedure UpdateCtrl(Sender: PControlRec);
  655. procedure UpdateMenu(Sender: PControlRec);
  656. procedure UpdateToolbar(Sender: PControlRec);
  657. public
  658. destructor Destroy; {-}virtual;{+}{++}(*override;*){--}
  659. procedure LinkControl(Ctrl: PControl);
  660. {* Add a link to a TControl or descendant control. }
  661. procedure LinkMenuItem(Menu: PMenu; MenuItemIdx: integer);
  662. {* Add a link to a menu item. }
  663. procedure LinkToolbarButton(Toolbar: PControl; ButtonIdx: integer);
  664. {* Add a link to a toolbar button. }
  665. procedure Execute;
  666. {* Executes a OnExecute event handler. }
  667. property Caption: string read FCaption write SetCaption;
  668. {* Text caption. }
  669. property Hint: string read FHint write SetHint;
  670. {* Hint (tooltip). Currently used for toolbar buttons only. }
  671. property Checked: boolean read FChecked write SetChecked;
  672. {* Checked state. }
  673. property Enabled: boolean read FEnabled write SetEnabled;
  674. {* Enabled state. }
  675. property Visible: boolean read FVisible write SetVisible;
  676. {* Visible state. }
  677. property HelpContext: integer read FHelpContext write SetHelpContext;
  678. {* Help context. }
  679. property Accelerator: TMenuAccelerator read FAccelerator write SetAccelerator;
  680. {* Accelerator for menu items. }
  681. property OnExecute: TOnEvent read FOnExecute write SetOnExecute;
  682. {* This event is executed when user clicks on a linked object or Execute method was called. }
  683. end;
  684. //[END OF TAction DEFINITION]
  685. //[TActionList DEFINITION]
  686. TActionList = {-} object( TObj ) {+}{++}(*class*){--}
  687. {*! TActionList maintains a list of actions used with components and controls,
  688. such as menu items and buttons.
  689. Action lists are used, in conjunction with actions, to centralize the response
  690. to user commands (actions).
  691. Write an OnUpdateActions handler to update actions state.
  692. Created using function NewActionList.
  693. See also TAction.
  694. }
  695. protected
  696. FOwner: PControl;
  697. FActions: PList;
  698. FOnUpdateActions: TOnEvent;
  699. function GetActions(Idx: integer): PAction;
  700. function GetCount: integer;
  701. protected
  702. procedure DoUpdateActions(Sender: PObj);
  703. public
  704. destructor Destroy; {-}virtual;{+}{++}(*override;*){--}
  705. function Add(const ACaption, AHint: string; OnExecute: TOnEvent): PAction;
  706. {* Add a new action to the list. Returns pointer to action object. }
  707. procedure Delete(Idx: integer);
  708. {* Delete action by index from list. }
  709. procedure Clear;
  710. {* Clear all actions in the list. }
  711. property Actions[Idx: integer]: PAction read GetActions;
  712. {* Access to actions in the list. }
  713. property Count: integer read GetCount;
  714. {* Number of actions in the list.. }
  715. property OnUpdateActions: TOnEvent read FOnUpdateActions write FOnUpdateActions;
  716. {* Event handler to update actions state. This event is called each time when application
  717. goes in the idle state (no messages in the queue). }
  718. end;
  719. //[END OF TActionList DEFINITION]
  720. //[NewActionList DECLARATION]
  721. function NewActionList(AOwner: PControl): PActionList;
  722. {* Action list constructor. AOwner - owner form. }
  723. implementation
  724. type
  725. PCrackList = ^TCrackList;
  726. TCrackList = object( TList )
  727. end;
  728. {------------------------------------------------------------------------------)
  729. | |
  730. | T L i s t E x |
  731. | |
  732. (------------------------------------------------------------------------------}
  733. { TListEx }
  734. //[function NewListEx]
  735. function NewListEx: PListEx;
  736. begin
  737. {-}
  738. new( Result, Create );
  739. {+}{++}(*Result := PListEx.Create;*){--}
  740. Result.fList := NewList;
  741. Result.fObjects := NewList;
  742. end;
  743. //[END NewListEx]
  744. //[procedure TListEx.Add]
  745. procedure TListEx.Add(Value: Pointer);
  746. begin
  747. AddObj( Value, nil );
  748. end;
  749. //[procedure TListEx.AddObj]
  750. procedure TListEx.AddObj(Value, Obj: Pointer);
  751. var C: Integer;
  752. begin
  753. C := Count;
  754. fList.Add( Value );
  755. fObjects.Insert( C, Obj );
  756. end;
  757. //[procedure TListEx.Clear]
  758. procedure TListEx.Clear;
  759. begin
  760. fList.Clear;
  761. fObjects.Clear;
  762. end;
  763. //[procedure TListEx.Delete]
  764. procedure TListEx.Delete(Idx: Integer);
  765. begin
  766. DeleteRange( Idx, 1 );
  767. end;
  768. //[procedure TListEx.DeleteRange]
  769. procedure TListEx.DeleteRange(Idx, Len: Integer);
  770. begin
  771. fList.DeleteRange( Idx, Len );
  772. fObjects.DeleteRange( Idx, Len );
  773. end;
  774. //[destructor TListEx.Destroy]
  775. destructor TListEx.Destroy;
  776. begin
  777. fList.Free;
  778. fObjects.Free;
  779. inherited;
  780. end;
  781. //[function TListEx.GetAddBy]
  782. function TListEx.GetAddBy: Integer;
  783. begin
  784. Result := fList.AddBy;
  785. end;
  786. //[function TListEx.GetCount]
  787. function TListEx.GetCount: Integer;
  788. begin
  789. Result := fList.Count;
  790. end;
  791. //[function TListEx.GetEx]
  792. function TListEx.GetEx(Idx: Integer): Pointer;
  793. begin
  794. Result := fList.Items[ Idx ];
  795. end;
  796. //[function TListEx.IndexOf]
  797. function TListEx.IndexOf(Value: Pointer): Integer;
  798. begin
  799. Result := fList.IndexOf( Value );
  800. end;
  801. //[function TListEx.IndexOfObj]
  802. function TListEx.IndexOfObj(Obj: Pointer): Integer;
  803. begin
  804. Result := fObjects.IndexOf( Obj );
  805. end;
  806. //[procedure TListEx.Insert]
  807. procedure TListEx.Insert(Idx: Integer; Value: Pointer);
  808. begin
  809. InsertObj( Idx, Value, nil );
  810. end;
  811. //[procedure TListEx.InsertObj]
  812. procedure TListEx.InsertObj(Idx: Integer; Value, Obj: Pointer);
  813. begin
  814. fList.Insert( Idx, Value );
  815. fObjects.Insert( Idx, Obj );
  816. end;
  817. //[function TListEx.Last]
  818. function TListEx.Last: Pointer;
  819. begin
  820. Result := fList.Last;
  821. end;
  822. //[function TListEx.LastObj]
  823. function TListEx.LastObj: Pointer;
  824. begin
  825. Result := fObjects.Last;
  826. end;
  827. //[procedure TListEx.MoveItem]
  828. procedure TListEx.MoveItem(OldIdx, NewIdx: Integer);
  829. begin
  830. fList.MoveItem( OldIdx, NewIdx );
  831. fObjects.MoveItem( OldIdx, NewIdx );
  832. end;
  833. //[procedure TListEx.PutEx]
  834. procedure TListEx.PutEx(Idx: Integer; const Value: Pointer);
  835. begin
  836. fList.Items[ Idx ] := Value;
  837. end;
  838. //[procedure TListEx.Set_AddBy]
  839. procedure TListEx.Set_AddBy(const Value: Integer);
  840. begin
  841. fList.AddBy := Value;
  842. fObjects.AddBy := Value;
  843. end;
  844. //[procedure TListEx.Swap]
  845. procedure TListEx.Swap(Idx1, Idx2: Integer);
  846. begin
  847. fList.Swap( Idx1, Idx2 );
  848. fObjects.Swap( Idx1, Idx2 );
  849. end;
  850. {------------------------------------------------------------------------------)
  851. | |
  852. | T B i t s |
  853. | |
  854. (------------------------------------------------------------------------------}
  855. { TBits }
  856. //[function NewBits]
  857. function NewBits: PBits;
  858. begin
  859. {-}
  860. new( Result, Create );
  861. {+}{++}(*Result := PBits.Create;*){--}
  862. Result.fList := NewList;
  863. //Result.fList.fAddBy := 1;
  864. end;
  865. //[procedure TBits.AssignBits]
  866. procedure TBits.AssignBits(ToIdx: Integer; FromBits: PBits; FromIdx,
  867. N: Integer);
  868. var i: Integer;
  869. NewCount: Integer;
  870. begin
  871. if FromIdx >= FromBits.Count then Exit;
  872. if FromIdx + N > FromBits.Count then
  873. N := FromBits.Count - FromIdx;
  874. Capacity := (ToIdx + N + 8) div 8;
  875. NewCount := Max( Count, ToIdx + N - 1 );
  876. fCount := Max( NewCount, fCount );
  877. PCrackList( fList ).fCount := (Capacity + 3) div 4;
  878. while ToIdx and $1F <> 0 do
  879. begin
  880. Bits[ ToIdx ] := FromBits.Bits[ FromIdx ];
  881. Inc( ToIdx );
  882. Inc( FromIdx );
  883. Dec( N );
  884. if N = 0 then Exit;
  885. end;
  886. Move( PByte( Integer( PCrackList( FromBits.fList ).fItems ) + (FromIdx + 31) div 32 )^,
  887. PByte( Integer( PCrackList( fList ).fItems ) + ToIdx div 32 )^, (N + 31) div 32 );
  888. FromIdx := FromIdx and $1F;
  889. if FromIdx <> 0 then
  890. begin // shift data by (Idx and $1F) bits right
  891. for i := ToIdx div 32 to fList.Count-2 do
  892. fList.Items[ i ] := Pointer(
  893. (DWORD( fList.Items[ i ] ) shr FromIdx) or
  894. (DWORD( fList.Items[ i+1 ] ) shl (32 - FromIdx))
  895. );
  896. fList.Items[ fList.Count-1 ] := Pointer(
  897. DWORD( fList.Items[ fList.Count-1 ] ) shr FromIdx
  898. );
  899. end;
  900. end;
  901. //[function TBits.Copy]
  902. procedure TBits.Clear;
  903. begin
  904. fCount := 0;
  905. fList.Clear;
  906. end;
  907. function TBits.Copy(From, BitsCount: Integer): PBits;
  908. var Shift, N: Integer;
  909. FirstItemPtr: Pointer;
  910. begin
  911. Result := NewBits;
  912. if BitsCount = 0 then Exit;
  913. Result.Capacity := BitsCount + 32;
  914. Result.fCount := BitsCount;
  915. Move( PCrackList( fList ).fItems[ From shr 5 ],
  916. PCrackList( Result.fList ).fItems[ 0 ], (Count + 31) div 32 );
  917. Shift := From and $1F;
  918. if Shift <> 1 then
  919. begin
  920. N := (BitsCount + 31) div 32;
  921. FirstItemPtr := @ PCrackList( Result.fList ).fItems[ N - 1 ];
  922. asm
  923. PUSH ESI
  924. PUSH EDI
  925. MOV ESI, FirstItemPtr
  926. MOV EDI, ESI
  927. STD
  928. MOV ECX, N
  929. XOR EAX, EAX
  930. CDQ
  931. @@1:
  932. PUSH ECX
  933. LODSD
  934. MOV ECX, Shift
  935. SHRD EAX, EDX, CL
  936. STOSD
  937. SUB ECX, 32
  938. NEG ECX
  939. SHR EDX, CL
  940. POP ECX
  941. LOOP @@1
  942. CLD
  943. POP EDI
  944. POP ESI
  945. end {$IFDEF F_P} ['EAX','EDX','ECX'] {$ENDIF};
  946. end;
  947. end;
  948. //[destructor TBits.Destroy]
  949. destructor TBits.Destroy;
  950. begin
  951. fList.Free;
  952. inherited;
  953. end;
  954. //[function TBits.GetBit]
  955. {$IFDEF ASM_VERSION}
  956. function TBits.GetBit(Idx: Integer): Boolean;
  957. asm
  958. CMP EDX, [EAX].FCount
  959. JL @@1
  960. XOR EAX, EAX
  961. RET
  962. @@1:
  963. MOV EAX, [EAX].fList
  964. {TEST EAX, EAX
  965. JZ @@exit}
  966. MOV EAX, [EAX].TList.fItems
  967. BT [EAX], EDX
  968. SETC AL
  969. @@exit:
  970. end;
  971. {$ELSE}
  972. function TBits.GetBit(Idx: Integer): Boolean;
  973. begin
  974. if (Idx >= Count) {or (PCrackList( fList ).fItems = nil)} then Result := FALSE else
  975. Result := ( ( DWORD( PCrackList( fList ).fItems[ Idx shr 5 ] ) shr (Idx and $1F)) and 1 ) <> 0;
  976. end;
  977. {$ENDIF}
  978. //[function TBits.GetCapacity]
  979. function TBits.GetCapacity: Integer;
  980. begin
  981. Result := fList.Capacity * 32;
  982. end;
  983. //[function TBits.GetSize]
  984. function TBits.GetSize: Integer;
  985. begin
  986. Result := ( PCrackList( fList ).fCount + 3) div 4;
  987. end;
  988. {$IFDEF ASM_noVERSION}
  989. //[function TBits.IndexOf]
  990. function TBits.IndexOf(Value: Boolean): Integer;
  991. asm //cmd //opd
  992. PUSH EDI
  993. MOV EDI, [EAX].fList
  994. MOV ECX, [EDI].TList.fCount
  995. @@ret_1:
  996. OR EAX, -1
  997. JECXZ @@ret_EAX
  998. MOV EDI, [EDI].TList.fItems
  999. TEST DL, DL
  1000. MOV EDX, EDI
  1001. JE @@of_false
  1002. INC EAX
  1003. REPZ SCASD
  1004. JE @@ret_1
  1005. MOV EAX, [EDI-4]
  1006. NOT EAX
  1007. JMP @@calc_offset
  1008. BSF EAX, EAX
  1009. SUB EDI, EDX
  1010. SHR EDI, 2
  1011. ADD EAX, EDI
  1012. JMP @@ret_EAX
  1013. @@of_false:
  1014. REPE SCASD
  1015. JE @@ret_1
  1016. MOV EAX, [EDI-4]
  1017. @@calc_offset:
  1018. BSF EAX, EAX
  1019. DEC EAX
  1020. SUB EDI, 4
  1021. SUB EDI, EDX
  1022. SHL EDI, 3
  1023. ADD EAX, EDI
  1024. @@ret_EAX:
  1025. POP EDI
  1026. end;
  1027. {$ELSE ASM_VERSION} //Pascal
  1028. function TBits.IndexOf(Value: Boolean): Integer;
  1029. var I: Integer;
  1030. D: DWORD;
  1031. begin
  1032. Result := -1;
  1033. if Value then
  1034. begin
  1035. for I := 0 to fList.Count-1 do
  1036. begin
  1037. D := DWORD( PCrackList( fList ).fItems[ I ] );
  1038. if D <> 0 then
  1039. begin
  1040. asm
  1041. MOV EAX, D
  1042. BSF EAX, EAX
  1043. MOV D, EAX
  1044. end {$IFDEF F_P} [ 'EAX' ] {$ENDIF};
  1045. Result := I * 32 + Integer( D );
  1046. break;
  1047. end;
  1048. end;
  1049. end
  1050. else
  1051. begin
  1052. for I := 0 to PCrackList( fList ).fCount-1 do
  1053. begin
  1054. D := DWORD( PCrackList( fList ).fItems[ I ] );
  1055. if D <> $FFFFFFFF then
  1056. begin
  1057. asm
  1058. MOV EAX, D
  1059. NOT EAX
  1060. BSF EAX, EAX
  1061. MOV D, EAX
  1062. end {$IFDEF F_P} [ 'EAX' ] {$ENDIF};
  1063. Result := I * 32 + Integer( D );
  1064. break;
  1065. end;
  1066. end;
  1067. end;
  1068. end;
  1069. {$ENDIF ASM_VERSION}
  1070. //[function TBits.LoadFromStream]
  1071. function TBits.LoadFromStream(strm: PStream): Integer;
  1072. var
  1073. i: Integer;
  1074. begin
  1075. Result := strm.Read( i, 4 );
  1076. if Result < 4 then Exit;
  1077. bits[ i]:= false; //by miek
  1078. fcount:= i;
  1079. i := (i + 7) div 8;
  1080. Inc( Result, strm.Read( PCrackList( fList ).fItems^, i ) );
  1081. end;
  1082. //[function TBits.OpenBit]
  1083. function TBits.OpenBit: Integer;
  1084. begin
  1085. Result := IndexOf( FALSE );
  1086. if Result < 0 then Result := Count;
  1087. end;
  1088. //[function TBits.Range]
  1089. function TBits.Range(Idx, N: Integer): PBits;
  1090. begin
  1091. Result := NewBits;
  1092. Result.AssignBits( 0, @ Self, Idx, N );
  1093. end;
  1094. //[function TBits.SaveToStream]
  1095. function TBits.SaveToStream(strm: PStream): Integer;
  1096. begin
  1097. Result := strm.Write( fCount, 4 );
  1098. if fCount = 0 then Exit;
  1099. Inc( Result, strm.Write( PCrackList( fList ).fItems^, (fCount + 7) div 8 ) );
  1100. end;
  1101. //[procedure TBits.SetBit]
  1102. {$IFDEF ASM_VERSION}
  1103. procedure TBits.SetBit(Idx: Integer; const Value: Boolean);
  1104. asm
  1105. PUSH ECX
  1106. MOV ECX, [EAX].fList
  1107. MOV ECX, [ECX].TList.fCapacity
  1108. SHL ECX, 5
  1109. CMP EDX, ECX
  1110. JLE @@1
  1111. PUSH EDX
  1112. INC EDX
  1113. PUSH EAX
  1114. CALL SetCapacity
  1115. POP EAX
  1116. POP EDX
  1117. @@1:
  1118. CMP EDX, [EAX].FCount
  1119. JL @@2
  1120. INC EDX
  1121. MOV [EAX].fCount, EDX
  1122. DEC EDX
  1123. @@2:
  1124. POP ECX
  1125. MOV EAX, [EAX].fList
  1126. MOV EAX, [EAX].TList.fItems
  1127. SHR ECX, 1
  1128. JC @@2set
  1129. BTR [EAX], EDX
  1130. JMP @@exit
  1131. @@2set:
  1132. BTS [EAX], EDX
  1133. @@exit:
  1134. end;
  1135. {$ELSE}
  1136. procedure TBits.SetBit(Idx: Integer; const Value: Boolean);
  1137. var Msk: DWORD;
  1138. begin
  1139. if Idx >= Capacity then
  1140. Capacity := Idx + 1;
  1141. Msk := 1 shl (Idx and $1F);
  1142. if Value then
  1143. PCrackList( fList ).fItems[ Idx shr 5 ] := Pointer(
  1144. DWORD(PCrackList( fList ).fItems[ Idx shr 5 ]) or Msk)
  1145. else
  1146. PCrackList( fList ).fItems[ Idx shr 5 ] := Pointer(
  1147. DWORD(PCrackList( fList ).fItems[ Idx shr 5 ]) and not Msk);
  1148. if Idx >= fCount then
  1149. fCount := Idx + 1;
  1150. end;
  1151. {$ENDIF}
  1152. //[procedure TBits.SetCapacity]
  1153. procedure TBits.SetCapacity(const Value: Integer);
  1154. var OldCap: Integer;
  1155. begin
  1156. OldCap := fList.Capacity;
  1157. fList.Capacity := (Value + 31) div 32;
  1158. if OldCap < fList.Capacity then
  1159. FillChar( PChar( Integer( PCrackList( fList ).fItems ) + OldCap * Sizeof( Pointer ) )^,
  1160. (fList.Capacity - OldCap) * sizeof( Pointer ), 0 );
  1161. end;
  1162. {------------------------------------------------------------------------------)
  1163. | |
  1164. | T F a s t S t r L i s t |
  1165. | |
  1166. (------------------------------------------------------------------------------}
  1167. function NewFastStrListEx: PFastStrListEx;
  1168. begin
  1169. new( Result, Create );
  1170. end;
  1171. procedure InitUpper;
  1172. var c: Char;
  1173. begin
  1174. for c := #0 to #255 do
  1175. Upper[ c ] := AnsiUpperCase( c + #0 )[ 1 ];
  1176. Upper_Initialized := TRUE;
  1177. end;
  1178. { TFastStrListEx }
  1179. function TFastStrListEx.AddAnsi(const S: String): Integer;
  1180. begin
  1181. Result := AddObjectLen( PChar( S ), Length( S ), 0 );
  1182. end;
  1183. function TFastStrListEx.AddAnsiObject(const S: String; Obj: DWORD): Integer;
  1184. begin
  1185. Result := AddObjectLen( PChar( S ), Length( S ), Obj );
  1186. end;
  1187. function TFastStrListEx.Add(S: PChar): integer;
  1188. begin
  1189. Result := AddObjectLen( S, StrLen( S ), 0 )
  1190. end;
  1191. function TFastStrListEx.AddLen(S: PChar; Len: Integer): integer;
  1192. begin
  1193. Result := AddObjectLen( S, Len, 0 )
  1194. end;
  1195. function TFastStrListEx.AddObject(S: PChar; Obj: DWORD): Integer;
  1196. begin
  1197. Result := AddObjectLen( S, StrLen( S ), Obj )
  1198. end;
  1199. function TFastStrListEx.AddObjectLen(S: PChar; Len: Integer; Obj: DWORD): Integer;
  1200. var Dest: PChar;
  1201. begin
  1202. ProvideSpace( Len + 9 );
  1203. Dest := PChar( DWORD( fTextBuf ) + fUsedSiz );
  1204. Result := fCount;
  1205. Inc( fCount );
  1206. fList.Add( Pointer( DWORD(Dest)-DWORD(fTextBuf) ) );
  1207. PDWORD( Dest )^ := Obj;
  1208. Inc( Dest, 4 );
  1209. PDWORD( Dest )^ := Len;
  1210. Inc( Dest, 4 );
  1211. if S <> nil then
  1212. System.Move( S^, Dest^, Len );
  1213. Inc( Dest, Len );
  1214. Dest^ := #0;
  1215. Inc( fUsedSiz, Len+9 );
  1216. end;
  1217. function TFastStrListEx.AppendToFile(const FileName: string): Boolean;
  1218. var F: HFile;
  1219. Txt: String;
  1220. begin
  1221. Txt := Text;
  1222. F := FileCreate( FileName, ofOpenAlways or ofOpenReadWrite or ofShareDenyWrite );
  1223. if F = INVALID_HANDLE_VALUE then Result := FALSE
  1224. else begin
  1225. FileSeek( F, 0, spEnd );
  1226. Result := FileWrite( F, PChar( Txt )^, Length( Txt ) ) = DWORD( Length( Txt ) );
  1227. FileClose( F );
  1228. end;
  1229. end;
  1230. procedure TFastStrListEx.Clear;
  1231. begin
  1232. if FastClear then
  1233. begin
  1234. if fList.Count > 0 then
  1235. PCrackList(fList).FCount := 0;
  1236. end
  1237. else
  1238. begin
  1239. fList.Clear;
  1240. if fTextBuf <> nil then
  1241. FreeMem( fTextBuf );
  1242. fTextBuf := nil;
  1243. end;
  1244. fTextSiz := 0;
  1245. fUsedSiz := 0;
  1246. fCount := 0;
  1247. end;
  1248. procedure TFastStrListEx.Delete(Idx: integer);
  1249. begin
  1250. if (Idx < 0) or (Idx >= Count) then Exit;
  1251. if Idx = Count-1 then
  1252. Dec( fUsedSiz, ItemLen[ Idx ]+9 );
  1253. fList.Delete( Idx );
  1254. Dec( fCount );
  1255. end;
  1256. destructor TFastStrListEx.Destroy;
  1257. begin
  1258. FastClear := FALSE;
  1259. Clear;
  1260. fList.Free;
  1261. inherited;
  1262. end;
  1263. function TFastStrListEx.Find(const S: String; var Index: Integer): Boolean;
  1264. var i: Integer;
  1265. begin
  1266. for i := 0 to Count-1 do
  1267. if (ItemLen[ i ] = Length( S )) and
  1268. ((S = '') or CompareMem( ItemPtrs[ i ], @ S[ 1 ], Length( S ) )) then
  1269. begin
  1270. Index := i;
  1271. Result := TRUE;
  1272. Exit;
  1273. end;
  1274. Result := FALSE;
  1275. end;
  1276. function TFastStrListEx.Get(Idx: integer): string;
  1277. begin
  1278. if (Idx >= 0) and (Idx <= Count) then
  1279. SetString( Result, PChar( DWORD( fTextBuf ) + DWORD( fList.Items[ Idx ] ) + 8 ),
  1280. ItemLen[ Idx ] )
  1281. else
  1282. Result := '';
  1283. end;
  1284. function TFastStrListEx.GetItemLen(Idx: Integer): Integer;
  1285. var Src: PDWORD;
  1286. begin
  1287. if (Idx >= 0) and (Idx <= Count) then
  1288. begin
  1289. Src := PDWORD( DWORD( fTextBuf ) + DWORD( fList.Items[ Idx ] ) + 4 );
  1290. Result := Src^
  1291. end
  1292. else Result := 0;
  1293. end;
  1294. function TFastStrListEx.GetObject(Idx: Integer): DWORD;
  1295. var Src: PDWORD;
  1296. begin
  1297. if (Idx >= 0) and (Idx <= Count) then
  1298. begin
  1299. Src := PDWORD( DWORD( fTextBuf ) + DWORD( fList.Items[ Idx ] ) );
  1300. Result := Src^
  1301. end
  1302. else Result := 0;
  1303. end;
  1304. function TFastStrListEx.GetPChars(Idx: Integer): PChar;
  1305. begin
  1306. if (Idx >= 0) and (Idx <= Count) then
  1307. Result := PChar( DWORD( fTextBuf ) + DWORD( fList.Items[ Idx ] ) + 8 )
  1308. else Result := nil;
  1309. end;
  1310. function TFastStrListEx.GetTextStr: string;
  1311. var L, i: Integer;
  1312. p: PChar;
  1313. begin
  1314. L := 0;
  1315. for i := 0 to Count-1 do
  1316. Inc( L, ItemLen[ i ] + 2 );
  1317. SetLength( Result, L );
  1318. p := PChar( Result );
  1319. for i := 0 to Count-1 do
  1320. begin
  1321. L := ItemLen[ i ];
  1322. if L > 0 then
  1323. begin
  1324. System.Move( ItemPtrs[ i ]^, p^, L );
  1325. Inc( p, L );
  1326. end;
  1327. p^ := #13; Inc( p );
  1328. p^ := #10; Inc( p );
  1329. end;
  1330. end;
  1331. function TFastStrListEx.IndexOf(const S: string): integer;
  1332. begin
  1333. if not Find( S, Result ) then Result := -1;
  1334. end;
  1335. function TFastStrListEx.IndexOf_NoCase(const S: string): integer;
  1336. begin
  1337. Result := IndexOfStrL_NoCase( PChar( S ), Length( S ) );
  1338. end;
  1339. function TFastStrListEx.IndexOfStrL_NoCase(Str: PChar;
  1340. L: Integer): integer;
  1341. var i: Integer;
  1342. begin
  1343. for i := 0 to Count-1 do
  1344. if (ItemLen[ i ] = L) and
  1345. ((L = 0) or (StrLComp_NoCase( ItemPtrs[ i ], Str, L ) = 0)) then
  1346. begin
  1347. Result := i;
  1348. Exit;
  1349. end;
  1350. Result := -1;
  1351. end;
  1352. procedure TFastStrListEx.Init;
  1353. begin
  1354. fList := NewList;
  1355. FastClear := TRUE;
  1356. end;
  1357. procedure TFastStrListEx.InsertAnsi(Idx: integer; const S: String);
  1358. begin
  1359. InsertObjectLen( Idx, PChar( S ), Length( S ), 0 );
  1360. end;
  1361. procedure TFastStrListEx.InsertAnsiObject(Idx: integer; const S: String;
  1362. Obj: DWORD);
  1363. begin
  1364. InsertObjectLen( Idx, PChar( S ), Length( S ), Obj );
  1365. end;
  1366. procedure TFastStrListEx.Insert(Idx: integer; S: PChar);
  1367. begin
  1368. InsertObjectLen( Idx, S, StrLen( S ), 0 )
  1369. end;
  1370. procedure TFastStrListEx.InsertLen(Idx: Integer; S: PChar; Len: Integer);
  1371. begin
  1372. InsertObjectLen( Idx, S, Len, 0 )
  1373. end;
  1374. procedure TFastStrListEx.InsertObject(Idx: Integer; S: PChar; Obj: DWORD);
  1375. begin
  1376. Ins

Large files files are truncated, but you can click here to view the full file