cclasses.pas 62 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410
  1. {
  2. $Id$
  3. Copyright (c) 1998-2002 by Florian Klaempfl and Peter Vreman
  4. This module provides some basic classes
  5. This program is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 2 of the License, or
  8. (at your option) any later version.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program; if not, write to the Free Software
  15. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  16. ****************************************************************************
  17. }
  18. unit cclasses;
  19. {$i fpcdefs.inc}
  20. interface
  21. uses
  22. cutils,cstreams;
  23. {********************************************
  24. TMemDebug
  25. ********************************************}
  26. type
  27. tmemdebug = class
  28. private
  29. totalmem,
  30. startmem : integer;
  31. infostr : string[40];
  32. public
  33. constructor Create(const s:string);
  34. destructor Destroy;override;
  35. procedure show;
  36. procedure start;
  37. procedure stop;
  38. end;
  39. {*******************************************************
  40. TList (Copied from FCL, exception handling stripped)
  41. ********************************************************}
  42. const
  43. MaxListSize = Maxint div 16;
  44. SListIndexError = 'List index exceeds bounds (%d)';
  45. SListCapacityError = 'The maximum list capacity is reached (%d)';
  46. SListCountError = 'List count too large (%d)';
  47. type
  48. { TList class }
  49. PPointerList = ^TPointerList;
  50. TPointerList = array[0..MaxListSize - 1] of Pointer;
  51. TListSortCompare = function (Item1, Item2: Pointer): Integer;
  52. TList = class(TObject)
  53. private
  54. FList: PPointerList;
  55. FCount: Integer;
  56. FCapacity: Integer;
  57. protected
  58. function Get(Index: Integer): Pointer;
  59. procedure Grow; virtual;
  60. procedure Put(Index: Integer; Item: Pointer);
  61. procedure SetCapacity(NewCapacity: Integer);
  62. procedure SetCount(NewCount: Integer);
  63. public
  64. destructor Destroy; override;
  65. function Add(Item: Pointer): Integer;
  66. procedure Clear; dynamic;
  67. procedure Delete(Index: Integer);
  68. class procedure Error(const Msg: string; Data: Integer); virtual;
  69. procedure Exchange(Index1, Index2: Integer);
  70. function Expand: TList;
  71. function Extract(item: Pointer): Pointer;
  72. function First: Pointer;
  73. procedure Assign(Obj:TList);
  74. function IndexOf(Item: Pointer): Integer;
  75. procedure Insert(Index: Integer; Item: Pointer);
  76. function Last: Pointer;
  77. procedure Move(CurIndex, NewIndex: Integer);
  78. function Remove(Item: Pointer): Integer;
  79. procedure Pack;
  80. procedure Sort(Compare: TListSortCompare);
  81. property Capacity: Integer read FCapacity write SetCapacity;
  82. property Count: Integer read FCount write SetCount;
  83. property Items[Index: Integer]: Pointer read Get write Put; default;
  84. property List: PPointerList read FList;
  85. end;
  86. {********************************************
  87. TLinkedList
  88. ********************************************}
  89. type
  90. TLinkedListItem = class
  91. public
  92. Previous,
  93. Next : TLinkedListItem;
  94. Constructor Create;
  95. Destructor Destroy;override;
  96. Function GetCopy:TLinkedListItem;virtual;
  97. end;
  98. TLinkedListItemClass = class of TLinkedListItem;
  99. TLinkedList = class
  100. private
  101. FCount : integer;
  102. FFirst,
  103. FLast : TLinkedListItem;
  104. FNoClear : boolean;
  105. public
  106. constructor Create;
  107. destructor Destroy;override;
  108. { true when the List is empty }
  109. function Empty:boolean;
  110. { deletes all Items }
  111. procedure Clear;
  112. { inserts an Item }
  113. procedure Insert(Item:TLinkedListItem);
  114. { inserts an Item before Loc }
  115. procedure InsertBefore(Item,Loc : TLinkedListItem);
  116. { inserts an Item after Loc }
  117. procedure InsertAfter(Item,Loc : TLinkedListItem);virtual;
  118. { concats an Item }
  119. procedure Concat(Item:TLinkedListItem);
  120. { deletes an Item }
  121. procedure Remove(Item:TLinkedListItem);
  122. { Gets First Item }
  123. function GetFirst:TLinkedListItem;
  124. { Gets last Item }
  125. function GetLast:TLinkedListItem;
  126. { inserts another List at the begin and make this List empty }
  127. procedure insertList(p : TLinkedList);
  128. { inserts another List after the provided item and make this List empty }
  129. procedure insertListAfter(Item:TLinkedListItem;p : TLinkedList);
  130. { concats another List at the end and make this List empty }
  131. procedure concatList(p : TLinkedList);
  132. { concats another List at the start and makes a copy
  133. the list is ordered in reverse.
  134. }
  135. procedure insertListcopy(p : TLinkedList);
  136. { concats another List at the end and makes a copy }
  137. procedure concatListcopy(p : TLinkedList);
  138. property First:TLinkedListItem read FFirst;
  139. property Last:TLinkedListItem read FLast;
  140. property Count:Integer read FCount;
  141. property NoClear:boolean write FNoClear;
  142. end;
  143. {********************************************
  144. TStringList
  145. ********************************************}
  146. { string containerItem }
  147. TStringListItem = class(TLinkedListItem)
  148. FPStr : PString;
  149. public
  150. constructor Create(const s:string);
  151. destructor Destroy;override;
  152. function GetCopy:TLinkedListItem;override;
  153. function Str:string;
  154. end;
  155. { string container }
  156. TStringList = class(TLinkedList)
  157. private
  158. FDoubles : boolean; { if this is set to true, doubles are allowed }
  159. public
  160. constructor Create;
  161. constructor Create_No_Double;
  162. { inserts an Item }
  163. procedure Insert(const s:string);
  164. { concats an Item }
  165. procedure Concat(const s:string);
  166. { deletes an Item }
  167. procedure Remove(const s:string);
  168. { Gets First Item }
  169. function GetFirst:string;
  170. { Gets last Item }
  171. function GetLast:string;
  172. { true if string is in the container }
  173. function Find(const s:string):TStringListItem;
  174. { inserts an item }
  175. procedure InsertItem(item:TStringListItem);
  176. { concats an item }
  177. procedure ConcatItem(item:TStringListItem);
  178. property Doubles:boolean read FDoubles write FDoubles;
  179. end;
  180. {********************************************
  181. Dictionary
  182. ********************************************}
  183. const
  184. { the real size will be [0..hasharray-1] ! }
  185. hasharraysize = 512;
  186. type
  187. { namedindexobect for use with dictionary and indexarray }
  188. TNamedIndexItem=class
  189. private
  190. { indexarray }
  191. FIndexNr : integer;
  192. FIndexNext : TNamedIndexItem;
  193. { dictionary }
  194. FLeft,
  195. FRight : TNamedIndexItem;
  196. FSpeedValue : cardinal;
  197. { singleList }
  198. FListNext : TNamedIndexItem;
  199. FName : Pstring;
  200. protected
  201. function GetName:string;virtual;
  202. procedure SetName(const n:string);virtual;
  203. public
  204. constructor Create;
  205. constructor CreateName(const n:string);
  206. destructor Destroy;override;
  207. property IndexNr:integer read FIndexNr write FIndexNr;
  208. property IndexNext:TNamedIndexItem read FIndexNext write FIndexNext;
  209. property Name:string read GetName write SetName;
  210. property SpeedValue:cardinal read FSpeedValue;
  211. property ListNext:TNamedIndexItem read FListNext;
  212. property Left:TNamedIndexItem read FLeft write FLeft;
  213. property Right:TNamedIndexItem read FRight write FRight;
  214. end;
  215. Pdictionaryhasharray=^Tdictionaryhasharray;
  216. Tdictionaryhasharray=array[0..hasharraysize-1] of TNamedIndexItem;
  217. TnamedIndexCallback = procedure(p:TNamedIndexItem;arg:pointer) of object;
  218. TnamedIndexStaticCallback = procedure(p:TNamedIndexItem;arg:pointer);
  219. Tdictionary=class
  220. private
  221. FRoot : TNamedIndexItem;
  222. FCount : longint;
  223. FHashArray : Pdictionaryhasharray;
  224. procedure cleartree(var obj:TNamedIndexItem);
  225. function insertNode(NewNode:TNamedIndexItem;var currNode:TNamedIndexItem):TNamedIndexItem;
  226. procedure inserttree(currtree,currroot:TNamedIndexItem);
  227. public
  228. noclear : boolean;
  229. delete_doubles : boolean;
  230. constructor Create;
  231. destructor Destroy;override;
  232. procedure usehash;
  233. procedure clear;
  234. function delete(const s:string):TNamedIndexItem;
  235. function empty:boolean;
  236. procedure foreach(proc2call:TNamedIndexcallback;arg:pointer);
  237. procedure foreach_static(proc2call:TNamedIndexStaticCallback;arg:pointer);
  238. function insert(obj:TNamedIndexItem):TNamedIndexItem;
  239. function replace(oldobj,newobj:TNamedIndexItem):boolean;
  240. function rename(const olds,News : string):TNamedIndexItem;
  241. function search(const s:string):TNamedIndexItem;
  242. function speedsearch(const s:string;SpeedValue:cardinal):TNamedIndexItem;
  243. property Items[const s:string]:TNamedIndexItem read Search;default;
  244. end;
  245. tsingleList=class
  246. First,
  247. last : TNamedIndexItem;
  248. constructor Create;
  249. procedure reset;
  250. procedure clear;
  251. procedure insert(p:TNamedIndexItem);
  252. end;
  253. tindexobjectarray=array[1..16000] of TNamedIndexItem;
  254. pnamedindexobjectarray=^tindexobjectarray;
  255. tindexarray=class
  256. noclear : boolean;
  257. First : TNamedIndexItem;
  258. count : integer;
  259. constructor Create(Agrowsize:integer);
  260. destructor destroy;override;
  261. procedure clear;
  262. procedure foreach(proc2call : Tnamedindexcallback;arg:pointer);
  263. procedure foreach_static(proc2call : Tnamedindexstaticcallback;arg:pointer);
  264. procedure deleteindex(p:TNamedIndexItem);
  265. procedure delete(var p:TNamedIndexItem);
  266. procedure insert(p:TNamedIndexItem);
  267. procedure replace(oldp,newp:TNamedIndexItem);
  268. function search(nr:integer):TNamedIndexItem;
  269. private
  270. growsize,
  271. size : integer;
  272. data : pnamedindexobjectarray;
  273. procedure grow(gsize:integer);
  274. end;
  275. {********************************************
  276. DynamicArray
  277. ********************************************}
  278. const
  279. dynamicblockbasesize = 12;
  280. type
  281. pdynamicblock = ^tdynamicblock;
  282. tdynamicblock = record
  283. pos,
  284. used : integer;
  285. Next : pdynamicblock;
  286. { can't use sizeof(integer) because it crashes gdb }
  287. data : array[0..1024*1024] of byte;
  288. end;
  289. tdynamicarray = class
  290. private
  291. FPosn : integer;
  292. FPosnblock : pdynamicblock;
  293. FBlocksize : integer;
  294. FFirstblock,
  295. FLastblock : pdynamicblock;
  296. procedure grow;
  297. public
  298. constructor Create(Ablocksize:integer);
  299. destructor Destroy;override;
  300. procedure reset;
  301. function size:integer;
  302. procedure align(i:integer);
  303. procedure seek(i:integer);
  304. function read(var d;len:integer):integer;
  305. procedure write(const d;len:integer);
  306. procedure writestr(const s:string);
  307. procedure readstream(f:TCStream;maxlen:longint);
  308. procedure writestream(f:TCStream);
  309. property BlockSize : integer read FBlocksize;
  310. property FirstBlock : PDynamicBlock read FFirstBlock;
  311. property Pos : integer read FPosn;
  312. end;
  313. implementation
  314. {*****************************************************************************
  315. Memory debug
  316. *****************************************************************************}
  317. constructor tmemdebug.create(const s:string);
  318. begin
  319. infostr:=s;
  320. totalmem:=0;
  321. Start;
  322. end;
  323. procedure tmemdebug.start;
  324. begin
  325. {$ifdef Delphi}
  326. startmem:=0;
  327. {$else}
  328. startmem:=memavail;
  329. {$endif Delphi}
  330. end;
  331. procedure tmemdebug.stop;
  332. begin
  333. if startmem<>0 then
  334. begin
  335. {$ifndef Delphi}
  336. inc(TotalMem,memavail-startmem);
  337. {$endif}
  338. startmem:=0;
  339. end;
  340. end;
  341. destructor tmemdebug.destroy;
  342. begin
  343. Stop;
  344. show;
  345. end;
  346. procedure tmemdebug.show;
  347. begin
  348. {$ifndef Delphi}
  349. write('memory [',infostr,'] ');
  350. if TotalMem>0 then
  351. writeln(DStr(TotalMem shr 10),' Kb released')
  352. else
  353. writeln(DStr((-TotalMem) shr 10),' Kb allocated');
  354. {$endif Delphi}
  355. end;
  356. {*****************************************************************************
  357. TList
  358. *****************************************************************************}
  359. Const
  360. // Ratio of Pointer and Word Size.
  361. WordRatio = SizeOf(Pointer) Div SizeOf(Word);
  362. function TList.Get(Index: Integer): Pointer;
  363. begin
  364. If (Index<0) or (Index>=FCount) then
  365. Error(SListIndexError,Index);
  366. Result:=FList^[Index];
  367. end;
  368. procedure TList.Grow;
  369. begin
  370. // Only for compatibility with Delphi. Not needed.
  371. end;
  372. procedure TList.Put(Index: Integer; Item: Pointer);
  373. begin
  374. if (Index<0) or (Index>=FCount) then
  375. Error(SListIndexError,Index);
  376. Flist^[Index]:=Item;
  377. end;
  378. function TList.Extract(item: Pointer): Pointer;
  379. var
  380. i : Integer;
  381. begin
  382. result:=nil;
  383. i:=IndexOf(item);
  384. if i>=0 then
  385. begin
  386. Result:=item;
  387. FList^[i]:=nil;
  388. Delete(i);
  389. end;
  390. end;
  391. procedure TList.SetCapacity(NewCapacity: Integer);
  392. Var NewList,ToFree : PPointerList;
  393. begin
  394. If (NewCapacity<0) or (NewCapacity>MaxListSize) then
  395. Error (SListCapacityError,NewCapacity);
  396. if NewCapacity=FCapacity then
  397. exit;
  398. ReallocMem(FList,SizeOf(Pointer)*NewCapacity);
  399. FCapacity:=NewCapacity;
  400. end;
  401. procedure TList.SetCount(NewCount: Integer);
  402. begin
  403. If (NewCount<0) or (NewCount>MaxListSize)then
  404. Error(SListCountError,NewCount);
  405. If NewCount<FCount then
  406. FCount:=NewCount
  407. else If NewCount>FCount then
  408. begin
  409. If NewCount>FCapacity then
  410. SetCapacity (NewCount);
  411. If FCount<NewCount then
  412. FillWord (Flist^[FCount],(NewCount-FCount)* WordRatio ,0);
  413. FCount:=Newcount;
  414. end;
  415. end;
  416. destructor TList.Destroy;
  417. begin
  418. Self.Clear;
  419. inherited Destroy;
  420. end;
  421. Function TList.Add(Item: Pointer): Integer;
  422. begin
  423. Self.Insert (Count,Item);
  424. Result:=Count-1;
  425. end;
  426. Procedure TList.Clear;
  427. begin
  428. If Assigned(FList) then
  429. begin
  430. FreeMem (Flist,FCapacity*SizeOf(Pointer));
  431. FList:=Nil;
  432. FCapacity:=0;
  433. FCount:=0;
  434. end;
  435. end;
  436. Procedure TList.Delete(Index: Integer);
  437. Var
  438. OldPointer :Pointer;
  439. begin
  440. If (Index<0) or (Index>=FCount) then
  441. Error (SListIndexError,Index);
  442. FCount:=FCount-1;
  443. OldPointer:=Flist^[Index];
  444. System.Move (FList^[Index+1],FList^[Index],(FCount-Index)*SizeOf(Pointer));
  445. // Shrink the list if appropiate
  446. if (FCapacity > 256) and (FCount < FCapacity shr 2) then
  447. begin
  448. FCapacity := FCapacity shr 1;
  449. ReallocMem(FList, SizeOf(Pointer) * FCapacity);
  450. end;
  451. end;
  452. class procedure TList.Error(const Msg: string; Data: Integer);
  453. var
  454. s:string;
  455. p:longint;
  456. begin
  457. p:=pos('%d',Msg);
  458. writeln(copy(Msg,1,pred(p)),Data,copy(Msg,p+3,255));
  459. end;
  460. procedure TList.Exchange(Index1, Index2: Integer);
  461. var Temp : Pointer;
  462. begin
  463. If ((Index1>=FCount) or (Index1<0)) then
  464. Error(SListIndexError,Index1);
  465. If ((Index2>=FCount) or (Index2<0)) then
  466. Error(SListIndexError,Index2);
  467. Temp:=FList^[Index1];
  468. FList^[Index1]:=FList^[Index2];
  469. FList^[Index2]:=Temp;
  470. end;
  471. function TList.Expand: TList;
  472. Var IncSize : Longint;
  473. begin
  474. if FCount<FCapacity then exit;
  475. IncSize:=4;
  476. if FCapacity>3 then IncSize:=IncSize+4;
  477. if FCapacity>8 then IncSize:=IncSize+8;
  478. if FCapacity>127 then Inc(IncSize, FCapacity shr 2);
  479. SetCapacity(FCapacity+IncSize);
  480. Result:=Self;
  481. end;
  482. function TList.First: Pointer;
  483. begin
  484. If FCount=0 then
  485. Result:=Nil
  486. else
  487. Result:=Items[0];
  488. end;
  489. function TList.IndexOf(Item: Pointer): Integer;
  490. begin
  491. Result:=0;
  492. While (Result<FCount) and (Flist^[Result]<>Item) do Result:=Result+1;
  493. If Result=FCount then Result:=-1;
  494. end;
  495. procedure TList.Insert(Index: Integer; Item: Pointer);
  496. begin
  497. If (Index<0) or (Index>FCount )then
  498. Error(SlistIndexError,Index);
  499. IF FCount=FCapacity Then Self.Expand;
  500. If Index<FCount then
  501. System.Move(Flist^[Index],Flist^[Index+1],(FCount-Index)*SizeOf(Pointer));
  502. FList^[Index]:=Item;
  503. FCount:=FCount+1;
  504. end;
  505. function TList.Last: Pointer;
  506. begin
  507. // Wouldn't it be better to return nil if the count is zero ?
  508. If FCount=0 then
  509. Result:=Nil
  510. else
  511. Result:=Items[FCount-1];
  512. end;
  513. procedure TList.Move(CurIndex, NewIndex: Integer);
  514. Var Temp : Pointer;
  515. begin
  516. If ((CurIndex<0) or (CurIndex>Count-1)) then
  517. Error(SListIndexError,CurIndex);
  518. If (NewINdex<0) then
  519. Error(SlistIndexError,NewIndex);
  520. Temp:=FList^[CurIndex];
  521. FList^[CurIndex]:=Nil;
  522. Self.Delete(CurIndex);
  523. // ?? If NewIndex>CurIndex then NewIndex:=NewIndex-1;
  524. // Newindex changes when deleting ??
  525. Self.Insert (NewIndex,Nil);
  526. FList^[NewIndex]:=Temp;
  527. end;
  528. function TList.Remove(Item: Pointer): Integer;
  529. begin
  530. Result:=IndexOf(Item);
  531. If Result<>-1 then
  532. Self.Delete (Result);
  533. end;
  534. Procedure TList.Pack;
  535. Var {Last,I,J,}Runner : Longint;
  536. begin
  537. // Not the fastest; but surely correct
  538. For Runner:=Fcount-1 downto 0 do
  539. if Items[Runner]=Nil then Self.Delete(Runner);
  540. { The following may be faster in case of large and defragmented lists
  541. If count=0 then exit;
  542. Runner:=0;I:=0;
  543. TheLast:=Count;
  544. while runner<count do
  545. begin
  546. // Find first Nil
  547. While (FList^[Runner]<>Nil) and (Runner<Count) do Runner:=Runner+1;
  548. if Runner<Count do
  549. begin
  550. // Start searching for non-nil from last known nil+1
  551. if i<Runner then I:=Runner+1;
  552. While (Flist[I]^=Nil) and (I<Count) do I:=I+1;
  553. // Start looking for last non-nil of block.
  554. J:=I+1;
  555. While (Flist^[J]<>Nil) and (J<Count) do J:=J+1;
  556. // Move block and zero out
  557. Move (Flist^[I],Flist^[Runner],J*SizeOf(Pointer));
  558. FillWord (Flist^[I],(J-I)*WordRatio,0);
  559. // Update Runner and Last to point behind last block
  560. TheLast:=Runner+(J-I);
  561. If J=Count then
  562. begin
  563. // Shortcut, when J=Count we checked all pointers
  564. Runner:=Count
  565. else
  566. begin
  567. Runner:=TheLast;
  568. I:=j;
  569. end;
  570. end;
  571. Count:=TheLast;
  572. }
  573. end;
  574. // Needed by Sort method.
  575. Procedure QuickSort (Flist : PPointerList; L,R : Longint;
  576. Compare : TListSortCompare);
  577. Var I,J : Longint;
  578. P,Q : Pointer;
  579. begin
  580. Repeat
  581. I:=L;
  582. J:=R;
  583. P:=FList^[ (L+R) div 2 ];
  584. repeat
  585. While Compare(P,FList^[i])>0 Do I:=I+1;
  586. While Compare(P,FList^[J])<0 Do J:=J-1;
  587. If I<=J then
  588. begin
  589. Q:=Flist^[I];
  590. Flist^[I]:=FList^[J];
  591. FList^[J]:=Q;
  592. I:=I+1;
  593. J:=j-1;
  594. end;
  595. Until I>J;
  596. If L<J then QuickSort (FList,L,J,Compare);
  597. L:=I;
  598. Until I>=R;
  599. end;
  600. procedure TList.Sort(Compare: TListSortCompare);
  601. begin
  602. If Not Assigned(FList) or (FCount<2) then exit;
  603. QuickSort (Flist, 0, FCount-1,Compare);
  604. end;
  605. procedure TList.Assign(Obj:TList);
  606. // Principle copied from TCollection
  607. var i : Integer;
  608. begin
  609. Clear;
  610. For I:=0 To Obj.Count-1 Do
  611. Add(Obj[i]);
  612. end;
  613. {****************************************************************************
  614. TLinkedListItem
  615. ****************************************************************************}
  616. constructor TLinkedListItem.Create;
  617. begin
  618. Previous:=nil;
  619. Next:=nil;
  620. end;
  621. destructor TLinkedListItem.Destroy;
  622. begin
  623. end;
  624. function TLinkedListItem.GetCopy:TLinkedListItem;
  625. var
  626. p : TLinkedListItem;
  627. l : integer;
  628. begin
  629. p:=TLinkedListItemClass(ClassType).Create;
  630. l:=InstanceSize;
  631. Move(pointer(self)^,pointer(p)^,l);
  632. Result:=p;
  633. end;
  634. {****************************************************************************
  635. TLinkedList
  636. ****************************************************************************}
  637. constructor TLinkedList.Create;
  638. begin
  639. FFirst:=nil;
  640. Flast:=nil;
  641. FCount:=0;
  642. FNoClear:=False;
  643. end;
  644. destructor TLinkedList.destroy;
  645. begin
  646. if not FNoClear then
  647. Clear;
  648. end;
  649. function TLinkedList.empty:boolean;
  650. begin
  651. Empty:=(FFirst=nil);
  652. end;
  653. procedure TLinkedList.Insert(Item:TLinkedListItem);
  654. begin
  655. if FFirst=nil then
  656. begin
  657. FLast:=Item;
  658. Item.Previous:=nil;
  659. Item.Next:=nil;
  660. end
  661. else
  662. begin
  663. FFirst.Previous:=Item;
  664. Item.Previous:=nil;
  665. Item.Next:=FFirst;
  666. end;
  667. FFirst:=Item;
  668. inc(FCount);
  669. end;
  670. procedure TLinkedList.InsertBefore(Item,Loc : TLinkedListItem);
  671. begin
  672. Item.Previous:=Loc.Previous;
  673. Item.Next:=Loc;
  674. Loc.Previous:=Item;
  675. if assigned(Item.Previous) then
  676. Item.Previous.Next:=Item
  677. else
  678. { if we've no next item, we've to adjust FFist }
  679. FFirst:=Item;
  680. inc(FCount);
  681. end;
  682. procedure TLinkedList.InsertAfter(Item,Loc : TLinkedListItem);
  683. begin
  684. Item.Next:=Loc.Next;
  685. Loc.Next:=Item;
  686. Item.Previous:=Loc;
  687. if assigned(Item.Next) then
  688. Item.Next.Previous:=Item
  689. else
  690. { if we've no next item, we've to adjust FLast }
  691. FLast:=Item;
  692. inc(FCount);
  693. end;
  694. procedure TLinkedList.Concat(Item:TLinkedListItem);
  695. begin
  696. if FFirst=nil then
  697. begin
  698. FFirst:=Item;
  699. Item.Previous:=nil;
  700. Item.Next:=nil;
  701. end
  702. else
  703. begin
  704. Flast.Next:=Item;
  705. Item.Previous:=Flast;
  706. Item.Next:=nil;
  707. end;
  708. Flast:=Item;
  709. inc(FCount);
  710. end;
  711. procedure TLinkedList.remove(Item:TLinkedListItem);
  712. begin
  713. if Item=nil then
  714. exit;
  715. if (FFirst=Item) and (Flast=Item) then
  716. begin
  717. FFirst:=nil;
  718. Flast:=nil;
  719. end
  720. else if FFirst=Item then
  721. begin
  722. FFirst:=Item.Next;
  723. if assigned(FFirst) then
  724. FFirst.Previous:=nil;
  725. end
  726. else if Flast=Item then
  727. begin
  728. Flast:=Flast.Previous;
  729. if assigned(Flast) then
  730. Flast.Next:=nil;
  731. end
  732. else
  733. begin
  734. Item.Previous.Next:=Item.Next;
  735. Item.Next.Previous:=Item.Previous;
  736. end;
  737. Item.Next:=nil;
  738. Item.Previous:=nil;
  739. dec(FCount);
  740. end;
  741. procedure TLinkedList.clear;
  742. var
  743. NewNode : TLinkedListItem;
  744. begin
  745. NewNode:=FFirst;
  746. while assigned(NewNode) do
  747. begin
  748. FFirst:=NewNode.Next;
  749. NewNode.Free;
  750. NewNode:=FFirst;
  751. end;
  752. FLast:=nil;
  753. FFirst:=nil;
  754. FCount:=0;
  755. end;
  756. function TLinkedList.GetFirst:TLinkedListItem;
  757. begin
  758. if FFirst=nil then
  759. GetFirst:=nil
  760. else
  761. begin
  762. GetFirst:=FFirst;
  763. if FFirst=FLast then
  764. FLast:=nil;
  765. FFirst:=FFirst.Next;
  766. dec(FCount);
  767. end;
  768. end;
  769. function TLinkedList.GetLast:TLinkedListItem;
  770. begin
  771. if FLast=nil then
  772. Getlast:=nil
  773. else
  774. begin
  775. Getlast:=FLast;
  776. if FLast=FFirst then
  777. FFirst:=nil;
  778. FLast:=FLast.Previous;
  779. dec(FCount);
  780. end;
  781. end;
  782. procedure TLinkedList.insertList(p : TLinkedList);
  783. begin
  784. { empty List ? }
  785. if (p.FFirst=nil) then
  786. exit;
  787. p.Flast.Next:=FFirst;
  788. { we have a double Linked List }
  789. if assigned(FFirst) then
  790. FFirst.Previous:=p.Flast;
  791. FFirst:=p.FFirst;
  792. if (FLast=nil) then
  793. Flast:=p.Flast;
  794. inc(FCount,p.FCount);
  795. { p becomes empty }
  796. p.FFirst:=nil;
  797. p.Flast:=nil;
  798. p.FCount:=0;
  799. end;
  800. procedure TLinkedList.insertListAfter(Item:TLinkedListItem;p : TLinkedList);
  801. begin
  802. { empty List ? }
  803. if (p.FFirst=nil) then
  804. exit;
  805. if (Item=nil) then
  806. begin
  807. { Insert at begin }
  808. InsertList(p);
  809. exit;
  810. end
  811. else
  812. begin
  813. p.FFirst.Previous:=Item;
  814. p.FLast.Next:=Item.Next;
  815. if assigned(Item.Next) then
  816. Item.Next.Previous:=p.FLast
  817. else
  818. FLast:=p.FLast;
  819. Item.Next:=p.FFirst;
  820. inc(FCount,p.FCount);
  821. end;
  822. { p becomes empty }
  823. p.FFirst:=nil;
  824. p.Flast:=nil;
  825. p.FCount:=0;
  826. end;
  827. procedure TLinkedList.concatList(p : TLinkedList);
  828. begin
  829. if (p.FFirst=nil) then
  830. exit;
  831. if FFirst=nil then
  832. FFirst:=p.FFirst
  833. else
  834. begin
  835. FLast.Next:=p.FFirst;
  836. p.FFirst.Previous:=Flast;
  837. end;
  838. Flast:=p.Flast;
  839. inc(FCount,p.FCount);
  840. { make p empty }
  841. p.Flast:=nil;
  842. p.FFirst:=nil;
  843. p.FCount:=0;
  844. end;
  845. procedure TLinkedList.insertListcopy(p : TLinkedList);
  846. var
  847. NewNode,NewNode2 : TLinkedListItem;
  848. begin
  849. NewNode:=p.First;
  850. while assigned(NewNode) do
  851. begin
  852. NewNode2:=NewNode.Getcopy;
  853. if assigned(NewNode2) then
  854. Insert(NewNode2);
  855. NewNode:=NewNode.Next;
  856. end;
  857. end;
  858. procedure TLinkedList.concatListcopy(p : TLinkedList);
  859. var
  860. NewNode,NewNode2 : TLinkedListItem;
  861. begin
  862. NewNode:=p.First;
  863. while assigned(NewNode) do
  864. begin
  865. NewNode2:=NewNode.Getcopy;
  866. if assigned(NewNode2) then
  867. Concat(NewNode2);
  868. NewNode:=NewNode.Next;
  869. end;
  870. end;
  871. {****************************************************************************
  872. TStringListItem
  873. ****************************************************************************}
  874. constructor TStringListItem.Create(const s:string);
  875. begin
  876. inherited Create;
  877. FPStr:=stringdup(s);
  878. end;
  879. destructor TStringListItem.Destroy;
  880. begin
  881. stringdispose(FPStr);
  882. end;
  883. function TStringListItem.Str:string;
  884. begin
  885. Str:=FPStr^;
  886. end;
  887. function TStringListItem.GetCopy:TLinkedListItem;
  888. begin
  889. Result:=(inherited GetCopy);
  890. TStringListItem(Result).FPStr:=stringdup(FPstr^);
  891. end;
  892. {****************************************************************************
  893. TSTRINGList
  894. ****************************************************************************}
  895. constructor tstringList.Create;
  896. begin
  897. inherited Create;
  898. FDoubles:=true;
  899. end;
  900. constructor tstringList.Create_no_double;
  901. begin
  902. inherited Create;
  903. FDoubles:=false;
  904. end;
  905. procedure tstringList.insert(const s : string);
  906. begin
  907. if (s='') or
  908. ((not FDoubles) and (find(s)<>nil)) then
  909. exit;
  910. inherited insert(tstringListItem.create(s));
  911. end;
  912. procedure tstringList.concat(const s : string);
  913. begin
  914. if (s='') or
  915. ((not FDoubles) and (find(s)<>nil)) then
  916. exit;
  917. inherited concat(tstringListItem.create(s));
  918. end;
  919. procedure tstringList.remove(const s : string);
  920. var
  921. p : tstringListItem;
  922. begin
  923. if s='' then
  924. exit;
  925. p:=find(s);
  926. if assigned(p) then
  927. begin
  928. inherited Remove(p);
  929. p.Free;
  930. end;
  931. end;
  932. function tstringList.GetFirst : string;
  933. var
  934. p : tstringListItem;
  935. begin
  936. p:=tstringListItem(inherited GetFirst);
  937. if p=nil then
  938. GetFirst:=''
  939. else
  940. begin
  941. GetFirst:=p.FPStr^;
  942. p.free;
  943. end;
  944. end;
  945. function tstringList.Getlast : string;
  946. var
  947. p : tstringListItem;
  948. begin
  949. p:=tstringListItem(inherited Getlast);
  950. if p=nil then
  951. Getlast:=''
  952. else
  953. begin
  954. Getlast:=p.FPStr^;
  955. p.free;
  956. end;
  957. end;
  958. function tstringList.find(const s:string):TstringListItem;
  959. var
  960. NewNode : tstringListItem;
  961. begin
  962. find:=nil;
  963. if s='' then
  964. exit;
  965. NewNode:=tstringListItem(FFirst);
  966. while assigned(NewNode) do
  967. begin
  968. if NewNode.FPStr^=s then
  969. begin
  970. find:=NewNode;
  971. exit;
  972. end;
  973. NewNode:=tstringListItem(NewNode.Next);
  974. end;
  975. end;
  976. procedure TStringList.InsertItem(item:TStringListItem);
  977. begin
  978. inherited Insert(item);
  979. end;
  980. procedure TStringList.ConcatItem(item:TStringListItem);
  981. begin
  982. inherited Concat(item);
  983. end;
  984. {****************************************************************************
  985. TNamedIndexItem
  986. ****************************************************************************}
  987. constructor TNamedIndexItem.Create;
  988. begin
  989. { index }
  990. Findexnr:=-1;
  991. FindexNext:=nil;
  992. { dictionary }
  993. Fleft:=nil;
  994. Fright:=nil;
  995. FName:=nil;
  996. Fspeedvalue:=cardinal($ffffffff);
  997. { List }
  998. FListNext:=nil;
  999. end;
  1000. constructor TNamedIndexItem.Createname(const n:string);
  1001. begin
  1002. { index }
  1003. Findexnr:=-1;
  1004. FindexNext:=nil;
  1005. { dictionary }
  1006. Fleft:=nil;
  1007. Fright:=nil;
  1008. fspeedvalue:=getspeedvalue(n);
  1009. {$ifdef compress}
  1010. FName:=stringdup(minilzw_encode(n));
  1011. {$else}
  1012. FName:=stringdup(n);
  1013. {$endif}
  1014. { List }
  1015. FListNext:=nil;
  1016. end;
  1017. destructor TNamedIndexItem.destroy;
  1018. begin
  1019. stringdispose(FName);
  1020. end;
  1021. procedure TNamedIndexItem.setname(const n:string);
  1022. begin
  1023. if speedvalue=cardinal($ffffffff) then
  1024. begin
  1025. if assigned(FName) then
  1026. stringdispose(FName);
  1027. fspeedvalue:=getspeedvalue(n);
  1028. {$ifdef compress}
  1029. FName:=stringdup(minilzw_encode(n));
  1030. {$else}
  1031. FName:=stringdup(n);
  1032. {$endif}
  1033. end;
  1034. end;
  1035. function TNamedIndexItem.GetName:string;
  1036. begin
  1037. if assigned(FName) then
  1038. {$ifdef compress}
  1039. Getname:=minilzw_decode(FName^)
  1040. {$else}
  1041. Getname:=FName^
  1042. {$endif}
  1043. else
  1044. Getname:='';
  1045. end;
  1046. {****************************************************************************
  1047. TDICTIONARY
  1048. ****************************************************************************}
  1049. constructor Tdictionary.Create;
  1050. begin
  1051. FRoot:=nil;
  1052. FHashArray:=nil;
  1053. noclear:=false;
  1054. delete_doubles:=false;
  1055. end;
  1056. procedure Tdictionary.usehash;
  1057. begin
  1058. if not(assigned(FRoot)) and
  1059. not(assigned(FHashArray)) then
  1060. begin
  1061. New(FHashArray);
  1062. fillchar(FHashArray^,sizeof(FHashArray^),0);
  1063. end;
  1064. end;
  1065. function counttree(p: tnamedindexitem): longint;
  1066. begin
  1067. counttree:=0;
  1068. if not assigned(p) then
  1069. exit;
  1070. result := 1;
  1071. inc(result,counttree(p.fleft));
  1072. inc(result,counttree(p.fright));
  1073. end;
  1074. destructor Tdictionary.destroy;
  1075. begin
  1076. if not noclear then
  1077. clear;
  1078. if assigned(FHashArray) then
  1079. begin
  1080. dispose(FHashArray);
  1081. end;
  1082. end;
  1083. procedure Tdictionary.cleartree(var obj:TNamedIndexItem);
  1084. begin
  1085. if assigned(obj.Fleft) then
  1086. cleartree(obj.FLeft);
  1087. if assigned(obj.FRight) then
  1088. cleartree(obj.FRight);
  1089. obj.free;
  1090. obj:=nil;
  1091. end;
  1092. procedure Tdictionary.clear;
  1093. var
  1094. w : integer;
  1095. begin
  1096. if assigned(FRoot) then
  1097. cleartree(FRoot);
  1098. if assigned(FHashArray) then
  1099. for w:= low(FHashArray^) to high(FHashArray^) do
  1100. if assigned(FHashArray^[w]) then
  1101. cleartree(FHashArray^[w]);
  1102. end;
  1103. function Tdictionary.delete(const s:string):TNamedIndexItem;
  1104. var
  1105. p,SpeedValue : cardinal;
  1106. n : TNamedIndexItem;
  1107. {$ifdef compress}
  1108. senc:string;
  1109. {$else}
  1110. senc:string absolute s;
  1111. {$endif}
  1112. procedure insert_right_bottom(var root,Atree:TNamedIndexItem);
  1113. begin
  1114. while root.FRight<>nil do
  1115. root:=root.FRight;
  1116. root.FRight:=Atree;
  1117. end;
  1118. function delete_from_tree(root:TNamedIndexItem):TNamedIndexItem;
  1119. type
  1120. leftright=(left,right);
  1121. var
  1122. lr : leftright;
  1123. oldroot : TNamedIndexItem;
  1124. begin
  1125. oldroot:=nil;
  1126. while (root<>nil) and (root.SpeedValue<>SpeedValue) do
  1127. begin
  1128. oldroot:=root;
  1129. if SpeedValue<root.SpeedValue then
  1130. begin
  1131. root:=root.FRight;
  1132. lr:=right;
  1133. end
  1134. else
  1135. begin
  1136. root:=root.FLeft;
  1137. lr:=left;
  1138. end;
  1139. end;
  1140. while (root<>nil) and (root.FName^<>senc) do
  1141. begin
  1142. oldroot:=root;
  1143. if senc<root.FName^ then
  1144. begin
  1145. root:=root.FRight;
  1146. lr:=right;
  1147. end
  1148. else
  1149. begin
  1150. root:=root.FLeft;
  1151. lr:=left;
  1152. end;
  1153. end;
  1154. if root<>nil then
  1155. begin
  1156. dec(FCount);
  1157. if root.FLeft<>nil then
  1158. begin
  1159. { Now the Node pointing to root must point to the left
  1160. subtree of root. The right subtree of root must be
  1161. connected to the right bottom of the left subtree.}
  1162. if lr=left then
  1163. oldroot.FLeft:=root.FLeft
  1164. else
  1165. oldroot.FRight:=root.FLeft;
  1166. if root.FRight<>nil then
  1167. insert_right_bottom(root.FLeft,root.FRight);
  1168. end
  1169. else
  1170. begin
  1171. { There is no left subtree. So we can just replace the Node to
  1172. delete with the right subtree.}
  1173. if lr=left then
  1174. oldroot.FLeft:=root.FRight
  1175. else
  1176. oldroot.FRight:=root.FRight;
  1177. end;
  1178. end;
  1179. delete_from_tree:=root;
  1180. end;
  1181. begin
  1182. {$ifdef compress}
  1183. senc:=minilzw_encode(s);
  1184. {$endif}
  1185. SpeedValue:=GetSpeedValue(s);
  1186. n:=FRoot;
  1187. if assigned(FHashArray) then
  1188. begin
  1189. { First, check if the Node to delete directly located under
  1190. the hasharray.}
  1191. p:=SpeedValue mod hasharraysize;
  1192. n:=FHashArray^[p];
  1193. if (n<>nil) and (n.SpeedValue=SpeedValue) and
  1194. (n.FName^=senc) then
  1195. begin
  1196. { The Node to delete is directly located under the
  1197. hasharray. Make the hasharray point to the left
  1198. subtree of the Node and place the right subtree on
  1199. the right-bottom of the left subtree.}
  1200. if n.FLeft<>nil then
  1201. begin
  1202. FHashArray^[p]:=n.FLeft;
  1203. if n.FRight<>nil then
  1204. insert_right_bottom(n.FLeft,n.FRight);
  1205. end
  1206. else
  1207. FHashArray^[p]:=n.FRight;
  1208. delete:=n;
  1209. dec(FCount);
  1210. exit;
  1211. end;
  1212. end
  1213. else
  1214. begin
  1215. { First check if the Node to delete is the root.}
  1216. if (FRoot<>nil) and (n.SpeedValue=SpeedValue) and
  1217. (n.FName^=senc) then
  1218. begin
  1219. if n.FLeft<>nil then
  1220. begin
  1221. FRoot:=n.FLeft;
  1222. if n.FRight<>nil then
  1223. insert_right_bottom(n.FLeft,n.FRight);
  1224. end
  1225. else
  1226. FRoot:=n.FRight;
  1227. delete:=n;
  1228. dec(FCount);
  1229. exit;
  1230. end;
  1231. end;
  1232. delete:=delete_from_tree(n);
  1233. end;
  1234. function Tdictionary.empty:boolean;
  1235. var
  1236. w : integer;
  1237. begin
  1238. if assigned(FHashArray) then
  1239. begin
  1240. empty:=false;
  1241. for w:=low(FHashArray^) to high(FHashArray^) do
  1242. if assigned(FHashArray^[w]) then
  1243. exit;
  1244. empty:=true;
  1245. end
  1246. else
  1247. empty:=(FRoot=nil);
  1248. end;
  1249. procedure Tdictionary.foreach(proc2call:TNamedIndexcallback;arg:pointer);
  1250. procedure a(p:TNamedIndexItem;arg:pointer);
  1251. begin
  1252. proc2call(p,arg);
  1253. if assigned(p.FLeft) then
  1254. a(p.FLeft,arg);
  1255. if assigned(p.FRight) then
  1256. a(p.FRight,arg);
  1257. end;
  1258. var
  1259. i : integer;
  1260. begin
  1261. if assigned(FHashArray) then
  1262. begin
  1263. for i:=low(FHashArray^) to high(FHashArray^) do
  1264. if assigned(FHashArray^[i]) then
  1265. a(FHashArray^[i],arg);
  1266. end
  1267. else
  1268. if assigned(FRoot) then
  1269. a(FRoot,arg);
  1270. end;
  1271. procedure Tdictionary.foreach_static(proc2call:TNamedIndexStaticCallback;arg:pointer);
  1272. procedure a(p:TNamedIndexItem;arg:pointer);
  1273. begin
  1274. proc2call(p,arg);
  1275. if assigned(p.FLeft) then
  1276. a(p.FLeft,arg);
  1277. if assigned(p.FRight) then
  1278. a(p.FRight,arg);
  1279. end;
  1280. var
  1281. i : integer;
  1282. begin
  1283. if assigned(FHashArray) then
  1284. begin
  1285. for i:=low(FHashArray^) to high(FHashArray^) do
  1286. if assigned(FHashArray^[i]) then
  1287. a(FHashArray^[i],arg);
  1288. end
  1289. else
  1290. if assigned(FRoot) then
  1291. a(FRoot,arg);
  1292. end;
  1293. function Tdictionary.replace(oldobj,newobj:TNamedIndexItem):boolean;
  1294. var
  1295. hp : TNamedIndexItem;
  1296. begin
  1297. hp:=nil;
  1298. Replace:=false;
  1299. { must be the same name and hash }
  1300. if (oldobj.FSpeedValue<>newobj.FSpeedValue) or
  1301. (oldobj.FName^<>newobj.FName^) then
  1302. exit;
  1303. { copy tree info }
  1304. newobj.FLeft:=oldobj.FLeft;
  1305. newobj.FRight:=oldobj.FRight;
  1306. { update treeroot }
  1307. if assigned(FHashArray) then
  1308. begin
  1309. hp:=FHashArray^[newobj.FSpeedValue mod hasharraysize];
  1310. if hp=oldobj then
  1311. begin
  1312. FHashArray^[newobj.FSpeedValue mod hasharraysize]:=newobj;
  1313. hp:=nil;
  1314. end;
  1315. end
  1316. else
  1317. begin
  1318. hp:=FRoot;
  1319. if hp=oldobj then
  1320. begin
  1321. FRoot:=newobj;
  1322. hp:=nil;
  1323. end;
  1324. end;
  1325. { update parent entry }
  1326. while assigned(hp) do
  1327. begin
  1328. { is the node to replace the left or right, then
  1329. update this node and stop }
  1330. if hp.FLeft=oldobj then
  1331. begin
  1332. hp.FLeft:=newobj;
  1333. break;
  1334. end;
  1335. if hp.FRight=oldobj then
  1336. begin
  1337. hp.FRight:=newobj;
  1338. break;
  1339. end;
  1340. { First check SpeedValue, to allow a fast insert }
  1341. if hp.SpeedValue>oldobj.SpeedValue then
  1342. hp:=hp.FRight
  1343. else
  1344. if hp.SpeedValue<oldobj.SpeedValue then
  1345. hp:=hp.FLeft
  1346. else
  1347. begin
  1348. if (hp.FName^=oldobj.FName^) then
  1349. begin
  1350. { this can never happend, return error }
  1351. exit;
  1352. end
  1353. else
  1354. if oldobj.FName^>hp.FName^ then
  1355. hp:=hp.FLeft
  1356. else
  1357. hp:=hp.FRight;
  1358. end;
  1359. end;
  1360. Replace:=true;
  1361. end;
  1362. function Tdictionary.insert(obj:TNamedIndexItem):TNamedIndexItem;
  1363. begin
  1364. inc(FCount);
  1365. if assigned(FHashArray) then
  1366. insert:=insertNode(obj,FHashArray^[obj.SpeedValue mod hasharraysize])
  1367. else
  1368. insert:=insertNode(obj,FRoot);
  1369. end;
  1370. function tdictionary.insertNode(NewNode:TNamedIndexItem;var currNode:TNamedIndexItem):TNamedIndexItem;
  1371. begin
  1372. if currNode=nil then
  1373. begin
  1374. currNode:=NewNode;
  1375. insertNode:=NewNode;
  1376. end
  1377. { First check SpeedValue, to allow a fast insert }
  1378. else
  1379. if currNode.SpeedValue>NewNode.SpeedValue then
  1380. insertNode:=insertNode(NewNode,currNode.FRight)
  1381. else
  1382. if currNode.SpeedValue<NewNode.SpeedValue then
  1383. insertNode:=insertNode(NewNode,currNode.FLeft)
  1384. else
  1385. begin
  1386. if currNode.FName^>NewNode.FName^ then
  1387. insertNode:=insertNode(NewNode,currNode.FRight)
  1388. else
  1389. if currNode.FName^<NewNode.FName^ then
  1390. insertNode:=insertNode(NewNode,currNode.FLeft)
  1391. else
  1392. begin
  1393. if (delete_doubles) and
  1394. assigned(currNode) then
  1395. begin
  1396. NewNode.FLeft:=currNode.FLeft;
  1397. NewNode.FRight:=currNode.FRight;
  1398. if delete_doubles then
  1399. begin
  1400. currnode.FLeft:=nil;
  1401. currnode.FRight:=nil;
  1402. currnode.free;
  1403. end;
  1404. currNode:=NewNode;
  1405. insertNode:=NewNode;
  1406. end
  1407. else
  1408. insertNode:=currNode;
  1409. end;
  1410. end;
  1411. end;
  1412. procedure tdictionary.inserttree(currtree,currroot:TNamedIndexItem);
  1413. begin
  1414. if assigned(currtree) then
  1415. begin
  1416. inserttree(currtree.FLeft,currroot);
  1417. inserttree(currtree.FRight,currroot);
  1418. currtree.FRight:=nil;
  1419. currtree.FLeft:=nil;
  1420. insertNode(currtree,currroot);
  1421. end;
  1422. end;
  1423. function tdictionary.rename(const olds,News : string):TNamedIndexItem;
  1424. var
  1425. spdval : cardinal;
  1426. lasthp,
  1427. hp,hp2,hp3 : TNamedIndexItem;
  1428. {$ifdef compress}
  1429. oldsenc,newsenc:string;
  1430. {$else}
  1431. oldsenc:string absolute olds;
  1432. newsenc:string absolute news;
  1433. {$endif}
  1434. begin
  1435. {$ifdef compress}
  1436. oldsenc:=minilzw_encode(olds);
  1437. newsenc:=minilzw_encode(news);
  1438. {$endif}
  1439. spdval:=GetSpeedValue(olds);
  1440. if assigned(FHashArray) then
  1441. hp:=FHashArray^[spdval mod hasharraysize]
  1442. else
  1443. hp:=FRoot;
  1444. lasthp:=nil;
  1445. while assigned(hp) do
  1446. begin
  1447. if spdval>hp.SpeedValue then
  1448. begin
  1449. lasthp:=hp;
  1450. hp:=hp.FLeft
  1451. end
  1452. else
  1453. if spdval<hp.SpeedValue then
  1454. begin
  1455. lasthp:=hp;
  1456. hp:=hp.FRight
  1457. end
  1458. else
  1459. begin
  1460. if (hp.FName^=oldsenc) then
  1461. begin
  1462. { Get in hp2 the replacer for the root or hasharr }
  1463. hp2:=hp.FLeft;
  1464. hp3:=hp.FRight;
  1465. if not assigned(hp2) then
  1466. begin
  1467. hp2:=hp.FRight;
  1468. hp3:=hp.FLeft;
  1469. end;
  1470. { remove entry from the tree }
  1471. if assigned(lasthp) then
  1472. begin
  1473. if lasthp.FLeft=hp then
  1474. lasthp.FLeft:=hp2
  1475. else
  1476. lasthp.FRight:=hp2;
  1477. end
  1478. else
  1479. begin
  1480. if assigned(FHashArray) then
  1481. FHashArray^[spdval mod hasharraysize]:=hp2
  1482. else
  1483. FRoot:=hp2;
  1484. end;
  1485. { reinsert the hp3 in the tree from hp2 }
  1486. inserttree(hp3,hp2);
  1487. { reset Node with New values }
  1488. hp.FLeft:=nil;
  1489. hp.FRight:=nil;
  1490. stringdispose(hp.FName);
  1491. hp.FName:=stringdup(newsenc);
  1492. hp.FSpeedValue:=GetSpeedValue(news);
  1493. { reinsert }
  1494. if assigned(FHashArray) then
  1495. rename:=insertNode(hp,FHashArray^[hp.SpeedValue mod hasharraysize])
  1496. else
  1497. rename:=insertNode(hp,FRoot);
  1498. exit;
  1499. end
  1500. else
  1501. if oldsenc>hp.FName^ then
  1502. begin
  1503. lasthp:=hp;
  1504. hp:=hp.FLeft
  1505. end
  1506. else
  1507. begin
  1508. lasthp:=hp;
  1509. hp:=hp.FRight;
  1510. end;
  1511. end;
  1512. end;
  1513. result := nil;
  1514. end;
  1515. function Tdictionary.search(const s:string):TNamedIndexItem;
  1516. var t:string;
  1517. begin
  1518. search:=speedsearch(s,getspeedvalue(s));
  1519. end;
  1520. function Tdictionary.speedsearch(const s:string;SpeedValue:cardinal):TNamedIndexItem;
  1521. var
  1522. NewNode:TNamedIndexItem;
  1523. {$ifdef compress}
  1524. decn:string;
  1525. {$endif}
  1526. begin
  1527. if assigned(FHashArray) then
  1528. NewNode:=FHashArray^[SpeedValue mod hasharraysize]
  1529. else
  1530. NewNode:=FRoot;
  1531. while assigned(NewNode) do
  1532. begin
  1533. if SpeedValue>NewNode.SpeedValue then
  1534. NewNode:=NewNode.FLeft
  1535. else
  1536. if SpeedValue<NewNode.SpeedValue then
  1537. NewNode:=NewNode.FRight
  1538. else
  1539. begin
  1540. {$ifdef compress}
  1541. decn:=minilzw_decode(newnode.fname^);
  1542. if (decn=s) then
  1543. begin
  1544. speedsearch:=NewNode;
  1545. exit;
  1546. end
  1547. else
  1548. if s>decn then
  1549. NewNode:=NewNode.FLeft
  1550. else
  1551. NewNode:=NewNode.FRight;
  1552. {$else}
  1553. if (NewNode.FName^=s) then
  1554. begin
  1555. speedsearch:=NewNode;
  1556. exit;
  1557. end
  1558. else
  1559. if s>NewNode.FName^ then
  1560. NewNode:=NewNode.FLeft
  1561. else
  1562. NewNode:=NewNode.FRight;
  1563. {$endif}
  1564. end;
  1565. end;
  1566. speedsearch:=nil;
  1567. end;
  1568. {****************************************************************************
  1569. tsingleList
  1570. ****************************************************************************}
  1571. constructor tsingleList.create;
  1572. begin
  1573. First:=nil;
  1574. last:=nil;
  1575. end;
  1576. procedure tsingleList.reset;
  1577. begin
  1578. First:=nil;
  1579. last:=nil;
  1580. end;
  1581. procedure tsingleList.clear;
  1582. var
  1583. hp,hp2 : TNamedIndexItem;
  1584. begin
  1585. hp:=First;
  1586. while assigned(hp) do
  1587. begin
  1588. hp2:=hp;
  1589. hp:=hp.FListNext;
  1590. hp2.free;
  1591. end;
  1592. First:=nil;
  1593. last:=nil;
  1594. end;
  1595. procedure tsingleList.insert(p:TNamedIndexItem);
  1596. begin
  1597. if not assigned(First) then
  1598. First:=p
  1599. else
  1600. last.FListNext:=p;
  1601. last:=p;
  1602. p.FListNext:=nil;
  1603. end;
  1604. {****************************************************************************
  1605. tindexarray
  1606. ****************************************************************************}
  1607. constructor tindexarray.create(Agrowsize:integer);
  1608. begin
  1609. growsize:=Agrowsize;
  1610. size:=0;
  1611. count:=0;
  1612. data:=nil;
  1613. First:=nil;
  1614. noclear:=false;
  1615. end;
  1616. destructor tindexarray.destroy;
  1617. begin
  1618. if assigned(data) then
  1619. begin
  1620. if not noclear then
  1621. clear;
  1622. freemem(data);
  1623. data:=nil;
  1624. end;
  1625. end;
  1626. function tindexarray.search(nr:integer):TNamedIndexItem;
  1627. begin
  1628. if nr<=count then
  1629. search:=data^[nr]
  1630. else
  1631. search:=nil;
  1632. end;
  1633. procedure tindexarray.clear;
  1634. var
  1635. i : integer;
  1636. begin
  1637. for i:=1 to count do
  1638. if assigned(data^[i]) then
  1639. begin
  1640. data^[i].free;
  1641. data^[i]:=nil;
  1642. end;
  1643. count:=0;
  1644. First:=nil;
  1645. end;
  1646. procedure tindexarray.foreach(proc2call : Tnamedindexcallback;arg:pointer);
  1647. var
  1648. i : integer;
  1649. begin
  1650. for i:=1 to count do
  1651. if assigned(data^[i]) then
  1652. proc2call(data^[i],arg);
  1653. end;
  1654. procedure tindexarray.foreach_static(proc2call : Tnamedindexstaticcallback;arg:pointer);
  1655. var
  1656. i : integer;
  1657. begin
  1658. for i:=1 to count do
  1659. if assigned(data^[i]) then
  1660. proc2call(data^[i],arg);
  1661. end;
  1662. procedure tindexarray.grow(gsize:integer);
  1663. var
  1664. osize : integer;
  1665. begin
  1666. osize:=size;
  1667. inc(size,gsize);
  1668. reallocmem(data,size*sizeof(pointer));
  1669. fillchar(data^[osize+1],gsize*sizeof(pointer),0);
  1670. end;
  1671. procedure tindexarray.deleteindex(p:TNamedIndexItem);
  1672. var
  1673. i : integer;
  1674. begin
  1675. i:=p.Findexnr;
  1676. { update counter }
  1677. if i=count then
  1678. dec(count);
  1679. { update Linked List }
  1680. while (i>0) do
  1681. begin
  1682. dec(i);
  1683. if (i>0) and assigned(data^[i]) then
  1684. begin
  1685. data^[i].FindexNext:=data^[p.Findexnr].FindexNext;
  1686. break;
  1687. end;
  1688. end;
  1689. if i=0 then
  1690. First:=p.FindexNext;
  1691. data^[p.FIndexnr]:=nil;
  1692. { clear entry }
  1693. p.FIndexnr:=-1;
  1694. p.FIndexNext:=nil;
  1695. end;
  1696. procedure tindexarray.delete(var p:TNamedIndexItem);
  1697. begin
  1698. deleteindex(p);
  1699. p.free;
  1700. p:=nil;
  1701. end;
  1702. procedure tindexarray.insert(p:TNamedIndexItem);
  1703. var
  1704. i : integer;
  1705. begin
  1706. if p.FIndexnr=-1 then
  1707. begin
  1708. inc(count);
  1709. p.FIndexnr:=count;
  1710. end;
  1711. if p.FIndexnr>count then
  1712. count:=p.FIndexnr;
  1713. if count>size then
  1714. grow(((count div growsize)+1)*growsize);
  1715. Assert(not assigned(data^[p.FIndexnr]) or (p=data^[p.FIndexnr]));
  1716. data^[p.FIndexnr]:=p;
  1717. { update Linked List backward }
  1718. i:=p.FIndexnr;
  1719. while (i>0) do
  1720. begin
  1721. dec(i);
  1722. if (i>0) and assigned(data^[i]) then
  1723. begin
  1724. data^[i].FIndexNext:=p;
  1725. break;
  1726. end;
  1727. end;
  1728. if i=0 then
  1729. First:=p;
  1730. { update Linked List forward }
  1731. i:=p.FIndexnr;
  1732. while (i<=count) do
  1733. begin
  1734. inc(i);
  1735. if (i<=count) and assigned(data^[i]) then
  1736. begin
  1737. p.FIndexNext:=data^[i];
  1738. exit;
  1739. end;
  1740. end;
  1741. if i>count then
  1742. p.FIndexNext:=nil;
  1743. end;
  1744. procedure tindexarray.replace(oldp,newp:TNamedIndexItem);
  1745. var
  1746. i : integer;
  1747. begin
  1748. newp.FIndexnr:=oldp.FIndexnr;
  1749. newp.FIndexNext:=oldp.FIndexNext;
  1750. data^[newp.FIndexnr]:=newp;
  1751. if First=oldp then
  1752. First:=newp;
  1753. { update Linked List backward }
  1754. i:=newp.FIndexnr;
  1755. while (i>0) do
  1756. begin
  1757. dec(i);
  1758. if (i>0) and assigned(data^[i]) then
  1759. begin
  1760. data^[i].FIndexNext:=newp;
  1761. break;
  1762. end;
  1763. end;
  1764. end;
  1765. {****************************************************************************
  1766. tdynamicarray
  1767. ****************************************************************************}
  1768. constructor tdynamicarray.create(Ablocksize:integer);
  1769. begin
  1770. FPosn:=0;
  1771. FPosnblock:=nil;
  1772. FFirstblock:=nil;
  1773. FLastblock:=nil;
  1774. Fblocksize:=Ablocksize;
  1775. grow;
  1776. end;
  1777. destructor tdynamicarray.destroy;
  1778. var
  1779. hp : pdynamicblock;
  1780. begin
  1781. while assigned(FFirstblock) do
  1782. begin
  1783. hp:=FFirstblock;
  1784. FFirstblock:=FFirstblock^.Next;
  1785. Freemem(hp);
  1786. end;
  1787. end;
  1788. function tdynamicarray.size:integer;
  1789. begin
  1790. if assigned(FLastblock) then
  1791. size:=FLastblock^.pos+FLastblock^.used
  1792. else
  1793. size:=0;
  1794. end;
  1795. procedure tdynamicarray.reset;
  1796. var
  1797. hp : pdynamicblock;
  1798. begin
  1799. while assigned(FFirstblock) do
  1800. begin
  1801. hp:=FFirstblock;
  1802. FFirstblock:=FFirstblock^.Next;
  1803. Freemem(hp);
  1804. end;
  1805. FPosn:=0;
  1806. FPosnblock:=nil;
  1807. FFirstblock:=nil;
  1808. FLastblock:=nil;
  1809. grow;
  1810. end;
  1811. procedure tdynamicarray.grow;
  1812. var
  1813. nblock : pdynamicblock;
  1814. begin
  1815. Getmem(nblock,blocksize+dynamicblockbasesize);
  1816. if not assigned(FFirstblock) then
  1817. begin
  1818. FFirstblock:=nblock;
  1819. FPosnblock:=nblock;
  1820. nblock^.pos:=0;
  1821. end
  1822. else
  1823. begin
  1824. FLastblock^.Next:=nblock;
  1825. nblock^.pos:=FLastblock^.pos+FLastblock^.used;
  1826. end;
  1827. nblock^.used:=0;
  1828. nblock^.Next:=nil;
  1829. fillchar(nblock^.data,blocksize,0);
  1830. FLastblock:=nblock;
  1831. end;
  1832. procedure tdynamicarray.align(i:integer);
  1833. var
  1834. j : integer;
  1835. begin
  1836. j:=(FPosn mod i);
  1837. if j<>0 then
  1838. begin
  1839. j:=i-j;
  1840. if FPosnblock^.used+j>blocksize then
  1841. begin
  1842. dec(j,blocksize-FPosnblock^.used);
  1843. FPosnblock^.used:=blocksize;
  1844. grow;
  1845. FPosnblock:=FLastblock;
  1846. end;
  1847. inc(FPosnblock^.used,j);
  1848. inc(FPosn,j);
  1849. end;
  1850. end;
  1851. procedure tdynamicarray.seek(i:integer);
  1852. begin
  1853. if (i<FPosnblock^.pos) or (i>=FPosnblock^.pos+blocksize) then
  1854. begin
  1855. { set FPosnblock correct if the size is bigger then
  1856. the current block }
  1857. if FPosnblock^.pos>i then
  1858. FPosnblock:=FFirstblock;
  1859. while assigned(FPosnblock) do
  1860. begin
  1861. if FPosnblock^.pos+blocksize>i then
  1862. break;
  1863. FPosnblock:=FPosnblock^.Next;
  1864. end;
  1865. { not found ? then increase blocks }
  1866. if not assigned(FPosnblock) then
  1867. begin
  1868. repeat
  1869. { the current FLastblock is now also fully used }
  1870. FLastblock^.used:=blocksize;
  1871. grow;
  1872. FPosnblock:=FLastblock;
  1873. until FPosnblock^.pos+blocksize>=i;
  1874. end;
  1875. end;
  1876. FPosn:=i;
  1877. if FPosn mod blocksize>FPosnblock^.used then
  1878. FPosnblock^.used:=FPosn mod blocksize;
  1879. end;
  1880. procedure tdynamicarray.write(const d;len:integer);
  1881. var
  1882. p : pchar;
  1883. i,j : integer;
  1884. begin
  1885. p:=pchar(@d);
  1886. while (len>0) do
  1887. begin
  1888. i:=FPosn mod blocksize;
  1889. if i+len>=blocksize then
  1890. begin
  1891. j:=blocksize-i;
  1892. move(p^,FPosnblock^.data[i],j);
  1893. inc(p,j);
  1894. inc(FPosn,j);
  1895. dec(len,j);
  1896. FPosnblock^.used:=blocksize;
  1897. if assigned(FPosnblock^.Next) then
  1898. FPosnblock:=FPosnblock^.Next
  1899. else
  1900. begin
  1901. grow;
  1902. FPosnblock:=FLastblock;
  1903. end;
  1904. end
  1905. else
  1906. begin
  1907. move(p^,FPosnblock^.data[i],len);
  1908. inc(p,len);
  1909. inc(FPosn,len);
  1910. i:=FPosn mod blocksize;
  1911. if i>FPosnblock^.used then
  1912. FPosnblock^.used:=i;
  1913. len:=0;
  1914. end;
  1915. end;
  1916. end;
  1917. procedure tdynamicarray.writestr(const s:string);
  1918. begin
  1919. write(s[1],length(s));
  1920. end;
  1921. function tdynamicarray.read(var d;len:integer):integer;
  1922. var
  1923. p : pchar;
  1924. i,j,res : integer;
  1925. begin
  1926. res:=0;
  1927. p:=pchar(@d);
  1928. while (len>0) do
  1929. begin
  1930. i:=FPosn mod blocksize;
  1931. if i+len>=FPosnblock^.used then
  1932. begin
  1933. j:=FPosnblock^.used-i;
  1934. move(FPosnblock^.data[i],p^,j);
  1935. inc(p,j);
  1936. inc(FPosn,j);
  1937. inc(res,j);
  1938. dec(len,j);
  1939. if assigned(FPosnblock^.Next) then
  1940. FPosnblock:=FPosnblock^.Next
  1941. else
  1942. break;
  1943. end
  1944. else
  1945. begin
  1946. move(FPosnblock^.data[i],p^,len);
  1947. inc(p,len);
  1948. inc(FPosn,len);
  1949. inc(res,len);
  1950. len:=0;
  1951. end;
  1952. end;
  1953. read:=res;
  1954. end;
  1955. procedure tdynamicarray.readstream(f:TCStream;maxlen:longint);
  1956. var
  1957. i,left : integer;
  1958. begin
  1959. if maxlen=-1 then
  1960. maxlen:=maxlongint;
  1961. repeat
  1962. left:=blocksize-FPosnblock^.used;
  1963. if left>maxlen then
  1964. left:=maxlen;
  1965. i:=f.Read(FPosnblock^.data[FPosnblock^.used],left);
  1966. dec(maxlen,i);
  1967. inc(FPosnblock^.used,i);
  1968. if FPosnblock^.used=blocksize then
  1969. begin
  1970. if assigned(FPosnblock^.Next) then
  1971. FPosnblock:=FPosnblock^.Next
  1972. else
  1973. begin
  1974. grow;
  1975. FPosnblock:=FLastblock;
  1976. end;
  1977. end;
  1978. until (i<left) or (maxlen=0);
  1979. end;
  1980. procedure tdynamicarray.writestream(f:TCStream);
  1981. var
  1982. hp : pdynamicblock;
  1983. begin
  1984. hp:=FFirstblock;
  1985. while assigned(hp) do
  1986. begin
  1987. f.Write(hp^.data,hp^.used);
  1988. hp:=hp^.Next;
  1989. end;
  1990. end;
  1991. end.
  1992. {
  1993. $Log$
  1994. Revision 1.32 2004-05-23 14:31:31 peter
  1995. * count fixes for tlinkedlist
  1996. Revision 1.31 2004/04/28 18:02:54 peter
  1997. * add TList to cclasses, remove classes dependency from t_win32
  1998. Revision 1.30 2004/01/15 15:16:17 daniel
  1999. * Some minor stuff
  2000. * Managed to eliminate speed effects of string compression
  2001. Revision 1.29 2004/01/11 23:56:19 daniel
  2002. * Experiment: Compress strings to save memory
  2003. Did not save a single byte of mem; clearly the core size is boosted by
  2004. temporary memory usage...
  2005. Revision 1.28 2003/10/23 14:44:07 peter
  2006. * splitted buildderef and buildderefimpl to fix interface crc
  2007. calculation
  2008. Revision 1.27 2003/10/22 20:40:00 peter
  2009. * write derefdata in a separate ppu entry
  2010. Revision 1.26 2003/10/11 16:06:42 florian
  2011. * fixed some MMX<->SSE
  2012. * started to fix ppc, needs an overhaul
  2013. + stabs info improve for spilling, not sure if it works correctly/completly
  2014. - MMX_SUPPORT removed from Makefile.fpc
  2015. Revision 1.25 2003/09/29 20:52:50 peter
  2016. * insertbefore added
  2017. Revision 1.24 2003/09/24 13:02:10 marco
  2018. * (Peter) patch to fix snapshot
  2019. Revision 1.23 2003/06/09 12:19:34 peter
  2020. * insertlistafter added
  2021. Revision 1.22 2002/12/15 19:34:31 florian
  2022. + some front end stuff for vs_hidden added
  2023. Revision 1.21 2002/11/24 18:18:39 carl
  2024. - remove some unused defines
  2025. Revision 1.20 2002/10/05 12:43:23 carl
  2026. * fixes for Delphi 6 compilation
  2027. (warning : Some features do not work under Delphi)
  2028. Revision 1.19 2002/09/09 17:34:14 peter
  2029. * tdicationary.replace added to replace and item in a dictionary. This
  2030. is only allowed for the same name
  2031. * varsyms are inserted in symtable before the types are parsed. This
  2032. fixes the long standing "var longint : longint" bug
  2033. - consume_idlist and idstringlist removed. The loops are inserted
  2034. at the callers place and uses the symtable for duplicate id checking
  2035. Revision 1.18 2002/09/05 19:29:42 peter
  2036. * memdebug enhancements
  2037. Revision 1.17 2002/08/11 13:24:11 peter
  2038. * saving of asmsymbols in ppu supported
  2039. * asmsymbollist global is removed and moved into a new class
  2040. tasmlibrarydata that will hold the info of a .a file which
  2041. corresponds with a single module. Added librarydata to tmodule
  2042. to keep the library info stored for the module. In the future the
  2043. objectfiles will also be stored to the tasmlibrarydata class
  2044. * all getlabel/newasmsymbol and friends are moved to the new class
  2045. Revision 1.16 2002/08/09 19:08:53 carl
  2046. + fix incorrect comment in insertlistcopy
  2047. Revision 1.15 2002/07/01 18:46:21 peter
  2048. * internal linker
  2049. * reorganized aasm layer
  2050. Revision 1.14 2002/06/17 13:56:14 jonas
  2051. * tdictionary.rename() returns nil if the original object wasn't found
  2052. (reported by Sergey Korshunoff <[email protected]>)
  2053. Revision 1.13 2002/05/18 13:34:05 peter
  2054. * readded missing revisions
  2055. Revision 1.12 2002/05/16 19:46:35 carl
  2056. + defines.inc -> fpcdefs.inc to avoid conflicts if compiling by hand
  2057. + try to fix temp allocation (still in ifdef)
  2058. + generic constructor calls
  2059. + start of tassembler / tmodulebase class cleanup
  2060. Revision 1.10 2002/05/12 16:53:04 peter
  2061. * moved entry and exitcode to ncgutil and cgobj
  2062. * foreach gets extra argument for passing local data to the
  2063. iterator function
  2064. * -CR checks also class typecasts at runtime by changing them
  2065. into as
  2066. * fixed compiler to cycle with the -CR option
  2067. * fixed stabs with elf writer, finally the global variables can
  2068. be watched
  2069. * removed a lot of routines from cga unit and replaced them by
  2070. calls to cgobj
  2071. * u32bit-s32bit updates for and,or,xor nodes. When one element is
  2072. u32bit then the other is typecasted also to u32bit without giving
  2073. a rangecheck warning/error.
  2074. * fixed pascal calling method with reversing also the high tree in
  2075. the parast, detected by tcalcst3 test
  2076. }