PageRenderTime 69ms CodeModel.GetById 29ms RepoModel.GetById 0ms app.codeStats 0ms

/General-Purpose-Units/Temp/MeaningUnit.pp

http://my-units.googlecode.com/
Puppet | 2241 lines | 1597 code | 644 blank | 0 comment | 149 complexity | e083cac245a986017e3c95a65f054902 MD5 | raw file
  1. unit MeaningUnit;
  2. {$mode objfpc}{$H+}
  3. interface
  4. uses
  5. Classes, SysUtils, CollectionBaseUnit;
  6. const
  7. SpaceCode= 254;
  8. EoFCode= 255;
  9. type
  10. TChar= String;
  11. TWordEncoding= (weStart, wePersian, weEnglish, weEnd);
  12. // TCharSet= set of TChar;
  13. { EAnInvalidCharEncountered }
  14. EAnInvalidCharEncountered= class (Exception)
  15. private
  16. public
  17. constructor Create (Char: String);
  18. end;
  19. EEndOfMeaningOccured= class (Exception);
  20. EInvalidFile= class (Exception);
  21. EWMCIndexCollectionCannotBeMade= class (Exception);
  22. { TWord }
  23. TWord= class (TObject)
  24. private
  25. FChars: array of TChar;
  26. FEncoding: TWordEncoding;
  27. function GetChars (Index: Integer): TChar;
  28. function GetLength: Integer;
  29. function ReadNextCharFromStream (InputStream: TStream): string;
  30. public
  31. property Chars [Index: Integer]: TChar read GetChars;
  32. property Length: Integer read GetLength;
  33. property Encoding: TWordEncoding read FEncoding;
  34. procedure AddChar (NewChar: TChar);
  35. function StartWith (Str: String): Boolean;
  36. function EndWith (Str: String): Boolean;
  37. function Copy: TWord;
  38. constructor Create (WordEncoding: TWordEncoding= weEnglish);
  39. procedure Free;
  40. procedure LoadFromString (InputString: String);
  41. procedure LoadFromStream (InputStream: TStream; Version: Integer= 1);
  42. procedure LoadFromFile (var InputFile: TextFile; Version: Integer= 1);
  43. procedure SaveToStream (OutputStream: TStream; Version: Integer= 1);
  44. function ToString (WithSpace: Boolean= True): String;
  45. procedure DeleteChar (Index: Integer);
  46. end;
  47. { TWordCollection }
  48. TWordCollection= class (TBaseCollection)
  49. private
  50. function GetWord (Index: Integer): TWord;
  51. public
  52. property Word [Index: Integer]: TWord read GetWord;
  53. procedure AddWord (NewWord: TWord);
  54. procedure DeleteWord (Index: Integer);
  55. procedure Free;
  56. procedure SaveToStream (OutputStream: TStream; Version: Integer);
  57. procedure LoadFromStream (InputStream: TStream; Version: Integer);
  58. procedure LoadFromString (Str: String);
  59. function ToString (WithSpace: Boolean= True): String;
  60. function Copy: TWordCollection;
  61. end;
  62. { TWordColCollection }
  63. TWordColCollection= class (TBaseCollection)
  64. private
  65. function GetWordCollection (Index: Integer): TWordCollection;
  66. public
  67. property WordCollection [Index: Integer]: TWordCollection read GetWordCollection;
  68. procedure AddWordCollection (NewWordCollection: TWordCollection);
  69. procedure DeleteWordCollection (Index: Integer);
  70. procedure Free;
  71. procedure SaveToStream (OutputStream: TStream; Version: Integer);
  72. procedure LoadFromStream (InputStream: TStream; Version: Integer);
  73. function ToString (WithSpace: Boolean= True): String;
  74. end;
  75. { TQueryWord }
  76. TQueryWord= class (TWordCollection)
  77. private
  78. FCharCount: Integer;
  79. FPosition: Integer;
  80. FWordIndex: Integer;
  81. function GetChar(Index: Integer): TChar;
  82. function GetEoW: Boolean;
  83. function GetLastWord: TWord;
  84. public
  85. property EOW: Boolean read GetEoW;
  86. property CharAt [Index: Integer]: TChar read GetChar;
  87. property CharCount: Integer read FCharCount;
  88. property LastWord: TWord read GetLastWord;
  89. constructor Create;
  90. procedure Clear;
  91. function GetNextChar: TChar;
  92. function Copy: TQueryWord;
  93. procedure DeleteLastChar;
  94. function StartWith (Str: String): Boolean;
  95. function EndWith (Str: String): Boolean;
  96. procedure AddWord (NewWord: TWord);
  97. end;
  98. { TWordMeaning }
  99. TWordMeaning= class (TObject)
  100. private
  101. FMeanings: TWordColCollection;
  102. FMeaninigPosOnFile: Int64;
  103. FRefrenceCounter: Int64;
  104. FWord: TWordCollection;
  105. FWordPosOnFile: Int64;
  106. function GetMeaning (Index: Integer): TWordCollection;
  107. public
  108. property Word: TWordCollection read FWord;
  109. property Meaning [Index: Integer]: TWordCollection read GetMeaning;
  110. property WordPosOnFile: Int64 read FWordPosOnFile;
  111. property MeaninigPosOnFile: Int64 read FMeaninigPosOnFile;
  112. property RefrenceCounter: Int64 read FRefrenceCounter;
  113. constructor Create;
  114. procedure Free;
  115. procedure SetWordMeaning (NewWord: TWordCollection; NewMean: TWordColCollection);
  116. procedure LoadFromString (InputString: String);
  117. procedure LoadFromStringNew (InputString: String);
  118. procedure LoadFromFile (var InputFile: TextFile; Version: Integer);
  119. procedure SaveToTextStream (var OutputStream: TStream; Version: Integer);
  120. procedure SaveToStream (OutputStream: TStream; Version: Integer);
  121. procedure LoadFromStream (InputStream: TStream; Version: Integer);
  122. function ToString (WithSpace: Boolean= True): String;
  123. end;
  124. TWMIndex= class;
  125. { TWordMeaningCollection }
  126. TWordMeaningCollection= class (TBaseCollection)
  127. private
  128. function GetWordMeaning(Index: Integer): TWordMeaning;
  129. public
  130. property WordMeaning [Index: Integer]: TWordMeaning read GetWordMeaning;
  131. procedure Free;
  132. procedure AddWordMeaning (NewWordMeaning: TWordMeaning);
  133. procedure DeleteWordMeaning (Index: Integer);
  134. procedure SaveToStream (OutputStream: TStream; Version: Integer);
  135. procedure LoadFromStream (InputStram: TStream);
  136. procedure SaveToFile (FileName: String; Version: Integer= 1);
  137. procedure LoadFromFile (FileName: String);
  138. function GenerateIndexFile: TwMIndex;
  139. function ToString (WithSpace: Boolean= True): String;
  140. end;
  141. TWMIndexCollection= class;
  142. TFileManager= class;
  143. { TWMIndex }
  144. TWMIndex = class (TObject)
  145. private
  146. FHaveWord: Boolean;
  147. FChilds: TWMIndexCollection;
  148. FMeaninigPosOnFile: Int64;
  149. function GetChilds (Index: String): TWMIndex;
  150. procedure SaveToStream (OutputStream: TStream; Version: Integer);
  151. public
  152. property HaveWord: Boolean read FHaveWord;
  153. property Childs [Index: String]: TWMIndex read GetChilds;
  154. property MeaninigPosOnFile: Int64 read FMeaninigPosOnFile;
  155. constructor Create;
  156. procedure Free;
  157. procedure AddChild (Word: TWordCollection;
  158. Meanings: TWordColCollection; MeaninigPos: Int64);
  159. function FindMeaning (Word: TQueryWord; FileManager: TFileManager):
  160. TWordColCollection;
  161. function FindMeaningWithSpellChecking (Word: TQueryWord;
  162. FileManager: TFileManager): TWordMeaningCollection;
  163. procedure LoadFromFile (FileName: String);
  164. procedure SaveToFile (FileName: String; Version: Integer);
  165. procedure LoadFromStream (InputStream: TStream; Version: Integer);
  166. function ToString (Space: String= ''): String;
  167. end;
  168. { TWMIndexCollection }
  169. TWMIndexCollection= class (TNameValueCollection)
  170. private
  171. function GetWMIndex (Index: String; CreateIt: Boolean= False): TWMIndex;
  172. public
  173. property WMIndex [Index: String]: TWMIndex read GetWMIndex;
  174. constructor Create;
  175. procedure Free;
  176. procedure AddWMIndex (NewWMIndex: TWMIndex; Key: String);
  177. procedure SaveToStream (OutputStream: TStream; Version: Integer);
  178. procedure LoadFromStream (InputStream: TStream; Version: Integer);
  179. end;
  180. { TFileReader }
  181. TFileReader= class (TObject)
  182. private
  183. FInput: TFileStream;
  184. public
  185. constructor Create (FileName: String);
  186. procedure Free;
  187. function ReadMeaning (Position: Int64; Version: Integer): TWordColCollection;
  188. end;
  189. { TFileReaderCollection }
  190. TFileReaderCollection= class (TBaseCollection)
  191. private
  192. function GetFileReader(Index: Integer): TFileReader;
  193. public
  194. property FileReader [Index: Integer]: TFileReader read GetFileReader;
  195. constructor Create;
  196. procedure Free;
  197. procedure AddFileReader (NewFileReader: TFileReader);
  198. end;
  199. { TFileManager }
  200. TFileManager= class (TObject)
  201. private
  202. FFileReaderCollection: TFileReaderCollection;
  203. LastIndex: Integer;
  204. public
  205. constructor Create (MaxFileRead: Integer; FileName: String);
  206. procedure Free;
  207. function GetMeaninig (MeaninigPos: Int64): TWordColCollection;
  208. end;
  209. const
  210. CharCount: array [weStart..weEnd] of Integer= (0, 32, 26, 0);
  211. PersianAlphabet: array [0..43] of String= ('?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?',
  212. '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?',
  213. '?', '?', '?', '?', '?', #217#137, #217#146, '?', #226#128#140 {Zero width disjoiner});
  214. PersianIndex: array [0..43] of Integer= (0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
  215. 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 24, 25, 26, 27, 28, 29, 30, 31, 31, 31,
  216. 29, 0, 31, 3, 31, 2, -1, -2);
  217. EnglishAlphabet: array [0..25] of String= ('A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K',
  218. 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z');
  219. EnglishIndex: array [0..25] of Integer= (0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
  220. 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25);
  221. IgnoredCharacters: array [0..28] of String= ('?', '(', ')', '-', '_', '.', '?', #13,
  222. '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', #194#171, #194#187,
  223. '?', '!', '?', '?', ':', '?', #217#143{o}, '=', #61
  224. );
  225. SpaceCharSet: array [0..5] of String= (' ', #9, '[', ']', '(', ')');
  226. ReturnCharSet: array [0..0] of String= (#10);
  227. procedure WriteToStream (AStream: TStream; Str: String);
  228. implementation
  229. uses
  230. ExceptionUnit;
  231. procedure WriteToStream (AStream: TStream; Str: String);
  232. var
  233. i: Integer;
  234. begin
  235. for i:= 1 to Length (Str) do
  236. AStream.WriteByte (Ord (Str [i]));
  237. end;
  238. function ReadFromStream (AStream: TStream): String;
  239. var
  240. b: Byte;
  241. begin
  242. Result:= '';
  243. b:= AStream.ReadByte;
  244. while b<> 10 do
  245. begin
  246. Result:= Result+ Char (b);
  247. b:= AStream.ReadByte;
  248. end;
  249. end;
  250. { TWord }
  251. function TWord.GetChars (Index: Integer): TChar;
  252. begin
  253. if (Index< 0) or (Length<= Index) then
  254. raise ERangeCheckError.Create ('GetChars');
  255. Result:= FChars [Index];
  256. end;
  257. function TWord.GetLength: Integer;
  258. begin
  259. Result:= System.Length (FChars);
  260. end;
  261. function TWord.ReadNextCharFromStream (InputStream: TStream): String;
  262. var
  263. Str: String;
  264. b: Byte;
  265. i: Integer;
  266. function IsSpace (Str: String): Boolean;
  267. var
  268. i: Integer;
  269. begin
  270. Result:= True;
  271. for i:= 0 to High (SpaceCharSet) do
  272. if SpaceCharSet [i]= Str then
  273. Exit;
  274. if Str= ',' then
  275. raise EEndOfMeaningOccured.Create (',');
  276. if Str= #216#140 then
  277. raise EEndOfMeaningOccured.Create (',');
  278. Result:= False;
  279. end;
  280. function IsIgnored (Str: String): Boolean;
  281. var
  282. i: Integer;
  283. begin
  284. Result:= True;
  285. for i:= 0 to High (IgnoredCharacters) do
  286. if IgnoredCharacters [i]= Str then
  287. Exit;
  288. Result:= False;
  289. end;
  290. var
  291. OpenPar: Boolean;
  292. begin
  293. OpenPar:= False;
  294. if InputStream.Position< InputStream.Size then
  295. begin
  296. case FEncoding of
  297. weEnglish:
  298. begin
  299. Result:= '';
  300. while (InputStream.Position< InputStream.Size) and ((Result= '') or (OpenPar)) do
  301. begin
  302. b:= InputStream.ReadByte;
  303. Str:= Chr (b);
  304. if IsSpace (Str) then
  305. begin
  306. Result:= Result+ Chr (b);
  307. continue;
  308. end;
  309. if IsIgnored (Str) then
  310. Continue;
  311. Result:= Result+ Chr (b);
  312. if b= Ord ('(') then
  313. OpenPar:= True
  314. else if (b= Ord (')')) then
  315. begin
  316. if OpenPar then
  317. Exit
  318. else
  319. raise EAnInvalidCharEncountered.Create ('()');
  320. end;
  321. end;
  322. end;
  323. wePersian:
  324. begin
  325. Result:= '';
  326. while (InputStream.Position< InputStream.Size) and
  327. ((Result= '') or (OpenPar)) do
  328. begin
  329. b:= InputStream.ReadByte;
  330. Str:= Chr (b);
  331. if IsSpace (Str) then
  332. begin
  333. Result:= Result+ ' ';
  334. Continue;
  335. end;
  336. if IsIgnored (Str) then
  337. Continue;
  338. if Chr (b) in ['(', ')', '.', 'A'..'Z', 'a'..'z', '<', '>'] then
  339. begin
  340. Result:= Result+ Chr (b);
  341. if b= Ord ('(') then
  342. OpenPar:= True
  343. else if (b= Ord (')')) then
  344. begin
  345. if OpenPar then
  346. Exit
  347. else
  348. raise EAnInvalidCharEncountered.Create ('()');
  349. end;
  350. Str:= '';
  351. Continue;
  352. end;
  353. Str:= Str+ Chr (InputStream.ReadByte);
  354. if IsSpace (Str) then
  355. begin
  356. Result:= Result+ ' ';
  357. Continue;
  358. end;
  359. if IsIgnored (Str) then
  360. Continue;
  361. for i:= 0 to High (PersianAlphabet) do
  362. if PersianAlphabet [i]= Str then
  363. begin
  364. Result:= Result+ Str;
  365. Str:= '';
  366. Break;
  367. end;
  368. if Str= '' then// It is persian char
  369. Continue;
  370. Str:= Str+ Chr (InputStream.ReadByte);
  371. for i:= 0 to High (PersianAlphabet) do
  372. if PersianAlphabet [i]= Str then
  373. begin
  374. Result:= Result+ Str;
  375. Str:= '';
  376. Break;
  377. end;
  378. if Str= '' then// It is persian char
  379. Continue;
  380. if IsIgnored (Str) then
  381. Continue;
  382. if IsSpace (Str) then
  383. begin
  384. Result:= Result+ ' ';
  385. Continue;
  386. end;
  387. raise EAnInvalidCharEncountered.Create (Str);
  388. end;
  389. end;
  390. end;
  391. end
  392. else
  393. Result:= 'EOF';
  394. end;
  395. procedure TWord.AddChar (NewChar: TChar);
  396. begin
  397. SetLength (FChars, Length+ 1);
  398. FChars [Length- 1]:= NewChar;
  399. end;
  400. function TWord.StartWith (Str: String): Boolean;
  401. var
  402. i, l, StrLen: Integer;
  403. CharString: String;
  404. begin
  405. StrLen:= System.Length (Str);
  406. Result:= False;
  407. for i:= 0 to Length- 1 do
  408. begin
  409. CharString:= Chars [i];
  410. l:= System.Length (CharString);
  411. if System.Copy (Str, 1, l)<> CharString then
  412. Exit;
  413. Delete (Str, 1, l);
  414. Dec (StrLen, l);
  415. if StrLen= 0 then
  416. begin
  417. Result:= True;
  418. Exit;
  419. end;
  420. end;
  421. end;
  422. function TWord.EndWith(Str: String): Boolean;
  423. var
  424. i, l, StrLen: Integer;
  425. CharString: String;
  426. begin
  427. StrLen:= System.Length (Str);
  428. Result:= False;
  429. for i:= Length- 1 downto 0 do
  430. begin
  431. CharString:= Chars [i];
  432. l:= System.Length (CharString);
  433. if System.Copy (Str, StrLen- l+ 1, l)<> CharString then
  434. Exit;
  435. Delete (Str, StrLen- l+ 1, l);
  436. Dec (StrLen, l);
  437. if StrLen= 0 then
  438. begin
  439. Result:= True;
  440. Exit;
  441. end;
  442. end;
  443. end;
  444. function TWord.Copy: TWord;
  445. var
  446. i: Integer;
  447. begin
  448. Result:= TWord.Create (FEncoding);
  449. for i:= 0 to Length- 1 do
  450. Result.AddChar (Chars [i]);
  451. end;
  452. {
  453. constructor TWord.Create;
  454. begin
  455. inherited;
  456. SetLength (FChars, 0);
  457. FEncoding:= weStart;
  458. end;
  459. }
  460. constructor TWord.Create (WordEncoding: TWordEncoding);
  461. begin
  462. inherited Create;
  463. FEncoding:= WordEncoding;
  464. SetLength (FChars, 0);
  465. end;
  466. procedure TWord.Free;
  467. begin
  468. SetLength (FChars, 0);
  469. inherited;
  470. end;
  471. procedure TWord.LoadFromString (InputString: String);
  472. var
  473. InputStream: TStringStream;
  474. begin
  475. InputStream:= TStringStream.Create (InputString);
  476. LoadFromStream (InputStream, 0);
  477. InputStream.Free;
  478. end;
  479. procedure TWord.LoadFromStream (InputStream: TStream; Version: Integer);
  480. var
  481. c: Char;
  482. Ch: String;
  483. Len: Integer;
  484. begin
  485. case Version of
  486. 0:
  487. try
  488. Ch:= ReadNextCharFromStream (InputStream);
  489. while (Ch<> ' ') and (Ch<> 'EOF') do
  490. begin
  491. Self.AddChar (Ch);
  492. Ch:= ReadNextCharFromStream (InputStream);
  493. end;
  494. except
  495. on e: EAnInvalidCharEncountered do
  496. WriteLn (e.Message);
  497. end;
  498. 1:
  499. try
  500. Len:= InputStream.ReadByte;
  501. while Len> 0 do
  502. begin
  503. Ch:= '';
  504. c:= Char (InputStream.ReadByte);
  505. while c<> #0 do
  506. begin
  507. Ch:= Ch+ c;
  508. c:= Char (InputStream.ReadByte);
  509. end;
  510. Self.AddChar (Ch);
  511. Dec (Len);
  512. end;
  513. except
  514. on e: EAnInvalidCharEncountered do
  515. WriteLn (e.Message);
  516. end
  517. else
  518. raise EInvalidVersion.Create ('TWord', 'SaveToFile');
  519. end;
  520. end;
  521. procedure TWord.LoadFromFile (var InputFile: TextFile; Version: Integer);
  522. begin
  523. case Version of
  524. 1:
  525. raise ENotImplementedYet.Create ('TWord', 'LoadFromFile');
  526. else
  527. raise EInvalidVersion.Create ('TWord', 'LoadFromFile');
  528. end;
  529. end;
  530. procedure TWord.SaveToStream (OutputStream: TStream; Version: Integer);
  531. var
  532. i: Integer;
  533. begin
  534. case Version of
  535. 1:
  536. begin
  537. OutputStream.WriteByte (Byte (Length));
  538. for i:= 0 to Length- 1 do
  539. WriteToStream (OutputStream, FChars [i]+#0);
  540. end;
  541. else
  542. raise EInvalidVersion.Create ('TWord', 'SaveToFile');
  543. end;
  544. end;
  545. function TWord.ToString (WithSpace: Boolean= True): String;
  546. var
  547. i: Integer;
  548. begin
  549. if WithSpace then
  550. begin
  551. Result:= '(';//+ IntToStr (Ord (Encoding));
  552. for i:= 0 to Length- 1 do
  553. Result:= Result+ ' '+ FChars [i];
  554. Result:= Result+ ')';
  555. end
  556. else
  557. begin
  558. Result:= '';//+ IntToStr (Ord (Encoding));
  559. for i:= 0 to Length- 1 do
  560. Result:= Result+ FChars [i];
  561. end;
  562. end;
  563. procedure TWord.DeleteChar (Index: Integer);
  564. var
  565. i: Integer;
  566. begin
  567. Chars [Index];
  568. for i:= Index+ 1 to Length- 1 do
  569. FChars [i- 1]:= FChars [i];
  570. SetLength (FChars, Length- 1);
  571. end;
  572. { TWordCollection }
  573. function TWordCollection.GetWord (Index: Integer): TWord;
  574. begin
  575. Result:= Member [Index] as TWord;
  576. end;
  577. procedure TWordCollection.AddWord (NewWord: TWord);
  578. begin
  579. Add (NewWord);
  580. end;
  581. procedure TWordCollection.DeleteWord (Index: Integer);
  582. begin
  583. Word [Index].Free;
  584. DeleteFromCollection (Index);
  585. end;
  586. procedure TWordCollection.Free;
  587. var
  588. i: Integer;
  589. begin
  590. for i:= 0 to Size- 1 do
  591. Word [i].Free;
  592. inherited;
  593. end;
  594. procedure TWordCollection.SaveToStream (OutputStream: TStream; Version: Integer);
  595. procedure SaveToStreamVer1 (OutputStream: TStream);
  596. var
  597. i: Integer;
  598. begin
  599. OutputStream.WriteWord (Size);
  600. for i:= 0 to Size- 1 do
  601. Word [i].SaveToStream (OutputStream, Version);
  602. end;
  603. begin
  604. case Version of
  605. 1:
  606. SaveToStreamVer1 (OutputStream)
  607. else
  608. raise EInvalidVersion.Create ('TWordCollection', 'SaveToStream');
  609. end;
  610. end;
  611. procedure TWordCollection.LoadFromStream (InputStream: TStream; Version: Integer);
  612. procedure LoadFromStreamVer1 (InputputStream: TStream);
  613. var
  614. i: Integer;
  615. NewWord: TWord;
  616. begin
  617. i:= InputStream.ReadWord;
  618. while i<> 0 do
  619. begin
  620. NewWord:= TWord.Create;
  621. NewWord.LoadFromStream (InputStream, Version);
  622. Self.AddWord (NewWord);
  623. Dec (i);
  624. end;
  625. end;
  626. begin
  627. case Version of
  628. 1:
  629. LoadFromStreamVer1 (InputStream)
  630. else
  631. raise EInvalidVersion.Create ('TWordCollection', 'SaveToStream');
  632. end;
  633. end;
  634. procedure TWordCollection.LoadFromString (Str: String);
  635. var
  636. InputStream: TStringStream;
  637. NewWord: TWord;
  638. begin
  639. NewWord:= TWord.Create;
  640. NewWord.LoadFromString (Str);
  641. if NewWord.Length= 0 then
  642. NewWord.Free
  643. else
  644. Self.AddWord (NewWord);
  645. end;
  646. function TWordCollection.ToString (WithSpace: Boolean): String;
  647. var
  648. i: Integer;
  649. begin
  650. if WithSpace then
  651. begin
  652. Result:= '(';
  653. for i:= 0 to Size- 1 do
  654. Result:= Result+ ' '+ Word [i].ToString;
  655. Result:= Result+ ' )';
  656. end
  657. else
  658. begin
  659. Result:= '';
  660. for i:= 0 to Size- 1 do
  661. Result:= Result+ ' '+ Word [i].ToString (False);
  662. end;
  663. end;
  664. function TWordCollection.Copy: TWordCollection;
  665. var
  666. i, j: Integer;
  667. ActiveWord,
  668. NewWord: TWord;
  669. begin
  670. Result:= TWordCollection.Create;
  671. for i:= 0 to Size- 1 do
  672. begin
  673. ActiveWord:= Word [i];
  674. NewWord:= TWord.Create (ActiveWord.Encoding);
  675. for j:= 0 to ActiveWord.Length- 1 do
  676. NewWord.AddChar (ActiveWord.Chars [j]);
  677. Result.AddWord (NewWord);
  678. end;
  679. end;
  680. { TWordMeaning }
  681. function TWordMeaning.GetMeaning (Index: Integer): TWordCollection;
  682. begin
  683. Result:= FMeanings.Member [Index] as TWordCollection;
  684. end;
  685. constructor TWordMeaning.Create;
  686. begin
  687. inherited;
  688. FWord:= TWordCollection.Create;
  689. FMeanings:= TWordColCollection.Create;
  690. FWordPosOnFile:= -1;
  691. FMeaninigPosOnFile:= -1;
  692. FRefrenceCounter:= 0;
  693. end;
  694. procedure TWordMeaning.Free;
  695. begin
  696. FWord.Free;
  697. FMeanings.Free;
  698. inherited;
  699. end;
  700. procedure TWordMeaning.SetWordMeaning (NewWord: TWordCollection;
  701. NewMean: TWordColCollection);
  702. begin
  703. FWord.Free;
  704. FWord:= NewWord;
  705. FMeanings.Free;
  706. FMeanings:= NewMean;
  707. end;
  708. procedure TWordMeaning.LoadFromString (InputString: String);
  709. var
  710. NewWord: TWord;
  711. NewMean: TWordCollection;
  712. EnglishWordString: String;
  713. Index: Integer;
  714. InputStream: TStringStream;
  715. begin
  716. Index:= Length (InputString);
  717. while InputString [Index]<> '|' do
  718. Dec (Index);
  719. Dec (Index);
  720. EnglishWordString:= '';
  721. while InputString [Index]<> '|' do
  722. begin
  723. EnglishWordString:= InputString [Index]+ EnglishWordString;
  724. Dec (Index);
  725. end;
  726. InputStream:= TStringStream.Create (EnglishWordString);
  727. while InputStream.Position< InputStream.Size do
  728. begin
  729. NewWord:= TWord.Create (weEnglish);
  730. NewWord.LoadFromStream (InputStream, 0);
  731. if NewWord.Length> 0 then
  732. FWord.AddWord (NewWord)
  733. else
  734. NewWord.Free;
  735. end;
  736. InputStream.Free;
  737. Delete (InputString, Index, Length (InputString)- Index+ 1);
  738. InputStream:= TStringStream.Create (InputString);
  739. NewMean:= TWordCollection.Create;
  740. while InputStream.Position< InputStream.Size do
  741. begin
  742. try
  743. NewWord:= TWord.Create (wePersian);
  744. NewWord.LoadFromStream (InputStream, 0);
  745. if NewWord.Length> 0 then
  746. NewMean.AddWord (NewWord)
  747. else
  748. NewWord.Free;
  749. except
  750. on e: EEndOfMeaningOccured do
  751. begin
  752. if NewWord.Length<> 0 then
  753. NewMean.AddWord (NewWord)
  754. else
  755. NewWord.Free;
  756. if NewMean.Size<> 0 then
  757. FMeanings.AddWordCollection (NewMean)
  758. else
  759. NewMean.Free;
  760. NewMean:= TWordCollection.Create;
  761. end;
  762. end;
  763. end;
  764. if NewMean.Size<> 0 then
  765. FMeanings.AddWordCollection (NewMean)
  766. else
  767. NewMean.Free;
  768. InputStream.Free;
  769. end;
  770. procedure TWordMeaning.LoadFromStringNew (InputString: String);
  771. var
  772. NewWord: TWord;
  773. NewMean: TWordCollection;
  774. EnglishWordString: String;
  775. IndexPtr: PChar;
  776. Index: Integer;
  777. InputStream: TStringStream;
  778. begin
  779. InputString:= Trim (InputString);
  780. Index:= Length (InputString);
  781. IndexPtr:= @InputString [1];
  782. EnglishWordString:= '';
  783. while IndexPtr^<> ':' do
  784. begin
  785. EnglishWordString:= EnglishWordString+ IndexPtr^;
  786. Inc (IndexPtr);
  787. if IndexPtr^= ' ' then
  788. Break;
  789. end;
  790. while IndexPtr^<> ':' do
  791. Inc (IndexPtr);
  792. if IndexPtr^<> ':' then
  793. raise EAnInvalidCharEncountered.Create (IndexPtr);
  794. Inc (IndexPtr);
  795. if IndexPtr^<> ':' then
  796. raise EAnInvalidCharEncountered.Create (IndexPtr);
  797. Inc (IndexPtr);
  798. InputStream:= TStringStream.Create (EnglishWordString);
  799. while InputStream.Position< InputStream.Size do
  800. begin
  801. NewWord:= TWord.Create (weEnglish);
  802. NewWord.LoadFromStream (InputStream, 0);
  803. if NewWord.Length> 0 then
  804. FWord.AddWord (NewWord)
  805. else
  806. NewWord.Free;
  807. end;
  808. InputStream.Free;
  809. while IndexPtr^= ' ' do
  810. Inc (IndexPtr);
  811. InputStream:= TStringStream.Create (IndexPtr);
  812. NewMean:= TWordCollection.Create;
  813. while InputStream.Position< InputStream.Size do
  814. begin
  815. try
  816. NewWord:= TWord.Create (wePersian);
  817. NewWord.LoadFromStream (InputStream, 0);
  818. if NewWord.Length> 0 then
  819. NewMean.AddWord (NewWord)
  820. else
  821. NewWord.Free;
  822. except
  823. on e: EEndOfMeaningOccured do
  824. begin
  825. if NewWord.Length<> 0 then
  826. NewMean.AddWord (NewWord)
  827. else
  828. NewWord.Free;
  829. if NewMean.Size<> 0 then
  830. FMeanings.AddWordCollection (NewMean)
  831. else
  832. NewMean.Free;
  833. NewMean:= TWordCollection.Create;
  834. end;
  835. end;
  836. end;
  837. if NewMean.Size<> 0 then
  838. FMeanings.AddWordCollection (NewMean)
  839. else
  840. NewMean.Free;
  841. InputStream.Free;
  842. end;
  843. procedure TWordMeaning.LoadFromFile (var InputFile: TextFile; Version: Integer);
  844. begin
  845. end;
  846. procedure TWordMeaning.SaveToTextStream(var OutputStream: TStream;
  847. Version: Integer);
  848. begin
  849. end;
  850. procedure TWordMeaning.SaveToStream (OutputStream: TStream; Version: Integer);
  851. procedure SaveToStreamVer1;
  852. begin
  853. FWordPosOnFile:= OutputStream.Position;
  854. FWord.SaveToStream (OutputStream, Version);
  855. FMeaninigPosOnFile:= OutputStream.Position;
  856. FMeanings.SaveToStream (OutputStream, Version);
  857. OutputStream.WriteByte (0);
  858. end;
  859. procedure SaveToStreamVer2;
  860. begin
  861. FWordPosOnFile:= OutputStream.Position;
  862. FWord.SaveToStream (OutputStream, 1);
  863. FMeaninigPosOnFile:= OutputStream.Position;
  864. FMeanings.SaveToStream (OutputStream, 1);
  865. OutputStream.WriteDWord (FRefrenceCounter);
  866. OutputStream.WriteByte (0);
  867. end;
  868. begin
  869. case Version of
  870. 1:
  871. SaveToStreamVer1;
  872. 2:
  873. SaveToStreamVer2
  874. else
  875. raise EInvalidVersion.Create ('TWordMeaning', 'SaveToStream');
  876. end;
  877. end;
  878. procedure TWordMeaning.LoadFromStream (InputStream: TStream; Version: Integer);
  879. procedure LoadFromStreamVer1;
  880. var
  881. i: Integer;
  882. begin
  883. if FWord<> nil then
  884. FWord.Free;
  885. FWord:= TWordCollection.Create;
  886. FWordPosOnFile:= InputStream.Position;
  887. FWord.LoadFromStream (InputStream, Version);
  888. if FMeanings<> nil then
  889. FMeanings.Free;
  890. FMeanings:= TWordColCollection.Create;
  891. FMeaninigPosOnFile:= InputStream.Position;
  892. FMeanings.LoadFromStream (InputStream, Version);
  893. if InputStream.ReadByte<> 0 then
  894. raise EInvalidFile.Create ('Invalid WordMeaning');
  895. end;
  896. procedure LoadFromStreamVer2;
  897. var
  898. i: Integer;
  899. begin
  900. if FWord<> nil then
  901. FWord.Free;
  902. FWord:= TWordCollection.Create;
  903. FWordPosOnFile:= InputStream.Position;
  904. FWord.LoadFromStream (InputStream, 1);
  905. if FMeanings<> nil then
  906. FMeanings.Free;
  907. FMeanings:= TWordColCollection.Create;
  908. FMeaninigPosOnFile:= InputStream.Position;
  909. FMeanings.LoadFromStream (InputStream, 1);
  910. FRefrenceCounter:= InputStream.ReadDWord;
  911. if InputStream.ReadByte<> 0 then
  912. raise EInvalidFile.Create ('Invalid WordMeaning');
  913. end;
  914. begin
  915. case Version of
  916. 1:
  917. LoadFromStreamVer1;
  918. 2:
  919. LoadFromStreamVer2;
  920. else
  921. raise EInvalidVersion.Create ('TWordMeaning', 'LoadFromStream');
  922. end;
  923. end;
  924. function TWordMeaning.ToString (WithSpace: Boolean): String;
  925. begin
  926. if WithSpace then
  927. Result:= '('+ Word.ToString+ ':'#10+ FMeanings.ToString+ ')'
  928. else
  929. Result:= Word.ToString (False)+ ':'+ FMeanings.ToString (False);
  930. end;
  931. { TWordColCollection }
  932. function TWordColCollection.GetWordCollection (Index: Integer): TWordCollection;
  933. begin
  934. Result:= Member [Index] as TWordCollection;
  935. end;
  936. procedure TWordColCollection.AddWordCollection (NewWordCollection: TWordCollection);
  937. begin
  938. Add (NewWordCollection);
  939. end;
  940. procedure TWordColCollection.DeleteWordCollection (Index: Integer);
  941. begin
  942. WordCollection [Index].Free;
  943. DeleteWordCollection (Index);
  944. end;
  945. procedure TWordColCollection.Free;
  946. var
  947. i: Integer;
  948. begin
  949. for i:= 0 to Size- 1 do
  950. WordCollection [i].Free;
  951. inherited;
  952. end;
  953. procedure TWordColCollection.SaveToStream (OutputStream: TStream;
  954. Version: Integer);
  955. procedure SaveToStreamVer1;
  956. var
  957. i: Integer;
  958. begin
  959. OutputStream.WriteByte (Size);
  960. for i:= 0 to Size- 1 do
  961. WordCollection [i].SaveToStream (OutputStream, Version);
  962. end;
  963. begin
  964. case Version of
  965. 1:
  966. SaveToStreamVer1
  967. else
  968. raise EInvalidVersion.Create ('TWordColleciton', 'SaveToFile');
  969. end;
  970. end;
  971. procedure TWordColCollection.LoadFromStream (InputStream: TStream;
  972. Version: Integer);
  973. procedure LoadFromStreamVer1;
  974. var
  975. i: Integer;
  976. NewWordCollection: TWordCollection;
  977. begin
  978. i:= InputStream.ReadByte;
  979. while i<> 0 do
  980. begin
  981. NewWordCollection:= TWordCollection.Create;
  982. NewWordCollection.LoadFromStream (InputStream, Version);
  983. Self.AddWordCollection (NewWordCollection);
  984. Dec (i);
  985. end;
  986. end;
  987. begin
  988. case Version of
  989. 1:
  990. LoadFromStreamVer1;
  991. else
  992. raise EInvalidVersion.Create ('TWordColleciton', 'SaveToFile');
  993. end;
  994. end;
  995. function TWordColCollection.ToString (WithSpace: Boolean= True): String;
  996. var
  997. i: Integer;
  998. begin
  999. if WithSpace then
  1000. begin
  1001. Result:= '(';
  1002. for i:= 0 to Size- 1 do
  1003. Result:= Result+ ' '+ WordCollection [i].ToString+ #10;
  1004. Result:= Result+ ')'#10;
  1005. end
  1006. else
  1007. begin
  1008. Result:= '';
  1009. for i:= 0 to Size- 2 do
  1010. Result:= Result+ WordCollection [i].ToString (False)+ ',';
  1011. if Size<> 0 then
  1012. Result:= Result+ WordCollection [Size- 1].ToString (False);
  1013. end;
  1014. end;
  1015. { TWordMeaningCollection }
  1016. function TWordMeaningCollection.GetWordMeaning (Index: Integer): TWordMeaning;
  1017. begin
  1018. Result:= Member [Index] as TWordMeaning;
  1019. end;
  1020. procedure TWordMeaningCollection.Free;
  1021. var
  1022. i: Integer;
  1023. begin
  1024. for i:= 0 to Size- 1 do
  1025. WordMeaning [i].Free;
  1026. inherited;
  1027. end;
  1028. procedure TWordMeaningCollection.AddWordMeaning (NewWordMeaning: TWordMeaning);
  1029. begin
  1030. Add (NewWordMeaning);
  1031. end;
  1032. procedure TWordMeaningCollection.DeleteWordMeaning (Index: Integer);
  1033. begin
  1034. WordMeaning [Index].Free;
  1035. DeleteFromCollection (Index);
  1036. end;
  1037. procedure TWordMeaningCollection.SaveToStream (OutputStream: TStream; Version: Integer= 1);
  1038. var
  1039. i: Integer;
  1040. procedure SaveHeader (OutputStram: TStream; Version: Integer);
  1041. var
  1042. S: String;
  1043. begin
  1044. WriteToStream (OutputStram, 'Version: '+ IntToStr (Version)+ #10);
  1045. WriteToStream (OutputStram, 'Dictionary File'#10);
  1046. WriteToStream (OutputStram, 'Developed by Amir Aavani'#10);
  1047. end;
  1048. begin
  1049. SaveHeader (OutputStream, Version);
  1050. OutputStream.WriteWord (Size);
  1051. for i:= 0 to Size- 1 do
  1052. WordMeaning [i].SaveToStream (OutputStream, Version);
  1053. end;
  1054. procedure TWordMeaningCollection.LoadFromStream (InputStram: TStream);
  1055. function ReadHeader (InputStram: TStream): Integer;
  1056. var
  1057. S: String;
  1058. begin
  1059. S:= ReadFromStream (InputStram);
  1060. if Copy (S, 1, Length ('Version: '))<> 'Version: ' then
  1061. raise EInvalidFile ('invalid Header!');
  1062. Delete (S, 1, Length ('Version: '));
  1063. Result:= StrToInt (S);
  1064. if ReadFromStream (InputStram)<> 'Dictionary File' then
  1065. raise EInvalidFile.Create ('Invalid Header');
  1066. if ReadFromStream (InputStram)<> 'Developed by Amir Aavani' then
  1067. raise EInvalidFile.Create ('Invalid Header');
  1068. end;
  1069. var
  1070. Version, i: Integer;
  1071. NewWordMeaning: TWordMeaning;
  1072. begin
  1073. Version:= ReadHeader (InputStram);
  1074. i:= InputStram.ReadWord;
  1075. while i<> 0 do
  1076. begin
  1077. NewWordMeaning:= TWordMeaning.Create;
  1078. NewWordMeaning.LoadFromStream (InputStram, Version);
  1079. Self.AddWordMeaning (NewWordMeaning);
  1080. Dec (i);
  1081. end;
  1082. end;
  1083. procedure TWordMeaningCollection.SaveToFile (FileName: String; Version: Integer= 1);
  1084. var
  1085. OutputStream: TFileStream;
  1086. begin
  1087. OutputStream:= TFileStream.Create (FileName, fmCreate);
  1088. SaveToStream (OutputStream, Version);
  1089. OutputStream.Free;
  1090. end;
  1091. procedure TWordMeaningCollection.LoadFromFile (FileName: String);
  1092. var
  1093. InputStream: TFileStream;
  1094. begin
  1095. InputStream:= TFileStream.Create (FileName, fmOpenRead);
  1096. LoadFromStream (InputStream);
  1097. if InputStream.Position<> InputStream.Size then
  1098. raise EInvalidFile.Create ('EoF!');
  1099. InputStream.Free;
  1100. end;
  1101. function TWordMeaningCollection.GenerateIndexFile: TWMIndex;
  1102. var
  1103. i: Integer;
  1104. Index: TwmIndex;
  1105. ActiveWordMeaning: TWordMeaning;
  1106. begin
  1107. WriteLn (Size);
  1108. if Size> 0 then
  1109. if WordMeaning [0].WordPosOnFile= -1 then
  1110. raise EWMCIndexCollectionCannotBeMade.Create
  1111. ('Word Meaning Collection Must be loaded from file!');
  1112. Result:= TWMIndex.Create;
  1113. for i:= 0 to Size- 1 do
  1114. begin
  1115. ActiveWordMeaning:= WordMeaning [i];
  1116. Result.AddChild (ActiveWordMeaning.Word,
  1117. ActiveWordMeaning.FMeanings,
  1118. ActiveWordMeaning.MeaninigPosOnFile
  1119. );
  1120. end;
  1121. end;
  1122. function TWordMeaningCollection.ToString (WithSpace: Boolean): String;
  1123. var
  1124. i: Integer;
  1125. begin
  1126. if WithSpace then
  1127. begin
  1128. Result:= '(';
  1129. for i:= 0 to Size- 1 do
  1130. Result:= Result+ ' '+ WordMeaning [i].ToString;
  1131. Result:= Result+ ')';
  1132. end
  1133. else
  1134. begin
  1135. Result:= '';
  1136. for i:= 0 to Size- 1 do
  1137. Result:= Result+ ' '+ WordMeaning [i].ToString (False);
  1138. end;
  1139. end;
  1140. { TWMIndex }
  1141. function TWMIndex.GetChilds (Index: String): TWMIndex;
  1142. begin
  1143. Result:= FChilds.WMIndex [Index];
  1144. end;
  1145. constructor TWMIndex.Create;
  1146. begin
  1147. inherited;
  1148. FChilds:= TWMIndexCollection.Create;
  1149. FMeaninigPosOnFile:= 0;
  1150. FHaveWord:= False;
  1151. end;
  1152. procedure TWMIndex.Free;
  1153. var
  1154. i: Integer;
  1155. begin
  1156. FChilds.Free;
  1157. inherited;
  1158. end;
  1159. procedure TWMIndex.AddChild (Word: TWordCollection;
  1160. Meanings: TWordColCollection; MeaninigPos: Int64);
  1161. var
  1162. NewWMIndex: TWMIndex;
  1163. NewWord: TWordCollection;
  1164. begin
  1165. if Word.Size= 0 then
  1166. begin
  1167. FHaveWord:= True;
  1168. FMeaninigPosOnFile:= MeaninigPos;
  1169. end
  1170. else
  1171. begin
  1172. NewWMIndex:= FChilds.GetWMIndex (Word.Word [0].Chars [0], True);
  1173. NewWord:= Word.Copy;
  1174. NewWord.Word [0].DeleteChar (0);
  1175. if NewWord.Word [0].Length= 0 then
  1176. NewWord.DeleteWord (0);
  1177. NewWMIndex.AddChild (NewWord, Meanings, MeaninigPos);
  1178. NewWord.Free;
  1179. end;
  1180. end;
  1181. function TWMIndex.FindMeaning (Word: TQueryWord; FileManager: TFileManager):
  1182. TWordColCollection;
  1183. var
  1184. FirstChar: TChar;
  1185. NextChild: TWMIndex;
  1186. begin
  1187. if Word.EOW then
  1188. begin
  1189. if MeaninigPosOnFile<> 0 then
  1190. Result:= FileManager.GetMeaninig (FMeaninigPosOnFile)
  1191. else
  1192. Result:= nil;
  1193. end
  1194. else
  1195. begin
  1196. FirstChar:= Word.GetNextChar;
  1197. NextChild:= FChilds.GetWMIndex (FirstChar, False);
  1198. if NextChild= nil then
  1199. begin
  1200. Result:= nil
  1201. end
  1202. else
  1203. Result:= NextChild.FindMeaning (Word, FileManager);
  1204. end;
  1205. end;
  1206. function TWMIndex.FindMeaningWithSpellChecking (Word: TQueryWord;
  1207. FileManager: TFileManager): TWordMeaningCollection;
  1208. const
  1209. MaxEndWithString= 5;
  1210. EndWithString: array [0..MaxEndWithString] of String=
  1211. ('s', 'es', 'd', 'ed', 'ing', 'ing' );
  1212. ReplaceEndWithString: array [0..MaxEndWithString] of String=
  1213. ('', '', '', '', 'e', '');
  1214. var
  1215. WordMeaning: TWordMeaning;
  1216. Meaning: TWordColCollection;
  1217. NewWord: TQueryWord;
  1218. i, j: Integer;
  1219. begin
  1220. Result:= TWordMeaningCollection.Create;
  1221. Meaning:= FindMeaning (Word, FileManager);
  1222. if Meaning<> nil then
  1223. begin
  1224. WordMeaning:= TWordMeaning.Create;
  1225. WordMeaning.SetWordMeaning (Word, Meaning);
  1226. Result.AddWordMeaning (WordMeaning);
  1227. end
  1228. else
  1229. begin
  1230. NewWord:= nil;
  1231. for i:= 0 to MaxEndWithString do
  1232. begin
  1233. if Word.EndWith (EndWithString [i]) then
  1234. begin
  1235. NewWord:= Word.Copy;
  1236. for j:= 1 to Length (EndWithString [i]) do
  1237. NewWord.DeleteLastChar;
  1238. if ReplaceEndWithString [i]<> '' then
  1239. for j:= 1 to Length (ReplaceEndWithString [i]) do
  1240. NewWord.LastWord.AddChar (ReplaceEndWithString [i][j]);
  1241. Meaning:= FindMeaning (NewWord, FileManager);
  1242. if Meaning<> nil then
  1243. begin
  1244. WordMeaning:= TWordMeaning.Create;
  1245. WordMeaning.SetWordMeaning (NewWord, Meaning);
  1246. Result.AddWordMeaning (WordMeaning);
  1247. end
  1248. else
  1249. begin
  1250. NewWord.Free;
  1251. end;
  1252. end;
  1253. end;
  1254. end;
  1255. end;
  1256. procedure TWMIndex.LoadFromFile (FileName: String);
  1257. var
  1258. InputStream: TFileStream;
  1259. function ReadHeader (InputStream: TStream): Integer;
  1260. var
  1261. S: String;
  1262. begin
  1263. S:= ReadFromStream (InputStream);
  1264. if Copy (S, 1, Length ('Version: '))<> 'Version: ' then
  1265. raise EInvalidFile ('invalid Header!');
  1266. Delete (S, 1, Length ('Version: '));
  1267. Result:= StrToInt (S);
  1268. case Result of
  1269. 1:
  1270. begin
  1271. S:= ReadFromStream (InputStream);
  1272. if UpperCase (S)<> 'DICTIONARY INDEX FILE' then
  1273. raise EInvalidFile.Create ('Invalid Header');
  1274. S:= ReadFromStream (InputStream);
  1275. if UpperCase (S)<> 'DEVELOPED BY AMIR AAVANI' then
  1276. raise EInvalidFile.Create ('Invalid Header');
  1277. end
  1278. else
  1279. EInvalidVersion.Create ('TWordMeaningCollection', 'SaveToStream');
  1280. end;
  1281. end;
  1282. var
  1283. Version: Integer;
  1284. begin
  1285. InputStream:= TFileStream.Create (FileName, fmOpenRead);
  1286. Version:= ReadHeader (InputStream);
  1287. LoadFromStream (InputStream, Version);
  1288. InputStream.Free;
  1289. end;
  1290. procedure TWMIndex.SaveToFile (FileName: String; Version: Integer);
  1291. var
  1292. OutputStream: TFileStream;
  1293. procedure WriteHeader (OutputStream: TStream; Version: Integer);
  1294. begin
  1295. case Version of
  1296. 1:
  1297. begin
  1298. WriteToStream (OutputStream, 'Version: '+ IntToStr (Version)+ #10);
  1299. WriteToStream (OutputStream, 'Dictionary Index File'#10);
  1300. WriteToStream (OutputStream, 'Developed by Amir Aavani'#10);
  1301. end
  1302. else
  1303. raise EInvalidVersion.Create ('TWMIndex', 'SaveToStream');
  1304. end;
  1305. end;
  1306. begin
  1307. OutputStream:= TFileStream.Create (FileName, fmCreate);
  1308. WriteHeader (OutputStream, Version);
  1309. SaveToStream (OutputStream, Version);
  1310. OutputStream.Free;
  1311. end;
  1312. procedure TWMIndex.LoadFromStream (InputStream: TStream; Version: Integer);
  1313. var
  1314. i: Integer;
  1315. ActiveNameValue: TNameValue;
  1316. begin
  1317. FHaveWord:= InputStream.ReadByte= $FF;
  1318. FMeaninigPosOnFile:= InputStream.ReadDWord;
  1319. FChilds.Free;
  1320. FChilds:= TWMIndexCollection.Create;
  1321. FChilds.LoadFromStream (InputStream, Version);
  1322. end;
  1323. function TWMIndex.ToString (Space: String): String;
  1324. var
  1325. i: Integer;
  1326. begin
  1327. if HaveWord then
  1328. Result:= Space+ '(+'+ IntToStr (FMeaninigPosOnFile)
  1329. else
  1330. Result:= Space+ '(-'+ IntToStr (FMeaninigPosOnFile);
  1331. for i:= 0 to FChilds.Size- 1 do
  1332. Result:= Result+ #10+ '('+ FChilds.NameValue [i].Name+ ':'+
  1333. (FChilds.NameValue [i].Value as TWMIndex).ToString (Space+ ' ')+
  1334. ')';
  1335. Result:= Result+ ')'+ #10;
  1336. end;
  1337. procedure TWMIndex.SaveToStream (OutputStream: TStream; Version: Integer);
  1338. var
  1339. i: Integer;
  1340. ActiveNameValue: TNameValue;
  1341. begin
  1342. if HaveWord then
  1343. OutputStream.WriteByte ($FF)
  1344. else
  1345. OutputStream.WriteByte (0);
  1346. OutputStream.WriteDWord (FMeaninigPosOnFile);
  1347. FChilds.SaveToStream (OutputStream, Version);
  1348. end;
  1349. { TWMIndexCollection }
  1350. function TWMIndexCollection.GetWMIndex (Index: String; CreateIt: Boolean): TWMIndex;
  1351. begin
  1352. try
  1353. Result:= NameValueByName [Index].Value as TWMIndex;
  1354. except
  1355. on e: EVariableNotFound do
  1356. begin
  1357. if CreateIt then
  1358. begin
  1359. Result:= TWMIndex.Create;
  1360. Self.AddWMIndex (Result, Index);
  1361. end
  1362. else
  1363. Result:= nil;
  1364. end;
  1365. end;
  1366. end;
  1367. constructor TWMIndexCollection.Create;
  1368. begin
  1369. inherited;
  1370. end;
  1371. procedure TWMIndexCollection.Free;
  1372. var
  1373. i: Integer;
  1374. begin
  1375. for i:= 0 to Size- 1 do
  1376. begin
  1377. (NameValue [i].Value as TWMIndex).Free;
  1378. NameValue [i].Free;
  1379. end;
  1380. inherited;
  1381. end;
  1382. procedure TWMIndexCollection.AddWMIndex (NewWMIndex: TWMIndex; Key: String);
  1383. begin
  1384. Add (TNameValue.Create (Key, NewWMIndex));
  1385. end;
  1386. procedure TWMIndexCollection.SaveToStream (OutputStream: TStream; Version: Integer);
  1387. var
  1388. i: Integer;
  1389. ActiveNameValue: TNameValue;
  1390. begin
  1391. OutputStream.WriteByte (Size);
  1392. for i:= 0 to Size- 1 do
  1393. begin
  1394. ActiveNameValue:= NameValue [i];
  1395. if Length (ActiveNameValue.Name)= 1 then
  1396. WriteToStream (OutputStream, #0+ ActiveNameValue.Name)
  1397. else if Length (ActiveNameValue.Name)= 2 then
  1398. WriteToStream (OutputStream, ActiveNameValue.Name)
  1399. else
  1400. WriteToStream (OutputStream, ActiveNameValue.Name);
  1401. (ActiveNameValue.Value as TWMIndex).SaveToStream (OutputStream, Version);
  1402. end;
  1403. end;
  1404. procedure TWMIndexCollection.LoadFromStream (InputStream: TStream; Version: Integer);
  1405. var
  1406. i: Integer;
  1407. ActiveNameValue: TNameValue;
  1408. Index: TWMIndex;
  1409. b: Byte;
  1410. Name: String;
  1411. begin
  1412. case Version of
  1413. 1:
  1414. begin
  1415. i:= InputStream.ReadByte;
  1416. while i> 0 do
  1417. begin
  1418. b:= InputStream.ReadByte;
  1419. if b= 0 then
  1420. Name:= Char (InputStream.ReadByte)
  1421. else
  1422. begin
  1423. Name:= Char (b)+ Char (InputStream.ReadByte);
  1424. end;
  1425. Index:= TWMIndex.Create;
  1426. Index.LoadFromStream (InputStream, Version);
  1427. AddWMIndex (Index, Name);
  1428. Dec (i);
  1429. end;
  1430. end
  1431. else
  1432. raise EInvalidVersion.Create ('TWMIndexCollection', 'LoadFromStream');
  1433. end;
  1434. end;
  1435. { TQueryWord }
  1436. function TQueryWord.GetEoW: Boolean;
  1437. begin
  1438. Result:= (Size<= FWordIndex);
  1439. end;
  1440. function TQueryWord.GetLastWord: TWord;
  1441. begin
  1442. Result:= Word [Size- 1];
  1443. end;
  1444. function TQueryWord.GetChar (Index: Integer): TChar;
  1445. var
  1446. i: Integer;
  1447. begin
  1448. Result:= #0;
  1449. for i:= 0 to Size- 1 do
  1450. if Word [i].Length< Index then
  1451. Result:= Word [i].Chars [Index]
  1452. else
  1453. Dec (Index, Word [i].Length);
  1454. end;
  1455. constructor TQueryWord.Create;
  1456. begin
  1457. inherited;
  1458. FPosition:= 0;
  1459. FWordIndex:= 0;
  1460. FCharCount:= 0;
  1461. end;
  1462. procedure TQueryWord.Clear;
  1463. begin
  1464. inherited;
  1465. end;
  1466. function TQueryWord.GetNextChar: TChar;
  1467. begin
  1468. Result:= Word [FWordIndex].Chars [FPosition];
  1469. Inc (FPosition);
  1470. if Word [FWordIndex].Length= FPosition then
  1471. begin
  1472. Inc (FWordIndex);
  1473. FPosition:= 0;
  1474. end;
  1475. end;
  1476. function TQueryWord.Copy: TQueryWord;
  1477. var
  1478. i: Integer;
  1479. begin
  1480. Result:= TQueryWord.Create;
  1481. for i:= 0 to Size- 1 do
  1482. Result.AddWord (Word [i].Copy);
  1483. end;
  1484. procedure TQueryWord.DeleteLastChar;
  1485. var
  1486. Activeword: TWord;
  1487. begin
  1488. if Size<> 0 then
  1489. begin
  1490. Activeword:= Word [Size- 1];
  1491. Activeword.DeleteChar (Activeword.Length- 1);
  1492. if Activeword.Length= 0 then
  1493. begin
  1494. Activeword.Free;
  1495. DeleteWord (Size- 1);
  1496. end;
  1497. end;
  1498. end;
  1499. function TQueryWord.StartWith (Str: String): Boolean;
  1500. begin
  1501. if Size= 0 then
  1502. Result:= False
  1503. else if Word [0].Length< Length (Str) then
  1504. Result:= Word [0].StartWith (Str)
  1505. else
  1506. Result:= False;
  1507. end;
  1508. function TQueryWord.EndWith (Str: String): Boolean;
  1509. begin
  1510. if Size= 0 then
  1511. Result:= False
  1512. else if Length (Str)< Word [Size- 1].Length then
  1513. Result:= Word [Size- 1].EndWith (Str)
  1514. else
  1515. Result:= False;
  1516. end;
  1517. procedure TQueryWord.AddWord(NewWord: TWord);
  1518. begin
  1519. inherited;
  1520. end;
  1521. { TFileReader }
  1522. constructor TFileReader.Create (FileName: String);
  1523. begin
  1524. inherited Create;
  1525. FInput:= TFileStream.Create (FileName, fmOpenRead);
  1526. end;
  1527. procedure TFileReader.Free;
  1528. begin
  1529. FInput.Free;
  1530. inherited;
  1531. end;
  1532. function TFileReader.ReadMeaning (Position: Int64; Version: Integer): TWordColCollection;
  1533. var
  1534. i: Integer;
  1535. begin
  1536. Result:= TWordColCollection.Create;
  1537. FInput.Position:= Position;
  1538. Result.LoadFromStream (FInput, Version);
  1539. end;
  1540. { TFileManager }
  1541. constructor TFileManager.Create (MaxFileRead: Integer; FileName: String);
  1542. var
  1543. i: Integer;
  1544. NewFileReader: TFileReader;
  1545. begin
  1546. inherited Create;
  1547. FFileReaderCollection:= TFileReaderCollection.Create;
  1548. for i:= 0 to MaxFileRead- 1 do
  1549. begin
  1550. NewFileReader:= TFileReader.Create (FileName);
  1551. FFileReaderCollection.AddFileReader (NewFileReader);
  1552. end;
  1553. LastIndex:= 0;
  1554. end;
  1555. procedure TFileManager.Free;
  1556. begin
  1557. FFileReaderCollection.Free;
  1558. inherited;
  1559. end;
  1560. function TFileManager.GetMeaninig (MeaninigPos: Int64): TWordColCollection;
  1561. begin
  1562. LastIndex:= (LastIndex+ 1) mod FFileReaderCollection.Size;
  1563. Result:= FFileReaderCollection.FileReader [LastIndex].ReadMeaning (MeaninigPos, 1);
  1564. end;
  1565. { TFileReaderCollection }
  1566. function TFileReaderCollection.GetFileReader (Index: Integer): TFileReader;
  1567. begin
  1568. Result:= Member [Index] as TFileReader;
  1569. end;
  1570. constructor TFileReaderCollection.Create;
  1571. begin
  1572. inherited;
  1573. end;
  1574. procedure TFileReaderCollection.Free;
  1575. var
  1576. i: Integer;
  1577. begin
  1578. for i:= 0 to Size- 1 do
  1579. FileReader [i].Free;
  1580. inherited;
  1581. end;
  1582. procedure TFileReaderCollection.AddFileReader (NewFileReader: TFileReader);
  1583. begin
  1584. inherited Add (NewFileReader);
  1585. end;
  1586. { EAnInvalidCharEncountered }
  1587. constructor EAnInvalidCharEncountered.Create (Char: String);
  1588. var
  1589. i: Integer;
  1590. Str: String;
  1591. begin
  1592. Str:= 'Invalid Char= ';
  1593. for i:= 1 to Length (Char) do
  1594. Str:= Str+ IntToStr (Ord (Char [i]))+ ' ';
  1595. inherited Create (Str);
  1596. end;
  1597. end.