123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857 |
- {
- This file is part of the Free Component Library (FCL)
- Copyright (c) 2002 by Florian Klaempfl
- See the file COPYING.FPC, included in this distribution,
- for details about the copyright.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- **********************************************************************}
- {$mode objfpc}
- unit contnrs;
- interface
- uses
- SysUtils, Classes;
- Type
- TObjectListCallback = Reference to Procedure(data:TObject;arg:JSValue);
- TFPObjectList = class(TObject)
- private
- FFreeObjects : Boolean;
- FList: TFPList;
- Function GetCount: integer;
- Procedure SetCount(const AValue: integer);
- protected
- Function GetItem(Index: Integer): TObject;
- Procedure SetItem(Index: Integer; AObject: TObject);
- Procedure SetCapacity(NewCapacity: Integer);
- Function GetCapacity: integer;
- public
- constructor Create; reintroduce;
- constructor Create(FreeObjects : Boolean);
- destructor Destroy; override;
- Procedure Clear;
- Function Add(AObject: TObject): Integer;
- Procedure Delete(Index: Integer);
- Procedure Exchange(Index1, Index2: Integer);
- Function Expand: TFPObjectList;
- Function Extract(Item: TObject): TObject;
- Function Remove(AObject: TObject): Integer;
- Function IndexOf(AObject: TObject): Integer;
- Function FindInstanceOf(AClass: TClass; AExact: Boolean; AStartAt: Integer): Integer;
- Procedure Insert(Index: Integer; AObject: TObject);
- Function First: TObject;
- Function Last: TObject;
- Procedure Move(CurIndex, NewIndex: Integer);
- Procedure Assign(Obj:TFPObjectList);
- Procedure Pack;
- Procedure Sort(Compare: TListSortCompare);
- Procedure ForEachCall(proc2call:TObjectListCallback;arg:JSValue);
- property Capacity: Integer read GetCapacity write SetCapacity;
- property Count: Integer read GetCount write SetCount;
- property OwnsObjects: Boolean read FFreeObjects write FFreeObjects;
- property Items[Index: Integer]: TObject read GetItem write SetItem; default;
- property List: TFPList read FList;
- end;
- { TObjectList }
- TObjectList = class(TList)
- private
- FFreeObjects : Boolean;
- Protected
- Procedure Notify(Ptr: JSValue; Action: TListNotification); override;
- Function GetItem(Index: Integer): TObject;
- Procedure SetItem(Index: Integer; AObject: TObject);
- public
- constructor Create; reintroduce;
- constructor Create(FreeObjects : boolean);
- Function Add(AObject: TObject): Integer; reintroduce;
- Function Extract(Item: TObject): TObject; reintroduce;
- Function Remove(AObject: TObject): Integer; reintroduce;
- Function IndexOf(AObject: TObject): Integer; reintroduce;
- Function FindInstanceOf(AClass: TClass; AExact: Boolean; AStartAt: Integer): Integer;
- Procedure Insert(Index: Integer; AObject: TObject); reintroduce;
- Function First: TObject; reintroduce;
- Function Last: TObject; reintroduce;
- property OwnsObjects: Boolean read FFreeObjects write FFreeObjects;
- property Items[Index: Integer]: TObject read GetItem write SetItem; default;
- end;
- TComponentList = class(TObjectList)
- Private
- FNotifier : TComponent;
- Protected
- Procedure Notify(Ptr: JSValue; Action: TListNotification); override;
- Function GetItems(Index: Integer): TComponent;
- Procedure SetItems(Index: Integer; AComponent: TComponent);
- Procedure HandleFreeNotify(Sender: TObject; AComponent: TComponent);
- public
- destructor Destroy; override;
- Function Add(AComponent: TComponent): Integer; reintroduce;
- Function Extract(Item: TComponent): TComponent; reintroduce;
- Function Remove(AComponent: TComponent): Integer; reintroduce;
- Function IndexOf(AComponent: TComponent): Integer; reintroduce;
- Function First: TComponent; reintroduce;
- Function Last: TComponent; reintroduce;
- Procedure Insert(Index: Integer; AComponent: TComponent); reintroduce;
- property Items[Index: Integer]: TComponent read GetItems write SetItems; default;
- end;
- TClassList = class(TList)
- protected
- Function GetItems(Index: Integer): TClass;
- Procedure SetItems(Index: Integer; AClass: TClass);
- public
- Function Add(AClass: TClass): Integer; reintroduce;
- Function Extract(Item: TClass): TClass; reintroduce;
- Function Remove(AClass: TClass): Integer; reintroduce;
- Function IndexOf(AClass: TClass): Integer; reintroduce;
- Function First: TClass; reintroduce;
- Function Last: TClass; reintroduce;
- Procedure Insert(Index: Integer; AClass: TClass); reintroduce;
- property Items[Index: Integer]: TClass read GetItems write SetItems; default;
- end;
- TOrderedList = class(TObject)
- private
- FList: TList;
- protected
- Procedure PushItem(AItem: JSValue); virtual; abstract;
- Function PopItem: JSValue; virtual;
- Function PeekItem: JSValue; virtual;
- property List: TList read FList;
- public
- constructor Create; reintroduce;
- destructor Destroy; override;
- Function Count: Integer;
- Function AtLeast(ACount: Integer): Boolean;
- Function Push(AItem: JSValue): JSValue;
- Function Pop: JSValue;
- Function Peek: JSValue;
- end;
- { TStack class }
- TStack = class(TOrderedList)
- protected
- Procedure PushItem(AItem: JSValue); override;
- end;
- { TObjectStack class }
- TObjectStack = class(TStack)
- public
- Function Push(AObject: TObject): TObject; reintroduce;
- Function Pop: TObject; reintroduce;
- Function Peek: TObject; reintroduce;
- end;
- { TQueue class }
- TQueue = class(TOrderedList)
- protected
- Procedure PushItem(AItem: JSValue); override;
- end;
- { TObjectQueue class }
- TObjectQueue = class(TQueue)
- public
- Function Push(AObject: TObject): TObject; reintroduce;
- Function Pop: TObject; reintroduce;
- Function Peek: TObject; reintroduce;
- end;
- { ---------------------------------------------------------------------
- Hash support, implemented by Dean Zobec
- ---------------------------------------------------------------------}
- { Must return a Longword value in the range 0..TableSize,
- usually via a mod operator; }
- THashFunction = Function(const S: string; const TableSize: Longword): Longword;
- { THTNode }
- THTCustomNode = class(TObject)
- private
- FKey: string;
- public
- constructor CreateWith(const AString: String);
- Function HasKey(const AKey: string): boolean;
- property Key: string read FKey;
- end;
- THTCustomNodeClass = Class of THTCustomNode;
- { TFPCustomHashTable }
- TFPCustomHashTable = class(TObject)
- private
- FHashTable: TFPObjectList;
- FHashFunction: THashFunction;
- FCount: Longword;
- Function GetDensity: Longword;
- Function GetNumberOfCollisions: Longword;
- Procedure SetHashTableSize(const Value: Longword);
- Procedure InitializeHashTable;
- Function GetVoidSlots: Longword;
- Function GetLoadFactor: double;
- Function GetAVGChainLen: double;
- Function GetMaxChainLength: Longword;
- protected
- FHashTableSize: Longword;
- Function Chain(const index: Longword):TFPObjectList;
- Function CreateNewNode(const aKey : string) : THTCustomNode; virtual; abstract;
- Procedure AddNode(ANode : THTCustomNode); virtual; abstract;
- Function ChainLength(const ChainIndex: Longword): Longword; virtual;
- Function FindOrCreateNew(const aKey: string): THTCustomNode; virtual;
- Procedure SetHashFunction(AHashFunction: THashFunction); virtual;
- Function FindChainForAdd(Const aKey : String) : TFPObjectList;
- public
- constructor Create; reintroduce;
- constructor CreateWith(AHashTableSize: Longword; aHashFunc: THashFunction);
- destructor Destroy; override;
- Procedure ChangeTableSize(const ANewSize: Longword); virtual;
- Procedure Clear; virtual;
- Procedure Delete(const aKey: string); virtual;
- Function Find(const aKey: string): THTCustomNode;
- Function IsEmpty: boolean;
- property HashFunction: THashFunction read FHashFunction write SetHashFunction;
- property Count: Longword read FCount;
- property HashTableSize: Longword read FHashTableSize write SetHashTableSize;
- property HashTable: TFPObjectList read FHashTable;
- property VoidSlots: Longword read GetVoidSlots;
- property LoadFactor: double read GetLoadFactor;
- property AVGChainLen: double read GetAVGChainLen;
- property MaxChainLength: Longword read GetMaxChainLength;
- property NumberOfCollisions: Longword read GetNumberOfCollisions;
- property Density: Longword read GetDensity;
- end;
- { TFPDataHashTable : Hash table with simple data JSValues }
- THTDataNode = Class(THTCustomNode)
- Private
- FData: JSValue;
- public
- property Data: JSValue read FData write FData;
- end;
- // For compatibility
- THTNode = THTDataNode;
- TDataIteratorMethod = Procedure(Item: JSValue; const Key: string; var Continue: Boolean) of object;
- TDataIteratorCallBack = Procedure(Item: JSValue; const Key: string; var Continue: Boolean);
- // For compatibility
- TIteratorMethod = TDataIteratorMethod;
- TFPDataHashTable = Class(TFPCustomHashTable)
- Private
- FIteratorCallBack: TDataIteratorCallBack;
- Procedure CallbackIterator(Item: JSValue; const Key: string; var Continue: Boolean);
- Protected
- Function CreateNewNode(const aKey : String) : THTCustomNode; override;
- Procedure AddNode(ANode : THTCustomNode); override;
- Procedure SetData(const index: string; const AValue: JSValue); virtual;
- Function GetData(const index: string):JSValue; virtual;
- Function ForEachCall(aMethod: TDataIteratorMethod): THTDataNode; virtual;
- Public
- Function Iterate(aMethod: TDataIteratorMethod): JSValue; virtual;
- Function Iterate(aMethod: TDataIteratorCallBack): JSValue; virtual;
- Procedure Add(const aKey: string; AItem: JSValue); virtual;
- property Items[const index: string]: JSValue read GetData write SetData; default;
- end;
- { TFPStringHashTable : Hash table with simple strings as data }
- THTStringNode = Class(THTCustomNode)
- Private
- FData : String;
- public
- property Data: String read FData write FData;
- end;
-
- TStringIteratorMethod = Procedure(Item: String; const Key: string; var Continue: Boolean) of object;
- TStringIteratorCallback = Procedure(Item: String; const Key: string; var Continue: Boolean);
- TFPStringHashTable = Class(TFPCustomHashTable)
- Private
- FIteratorCallBack: TStringIteratorCallback;
- Procedure CallbackIterator(Item: String; const Key: string; var Continue: Boolean);
- Protected
- Function CreateNewNode(const aKey : String) : THTCustomNode; override;
- Procedure AddNode(ANode : THTCustomNode); override;
- Procedure SetData(const Index, AValue: string); virtual;
- Function GetData(const index: string): String; virtual;
- Function ForEachCall(aMethod: TStringIteratorMethod): THTStringNode; virtual;
- Public
- Function Iterate(aMethod: TStringIteratorMethod): String; virtual;
- Function Iterate(aMethod: TStringIteratorCallback): String; virtual;
- Procedure Add(const aKey,aItem: string); virtual;
- property Items[const index: string]: String read GetData write SetData; default;
- end;
- { TFPStringHashTable : Hash table with simple strings as data }
- THTObjectNode = Class(THTCustomNode)
- Private
- FData : TObject;
- public
- property Data: TObject read FData write FData;
- end;
- THTOwnedObjectNode = Class(THTObjectNode)
- public
- destructor Destroy; override;
- end;
- TObjectIteratorMethod = Procedure(Item: TObject; const Key: string; var Continue: Boolean) of object;
- TObjectIteratorCallback = Procedure(Item: TObject; const Key: string; var Continue: Boolean);
- TFPObjectHashTable = Class(TFPCustomHashTable)
- Private
- FOwnsObjects : Boolean;
- FIteratorCallBack: TObjectIteratorCallback;
- procedure CallbackIterator(Item: TObject; const Key: string; var Continue: Boolean);
- Protected
- Function CreateNewNode(const aKey : String) : THTCustomNode; override;
- Procedure AddNode(ANode : THTCustomNode); override;
- Procedure SetData(const Index: string; AObject : TObject); virtual;
- Function GetData(const index: string): TObject; virtual;
- Function ForEachCall(aMethod: TObjectIteratorMethod): THTObjectNode; virtual;
- Public
- constructor Create(AOwnsObjects : Boolean = True); reintroduce;
- constructor CreateWith(AHashTableSize: Longword; aHashFunc: THashFunction; AOwnsObjects : Boolean = True); reintroduce;
- Function Iterate(aMethod: TObjectIteratorMethod): TObject; virtual;
- Function Iterate(aMethod: TObjectIteratorCallback): TObject; virtual;
- Procedure Add(const aKey: string; AItem : TObject); virtual;
- property Items[const index: string]: TObject read GetData write SetData; default;
- Property OwnsObjects : Boolean Read FOwnsObjects;
- end;
- EDuplicate = class(Exception);
- EKeyNotFound = class(Exception);
- Function RSHash(const S: string; const TableSize: Longword): Longword;
- { ---------------------------------------------------------------------
- Bucket lists as in Delphi
- ---------------------------------------------------------------------}
- Type
- TBucketItem = record
- Item, Data: JSValue;
- end;
- TBucketItemArray = array of TBucketItem;
- TBucket = record
- Count : Integer;
- Items : TBucketItemArray;
- end;
- TBucketArray = array of TBucket;
- TBucketProc = Reference to Procedure(AInfo, AItem, AData: JSValue; out AContinue: Boolean);
- { ---------------------------------------------------------------------
- TCustomBucketList
- ---------------------------------------------------------------------}
- { TCustomBucketList }
- TCustomBucketList = class(TObject)
- private
- FBuckets: TBucketArray;
- Function GetBucketCount: Integer;
- Function GetData(AItem: JSValue): JSValue;
- Procedure SetData(AItem: JSValue; const AData: JSValue);
- Procedure SetBucketCount(const Value: Integer);
- protected
- Procedure GetBucketItem(AItem: JSValue; out ABucket, AIndex: Integer);
- Function AddItem(ABucket: Integer; AItem, AData: JSValue): JSValue; virtual;
- Function BucketFor(AItem: JSValue): Integer; virtual; abstract;
- Function DeleteItem(ABucket: Integer; AIndex: Integer): JSValue; virtual;
- Procedure Error(Msg : String; Args : Array of Const);
- Function FindItem(AItem: JSValue; out ABucket, AIndex: Integer): Boolean; virtual;
- property Buckets: TBucketArray read FBuckets;
- property BucketCount: Integer read GetBucketCount write SetBucketCount;
- public
- destructor Destroy; override;
- Procedure Clear;
- Function Add(AItem, AData: JSValue): JSValue;
- Procedure Assign(AList: TCustomBucketList);
- Function Exists(AItem: JSValue): Boolean;
- Function Find(AItem: JSValue; out AData: JSValue): Boolean;
- Function ForEach(AProc: TBucketProc; AInfo: JSValue): Boolean;
- Function ForEach(AProc: TBucketProc): Boolean;
- Function Remove(AItem: JSValue): JSValue;
- property Data[AItem: JSValue]: JSValue read GetData write SetData; default;
- end;
- { ---------------------------------------------------------------------
- TBucketList
- ---------------------------------------------------------------------}
- TBucketListSizes = (bl2, bl4, bl8, bl16, bl32, bl64, bl128, bl256);
- { TBucketList }
- TBucketList = class(TCustomBucketList)
- private
- FBucketMask: Byte;
- protected
- Function BucketFor(AItem: JSValue): Integer; override;
- public
- constructor Create(ABuckets: TBucketListSizes = bl16); reintroduce;
- end;
- { ---------------------------------------------------------------------
- TObjectBucketList
- ---------------------------------------------------------------------}
- { TObjectBucketList }
- TObjectBucketList = class(TBucketList)
- protected
- Function GetData(AItem: TObject): TObject; reintroduce;
- Procedure SetData(AItem: TObject; const AData: TObject); reintroduce;
- public
- Function Add(AItem, AData: TObject): TObject; reintroduce;
- Function Remove(AItem: TObject): TObject; reintroduce;
- property Data[AItem: TObject]: TObject read GetData write SetData; default;
- end;
- implementation
- uses
- js;
- ResourceString
- DuplicateMsg = 'An item with key %0:s already exists';
- //KeyNotFoundMsg = 'Method: %0:s key [''%1:s''] not found in container';
- NotEmptyMsg = 'Hash table not empty.';
- SErrNoSuchItem = 'No item in list for %p';
- SDuplicateItem = 'Item already exists in list: %p';
- const
- NPRIMES = 28;
- PRIMELIST: array[0 .. NPRIMES-1] of Longword =
- ( 53, 97, 193, 389, 769,
- 1543, 3079, 6151, 12289, 24593,
- 49157, 98317, 196613, 393241, 786433,
- 1572869, 3145739, 6291469, 12582917, 25165843,
- 50331653, 100663319, 201326611, 402653189, 805306457,
- 1610612741, 3221225473, 4294967291 );
- constructor TFPObjectList.Create(FreeObjects : boolean);
- begin
- Create;
- FFreeObjects:=Freeobjects;
- end;
- destructor TFPObjectList.Destroy;
- begin
- if (FList <> nil) then
- begin
- Clear;
- FList.Destroy;
- end;
- inherited Destroy;
- end;
- Procedure TFPObjectList.Clear;
- var
- i: integer;
- O : TObject;
- begin
- if FFreeObjects then
- for i:=FList.Count-1 downto 0 do
- begin
- O:=TObject(FList[i]);
- FList[i]:=Nil;
- O.Free;
- end;
- FList.Clear;
- end;
- constructor TFPObjectList.Create;
- begin
- inherited Create;
- FList:=TFPList.Create;
- FFreeObjects:=True;
- end;
- Function TFPObjectList.GetCount: integer;
- begin
- Result:=FList.Count;
- end;
- Procedure TFPObjectList.SetCount(const AValue: integer);
- begin
- if FList.Count <> AValue then
- FList.Count:=AValue;
- end;
- Function TFPObjectList.GetItem(Index: Integer): TObject;
- begin
- Result:=TObject(FList[Index]);
- end;
- Procedure TFPObjectList.SetItem(Index: Integer; AObject: TObject);
- Var
- O : TObject;
- begin
- if OwnsObjects then
- begin
- O:=TObject(FList[Index]);
- FList[Index]:=AObject;
- O.Free;
- end
- else
- FList[index]:=AObject;
- end;
- Procedure TFPObjectList.SetCapacity(NewCapacity: Integer);
- begin
- FList.Capacity:=NewCapacity;
- end;
- Function TFPObjectList.GetCapacity: integer;
- begin
- Result:=FList.Capacity;
- end;
- Function TFPObjectList.Add(AObject: TObject): Integer;
- begin
- Result:=FList.Add(AObject);
- end;
- Procedure TFPObjectList.Delete(Index: Integer);
- Var
- O : TObject;
- begin
- if OwnsObjects then
- begin
- O:=TObject(FList[Index]);
- FList[Index]:=Nil;
- O.Free;
- end;
- FList.Delete(Index);
- end;
- Procedure TFPObjectList.Exchange(Index1, Index2: Integer);
- begin
- FList.Exchange(Index1, Index2);
- end;
- Function TFPObjectList.Expand: TFPObjectList;
- begin
- FList.Expand;
- Result:=Self;
- end;
- Function TFPObjectList.Extract(Item: TObject): TObject;
- begin
- Result:=TObject(FList.Extract(Item));
- end;
- Function TFPObjectList.Remove(AObject: TObject): Integer;
- Var
- O : TObject;
- begin
- Result:=IndexOf(AObject);
- if (Result <> -1) then
- begin
- if OwnsObjects then
- begin
- O:=TObject(FList[Result]);
- FList[Result]:=Nil;
- O.Free;
- end;
- FList.Delete(Result);
- end;
- end;
- Function TFPObjectList.IndexOf(AObject: TObject): Integer;
- begin
- Result:=FList.IndexOf(JSValue(AObject));
- end;
- Function TFPObjectList.FindInstanceOf(AClass: TClass; AExact: Boolean; AStartAt : Integer): Integer;
- var
- I : Integer;
- begin
- I:=AStartAt;
- Result:=-1;
- if AExact then
- while (I<Count) and (Result=-1) do
- if Items[i].ClassType=AClass then
- Result:=I
- else
- Inc(I)
- else
- while (I<Count) and (Result=-1) do
- if Items[i].InheritsFrom(AClass) then
- Result:=I
- else
- Inc(I);
- end;
- Procedure TFPObjectList.Insert(Index: Integer; AObject: TObject);
- begin
- FList.Insert(Index, JSValue(AObject));
- end;
- Procedure TFPObjectList.Move(CurIndex, NewIndex: Integer);
- begin
- FList.Move(CurIndex, NewIndex);
- end;
- Procedure TFPObjectList.Assign(Obj: TFPObjectList);
- var
- i: Integer;
- begin
- Clear;
- for i:=0 to Obj.Count - 1 do
- Add(Obj[i]);
- end;
- Procedure TFPObjectList.Pack;
- begin
- FList.Pack;
- end;
- Procedure TFPObjectList.Sort(Compare: TListSortCompare);
- begin
- FList.Sort(Compare);
- end;
- Function TFPObjectList.First: TObject;
- begin
- Result:=TObject(FList.First);
- end;
- Function TFPObjectList.Last: TObject;
- begin
- Result:=TObject(FList.Last);
- end;
- Procedure TFPObjectList.ForEachCall(proc2call:TObjectListCallback;arg:JSValue);
- begin
- FList.ForEachCall(TListCallBack(proc2call),arg);
- end;
- { TObjectList }
- constructor TObjectList.Create(FreeObjects: boolean);
- begin
- inherited Create;
- FFreeObjects:=FreeObjects;
- end;
- constructor TObjectList.Create;
- begin
- inherited Create;
- FFreeObjects:=True;
- end;
- Procedure TObjectList.Notify(Ptr: JSValue; Action: TListNotification);
- Var
- O : TObject;
- begin
- if FFreeObjects then
- if (Action=lnDeleted) then
- begin
- O:=TObject(Ptr);
- O.Free;
- end;
- inherited Notify(Ptr,Action);
- end;
- Function TObjectList.GetItem(Index: Integer): TObject;
- begin
- Result:=TObject(inherited Get(Index));
- end;
- Procedure TObjectList.SetItem(Index: Integer; AObject: TObject);
- begin
- // Put will take care of deleting old one in Notify.
- Put(Index,JSValue(AObject));
- end;
- Function TObjectList.Add(AObject: TObject): Integer;
- begin
- Result:=inherited Add(JSValue(AObject));
- end;
- Function TObjectList.Extract(Item: TObject): TObject;
- begin
- Result:=TObject(inherited Extract(JSValue(Item)));
- end;
- Function TObjectList.Remove(AObject: TObject): Integer;
- begin
- Result:=inherited Remove(JSValue(AObject));
- end;
- Function TObjectList.IndexOf(AObject: TObject): Integer;
- begin
- Result:=inherited IndexOf(JSValue(AObject));
- end;
- Function TObjectList.FindInstanceOf(AClass: TClass; AExact: Boolean;
- AStartAt: Integer): Integer;
- var
- I : Integer;
- begin
- I:=AStartAt;
- Result:=-1;
- if AExact then
- while (I<Count) and (Result=-1) do
- if Items[i].ClassType=AClass then
- Result:=I
- else
- Inc(I)
- else
- while (I<Count) and (Result=-1) do
- if Items[i].InheritsFrom(AClass) then
- Result:=I
- else
- Inc(I);
- end;
- Procedure TObjectList.Insert(Index: Integer; AObject: TObject);
- begin
- Inherited Insert(Index,JSValue(AObject));
- end;
- Function TObjectList.First: TObject;
- begin
- Result:=TObject(inherited First);
- end;
- Function TObjectList.Last: TObject;
- begin
- Result:=TObject(inherited Last);
- end;
- { TListComponent }
- type
- TlistComponent = class(TComponent)
- private
- Flist : TComponentList;
- public
- Procedure Notification(AComponent: TComponent; Operation: TOperation); override;
- end;
- Procedure TlistComponent.Notification(AComponent: TComponent;
- Operation: TOperation);
- begin
- if (Operation=opRemove) then
- Flist.HandleFreeNotify(Self,AComponent);
- inherited;
- end;
- { TComponentList }
- Function TComponentList.Add(AComponent: TComponent): Integer;
- begin
- Result:=inherited Add(AComponent);
- end;
- destructor TComponentList.Destroy;
- begin
- inherited;
- FreeAndNil(FNotifier);
- end;
- Function TComponentList.Extract(Item: TComponent): TComponent;
- begin
- Result:=TComponent(inherited Extract(Item));
- end;
- Function TComponentList.First: TComponent;
- begin
- Result:=TComponent(inherited First);
- end;
- Function TComponentList.GetItems(Index: Integer): TComponent;
- begin
- Result:=TComponent(inherited Items[Index]);
- end;
- Procedure TComponentList.HandleFreeNotify(Sender: TObject;
- AComponent: TComponent);
- begin
- Extract(AComponent);
- if Sender=nil then ;
- end;
- Function TComponentList.IndexOf(AComponent: TComponent): Integer;
- begin
- Result:=inherited IndexOf(AComponent);
- end;
- Procedure TComponentList.Insert(Index: Integer; AComponent: TComponent);
- begin
- inherited Insert(Index,AComponent)
- end;
- Function TComponentList.Last: TComponent;
- begin
- Result:=TComponent(inherited Last);
- end;
- Procedure TComponentList.Notify(Ptr: JSValue; Action: TListNotification);
- begin
- if FNotifier=nil then
- begin
- FNotifier:=TlistComponent.Create(nil);
- TlistComponent(FNotifier).FList:=Self;
- end;
- if Assigned(Ptr) then
- with TComponent(Ptr) do
- case Action of
- lnAdded : FreeNotification(FNotifier);
- lnExtracted, lnDeleted: RemoveFreeNotification(FNotifier);
- end;
- inherited Notify(Ptr, Action);
- end;
- Function TComponentList.Remove(AComponent: TComponent): Integer;
- begin
- Result:=inherited Remove(AComponent);
- end;
- Procedure TComponentList.SetItems(Index: Integer; AComponent: TComponent);
- begin
- Put(Index,AComponent);
- end;
- { TClassList }
- Function TClassList.Add(AClass: TClass): Integer;
- begin
- Result:=inherited Add(JSValue(AClass));
- end;
- Function TClassList.Extract(Item: TClass): TClass;
- begin
- Result:=TClass(inherited Extract(JSValue(Item)));
- end;
- Function TClassList.First: TClass;
- begin
- Result:=TClass(inherited First);
- end;
- Function TClassList.GetItems(Index: Integer): TClass;
- begin
- Result:=TClass(inherited Items[Index]);
- end;
- Function TClassList.IndexOf(AClass: TClass): Integer;
- begin
- Result:=inherited IndexOf(JSValue(AClass));
- end;
- Procedure TClassList.Insert(Index: Integer; AClass: TClass);
- begin
- inherited Insert(Index,JSValue(AClass));
- end;
- Function TClassList.Last: TClass;
- begin
- Result:=TClass(inherited Last);
- end;
- Function TClassList.Remove(AClass: TClass): Integer;
- begin
- Result:=inherited Remove(JSValue(AClass));
- end;
- Procedure TClassList.SetItems(Index: Integer; AClass: TClass);
- begin
- Put(Index,JSValue(AClass));
- end;
- { TOrderedList }
- Function TOrderedList.AtLeast(ACount: Integer): Boolean;
- begin
- Result:=(FList.Count>=Acount)
- end;
- Function TOrderedList.Count: Integer;
- begin
- Result:=FList.Count;
- end;
- constructor TOrderedList.Create;
- begin
- FList:=Tlist.Create;
- end;
- destructor TOrderedList.Destroy;
- begin
- FList.Free;
- end;
- Function TOrderedList.Peek: JSValue;
- begin
- if AtLeast(1) then
- Result:=PeekItem
- else
- Result:=nil;
- end;
- Function TOrderedList.PeekItem: JSValue;
- begin
- with Flist do
- Result:=Items[Count-1]
- end;
- Function TOrderedList.Pop: JSValue;
- begin
- If Atleast(1) then
- Result:=PopItem
- else
- Result:=nil;
- end;
- Function TOrderedList.PopItem: JSValue;
- begin
- with FList do
- if Count>0 then
- begin
- Result:=Items[Count-1];
- Delete(Count-1);
- end
- else
- Result:=nil;
- end;
- Function TOrderedList.Push(AItem: JSValue): JSValue;
- begin
- PushItem(AItem);
- Result:=AItem;
- end;
- { TStack }
- Procedure TStack.PushItem(AItem: JSValue);
- begin
- FList.Add(AItem);
- end;
- { TObjectStack }
- Function TObjectStack.Peek: TObject;
- begin
- Result:=TObject(inherited Peek);
- end;
- Function TObjectStack.Pop: TObject;
- begin
- Result:=TObject(Inherited Pop);
- end;
- Function TObjectStack.Push(AObject: TObject): TObject;
- begin
- Result:=TObject(inherited Push(JSValue(AObject)));
- end;
- { TQueue }
- Procedure TQueue.PushItem(AItem: JSValue);
- begin
- with FList Do
- Insert(0,AItem);
- end;
- { TObjectQueue }
- Function TObjectQueue.Peek: TObject;
- begin
- Result:=TObject(inherited Peek);
- end;
- Function TObjectQueue.Pop: TObject;
- begin
- Result:=TObject(inherited Pop);
- end;
- Function TObjectQueue.Push(AObject: TObject): TObject;
- begin
- Result:=TObject(inherited Push(JSValue(AObject)));
- end;
- {*****************************************************************************
- TFPHashList
- *****************************************************************************}
- (*
- Function FPHash(const s:shortstring):LongWord;
- var
- p,pmax : PChar;
- begin
- {$push}
- {$Q-}
- Result:=0;
- p:=@s[1];
- pmax:=@s[length(s)+1];
- while (p<pmax) do
- begin
- Result:=LongWord(LongInt(Result shl 5) - LongInt(Result)) xor LongWord(P^);
- Inc(p);
- end;
- {$pop}
- end;
- Function FPHash(P: PChar; Len: Integer): LongWord;
- var
- pmax : PChar;
- begin
- {$push}
- {$Q-}
- Result:=0;
- pmax:=p+len;
- while (p<pmax) do
- begin
- Result:=LongWord(LongInt(Result shl 5) - LongInt(Result)) xor LongWord(P^);
- Inc(p);
- end;
- {$pop}
- end;
- *)
- { ---------------------------------------------------------------------
- Hash support, by Dean Zobec
- ---------------------------------------------------------------------}
- { Default hash Function }
- Function RSHash(const S: string; const TableSize: Longword): Longword;
- const
- b = 378551;
- var
- a: Longword;
- i: Longword;
- begin
- a:=63689;
- Result:=0;
- if length(s)>0 then
- for i:=1 to Length(S) do
- begin
- Result:=Result * a + Ord(S[i]);
- a:=a * b;
- end;
- Result:=(Result and $7FFFFFFF) mod TableSize;
- end;
- { THTNode }
- constructor THTCustomNode.CreateWith(const AString: string);
- begin
- inherited Create;
- FKey:=AString;
- end;
- Function THTCustomNode.HasKey(const AKey: string): boolean;
- begin
- Result:=(AKey=FKey);
- end;
- { TFPCustomHashTable }
- constructor TFPCustomHashTable.Create;
- begin
- CreateWith(196613,@RSHash);
- end;
- constructor TFPCustomHashTable.CreateWith(AHashTableSize: Longword;
- aHashFunc: THashFunction);
- begin
- inherited Create;
- FHashTable:=TFPObjectList.Create(True);
- HashTableSize:=AHashTableSize;
- FHashFunction:=aHashFunc;
- end;
- destructor TFPCustomHashTable.Destroy;
- begin
- FHashTable.Free;
- inherited Destroy;
- end;
- Function TFPCustomHashTable.GetDensity: Longword;
- begin
- Result:=FHashTableSize - VoidSlots
- end;
- Function TFPCustomHashTable.GetNumberOfCollisions: Longword;
- begin
- Result:=FCount -(FHashTableSize - VoidSlots)
- end;
- Procedure TFPCustomHashTable.SetHashTableSize(const Value: Longword);
- var
- i: Longword;
- newSize: Longword;
- begin
- if Value <> FHashTableSize then
- begin
- i:=0;
- while (PRIMELIST[i] < Value) and (i < 27) do
- Inc(i);
- newSize:=PRIMELIST[i];
- if Count = 0 then
- begin
- FHashTableSize:=newSize;
- InitializeHashTable;
- end
- else
- ChangeTableSize(newSize);
- end;
- end;
- Procedure TFPCustomHashTable.InitializeHashTable;
- var
- i: LongWord;
- begin
- if FHashTableSize>0 Then
- for i:=0 to FHashTableSize-1 do
- FHashTable.Add(nil);
- FCount:=0;
- end;
- Procedure TFPCustomHashTable.ChangeTableSize(const ANewSize: Longword);
- var
- SavedTable, List: TFPObjectList;
- SavedTableSize: Longword;
- i, j: Longword;
- temp: THTCustomNode;
- begin
- SavedTable:=FHashTable;
- SavedTableSize:=FHashTableSize;
- FHashTableSize:=ANewSize;
- FHashTable:=TFPObjectList.Create(True);
- InitializeHashTable;
- if SavedTableSize>0 Then
- for i:=0 to SavedTableSize-1 do
- begin
- List:=TFPObjectList(SavedTable[i]);
- if Assigned(List) then
- for j:=0 to List.Count -1 do
- begin
- temp:=THTCustomNode(List[j]);
- AddNode(temp);
- end;
- end;
- SavedTable.Free;
- end;
- Procedure TFPCustomHashTable.SetHashFunction(AHashFunction: THashFunction);
- begin
- if IsEmpty then
- FHashFunction:=AHashFunction
- else
- raise Exception.Create(NotEmptyMsg);
- end;
- Function TFPCustomHashTable.Find(const aKey: string): THTCustomNode;
- var
- hashCode: Longword;
- chn: TFPObjectList;
- i: Longword;
- begin
- hashCode:=FHashFunction(aKey, FHashTableSize);
- chn:=Chain(hashCode);
- if Assigned(chn) then
- if chn.count>0 then
- for i:=0 to chn.Count - 1 do
- if THTCustomNode(chn[i]).Key=aKey then
- Exit(THTCustomNode(chn[i]));
- Result:=nil;
- end;
- Function TFPCustomHashTable.FindChainForAdd(Const aKey : String) : TFPObjectList;
- var
- hashCode: Longword;
- i: Longword;
- begin
- hashCode:=FHashFunction(aKey, FHashTableSize);
- Result:=Chain(hashCode);
- if Assigned(Result) then
- begin
- if Result.count>0 then
- for i:=0 to Result.Count - 1 do
- if (THTCustomNode(Result[i]).Key=aKey) then
- raise EDuplicate.CreateFmt(DuplicateMsg, [aKey]);
- end
- else
- begin
- FHashTable[hashcode]:=TFPObjectList.Create(True);
- Result:=Chain(hashCode);
- end;
- Inc(FCount);
- end;
- Procedure TFPCustomHashTable.Delete(const aKey: string);
- var
- hashCode: Longword;
- chn: TFPObjectList;
- i: Longword;
- begin
- hashCode:=FHashFunction(aKey, FHashTableSize);
- chn:=Chain(hashCode);
- if Assigned(chn) then
- if chn.count>0 then
- for i:=0 to chn.Count - 1 do
- if THTCustomNode(chn[i]).Key=aKey then
- begin
- chn.Delete(i);
- dec(FCount);
- Exit;
- end;
- end;
- Function TFPCustomHashTable.IsEmpty: boolean;
- begin
- Result:=(FCount = 0);
- end;
- Function TFPCustomHashTable.Chain(const index: Longword): TFPObjectList;
- begin
- Result:=TFPObjectList(FHashTable[index]);
- end;
- Function TFPCustomHashTable.GetVoidSlots: Longword;
- var
- i: Longword;
- num: Longword;
- begin
- num:=0;
- if FHashTableSize>0 then
- for i:= 0 to FHashTableSize-1 do
- if not Assigned(Chain(i)) then
- Inc(num);
- Result:=num;
- end;
- Function TFPCustomHashTable.GetLoadFactor: double;
- begin
- Result:=Count / FHashTableSize;
- end;
- Function TFPCustomHashTable.GetAVGChainLen: double;
- begin
- Result:=Count / (FHashTableSize - VoidSlots);
- end;
- Function TFPCustomHashTable.GetMaxChainLength: Longword;
- var
- i: Longword;
- begin
- Result:=0;
- if FHashTableSize>0 Then
- for i:=0 to FHashTableSize-1 do
- if ChainLength(i) > Result then
- Result:=ChainLength(i);
- end;
- Function TFPCustomHashTable.FindOrCreateNew(const aKey: string): THTCustomNode;
- var
- hashCode: Longword;
- chn: TFPObjectList;
- i: Longword;
- begin
- hashCode:=FHashFunction(aKey, FHashTableSize);
- chn:=Chain(hashCode);
- if Assigned(chn) then
- begin
- if chn.count>0 then
- for i:=0 to chn.Count - 1 do
- if (THTCustomNode(chn[i]).Key=aKey) then
- Exit(THTNode(chn[i]));
- end
- else
- begin
- FHashTable[hashcode]:=TFPObjectList.Create(true);
- chn:=Chain(hashcode);
- end;
- Inc(FCount);
- Result:=CreateNewNode(aKey);
- chn.Add(Result);
- end;
- Function TFPCustomHashTable.ChainLength(const ChainIndex: Longword): Longword;
- begin
- if Assigned(Chain(ChainIndex)) then
- Result:=Chain(ChainIndex).Count
- else
- Result:=0;
- end;
- Procedure TFPCustomHashTable.Clear;
- var
- i: Longword;
- begin
- if FHashTableSize>0 then
- for i:=0 to FHashTableSize - 1 do
- if Assigned(Chain(i)) then
- Chain(i).Clear;
- FCount:=0;
- end;
- { TFPDataHashTable }
- Procedure TFPDataHashTable.Add(const aKey: string; aItem: JSValue);
- var
- chn: TFPObjectList;
- NewNode: THtDataNode;
- begin
- chn:=FindChainForAdd(akey);
- NewNode:=THtDataNode(CreateNewNode(aKey));
- NewNode.Data:=aItem;
- chn.Add(NewNode);
- end;
- Function TFPDataHashTable.GetData(const Index: string): JSValue;
- var
- node: THTDataNode;
- begin
- node:=THTDataNode(Find(Index));
- if Assigned(node) then
- Result:=node.Data
- else
- Result:=nil;
- end;
- Procedure TFPDataHashTable.SetData(const index: string; const AValue: JSValue);
- begin
- THTDataNode(FindOrCreateNew(index)).Data:=AValue;
- end;
- Function TFPDataHashTable.CreateNewNode(const aKey : string) : THTCustomNode;
- begin
- Result:=THTDataNode.CreateWith(aKey);
- end;
- Function TFPDataHashTable.Iterate(aMethod: TDataIteratorMethod): JSValue;
- var
- N : THTDataNode;
- begin
- N:=ForEachCall(AMethod);
- if Assigned(N) then
- Result:=N.Data
- else
- Result:=nil;
- end;
- Procedure TFPDataHashTable.CallbackIterator(Item: JSValue; const Key: string; var Continue: Boolean);
- begin
- FIteratorCallBack(Item, Key, Continue);
- end;
- Function TFPDataHashTable.Iterate(aMethod: TDataIteratorCallBack): JSValue;
- begin
- FIteratorCallBack := aMethod;
- Result := Iterate(@CallbackIterator);
- end;
- Function TFPDataHashTable.ForEachCall(aMethod: TDataIteratorMethod): THTDataNode;
- var
- i, j: Longword;
- continue: Boolean;
- begin
- Result:=nil;
- continue:=true;
- if FHashTableSize>0 then
- for i:=0 to FHashTableSize-1 do
- if Assigned(Chain(i)) then
- if chain(i).count>0 then
- for j:=0 to Chain(i).Count-1 do
- begin
- aMethod(THTDataNode(Chain(i)[j]).Data, THTDataNode(Chain(i)[j]).Key, continue);
- if not continue then
- begin
- Result:=THTDataNode(Chain(i)[j]);
- Exit;
- end;
- end;
- end;
- Procedure TFPDataHashTable.AddNode(ANode : THTCustomNode);
- begin
- with THTDataNode(ANode) do
- Add(Key,Data);
- end;
- { TFPStringHashTable }
- Procedure TFPStringHashTable.AddNode(ANode : THTCustomNode);
- begin
- with THTStringNode(ANode) do
- Add(Key,Data);
- end;
- Function TFPStringHashTable.GetData(const Index: string): String;
- var
- node: THTStringNode;
- begin
- node:=THTStringNode(Find(Index));
- if Assigned(node) then
- Result:=node.Data
- else
- Result:='';
- end;
- Procedure TFPStringHashTable.SetData(const index, AValue: string);
- begin
- THTStringNode(FindOrCreateNew(index)).Data:=AValue;
- end;
- Procedure TFPStringHashTable.Add(const aKey, aItem: string);
- var
- chn: TFPObjectList;
- NewNode: THtStringNode;
- begin
- chn:=FindChainForAdd(akey);
- NewNode:=THtStringNode(CreateNewNode(aKey));
- NewNode.Data:=aItem;
- chn.Add(NewNode);
- end;
- Function TFPStringHashTable.CreateNewNode(const aKey : string) : THTCustomNode;
- begin
- Result:=THTStringNode.CreateWith(aKey);
- end;
- Function TFPStringHashTable.Iterate(aMethod: TStringIteratorMethod): String;
- var
- N : THTStringNode;
- begin
- N:=ForEachCall(AMethod);
- if Assigned(N) then
- Result:=N.Data
- else
- Result:='';
- end;
- Procedure TFPStringHashTable.CallbackIterator(Item: String; const Key: string; var Continue: Boolean);
- begin
- FIteratorCallBack(Item, Key, Continue);
- end;
- Function TFPStringHashTable.Iterate(aMethod: TStringIteratorCallback): String;
- begin
- FIteratorCallBack := aMethod;
- Result := Iterate(@CallbackIterator);
- end;
- Function TFPStringHashTable.ForEachCall(aMethod: TStringIteratorMethod): THTStringNode;
- var
- i, j: Longword;
- continue: boolean;
- begin
- Result:=nil;
- continue:=True;
- if FHashTableSize>0 then
- for i:=0 to FHashTableSize-1 do
- if Assigned(Chain(i)) then
- if chain(i).Count>0 then
- for j:=0 to Chain(i).Count-1 do
- begin
- aMethod(THTStringNode(Chain(i)[j]).Data, THTStringNode(Chain(i)[j]).Key, continue);
- if not continue then
- begin
- Result:=THTStringNode(Chain(i)[j]);
- Exit;
- end;
- end;
- end;
- { TFPObjectHashTable }
- Procedure TFPObjectHashTable.AddNode(ANode : THTCustomNode);
- begin
- With THTObjectNode(ANode) do
- Add(Key,Data);
- end;
- Function TFPObjectHashTable.GetData(const Index: string): TObject;
- var
- node: THTObjectNode;
- begin
- node:=THTObjectNode(Find(Index));
- if Assigned(node) then
- Result:=node.Data
- else
- Result:=nil;
- end;
- Procedure TFPObjectHashTable.SetData(const index : string; AObject : TObject);
- begin
- THTObjectNode(FindOrCreateNew(index)).Data:=AObject;
- end;
- Procedure TFPObjectHashTable.Add(const aKey: string; AItem : TObject);
- var
- chn: TFPObjectList;
- NewNode: THTObjectNode;
- begin
- chn:=FindChainForAdd(akey);
- NewNode:=THTObjectNode(CreateNewNode(aKey));
- NewNode.Data:=aItem;
- chn.Add(NewNode);
- end;
- Function TFPObjectHashTable.CreateNewNode(const aKey : string) : THTCustomNode;
- begin
- if OwnsObjects then
- Result:=THTOwnedObjectNode.CreateWith(aKey)
- else
- Result:=THTObjectNode.CreateWith(aKey);
- end;
- Function TFPObjectHashTable.Iterate(aMethod: TObjectIteratorMethod): TObject;
- var
- N : THTObjectNode;
- begin
- N:=ForEachCall(AMethod);
- if Assigned(N) then
- Result:=N.Data
- else
- Result:=nil;
- end;
- Procedure TFPObjectHashTable.CallbackIterator(Item: TObject; const Key: string; var Continue: Boolean);
- begin
- FIteratorCallBack(Item, Key, Continue);
- end;
- Function TFPObjectHashTable.Iterate(aMethod: TObjectIteratorCallback): TObject;
- begin
- FIteratorCallBack := aMethod;
- Result := Iterate(@CallbackIterator);
- end;
- Function TFPObjectHashTable.ForEachCall(aMethod: TObjectIteratorMethod): THTObjectNode;
- var
- i, j: Longword;
- continue: boolean;
- begin
- Result:=nil;
- continue:=true;
- if FHashTableSize>0 then
- for i:=0 to FHashTableSize-1 do
- if Assigned(Chain(i)) then
- if Chain(i).Count>0 then
- for j:=0 to Chain(i).Count-1 do
- begin
- aMethod(THTObjectNode(Chain(i)[j]).Data, THTObjectNode(Chain(i)[j]).Key, continue);
- if not continue then
- begin
- Result:=THTObjectNode(Chain(i)[j]);
- Exit;
- end;
- end;
- end;
- constructor TFPObjectHashTable.Create(AOwnsObjects : Boolean = True);
- begin
- inherited Create;
- FOwnsObjects:=AOwnsObjects;
- end;
- constructor TFPObjectHashTable.CreateWith(AHashTableSize: Longword; aHashFunc: THashFunction; AOwnsObjects : Boolean = True);
- begin
- inherited CreateWith(AHashTableSize,AHashFunc);
- FOwnsObjects:=AOwnsObjects;
- end;
- destructor THTOwnedObjectNode.Destroy;
- begin
- FreeAndNil(FData);
- inherited;
- end;
- { TCustomBucketList }
- Function TCustomBucketList.GetData(AItem: JSValue): JSValue;
- var
- B,I : Integer;
- begin
- GetBucketItem(AItem,B,I);
- Result:=FBuckets[B].Items[I].Data;
- end;
- Function TCustomBucketList.GetBucketCount: Integer;
- begin
- Result:=Length(FBuckets);
- end;
- Procedure TCustomBucketList.SetData(AItem: JSValue; const AData: JSValue);
- var
- B,I : Integer;
- begin
- GetBucketItem(AItem,B,I);
- FBuckets[B].Items[I].Data:=AData;
- end;
- Procedure TCustomBucketList.SetBucketCount(const Value: Integer);
- begin
- if (Value<>GetBucketCount) then
- SetLength(FBuckets,Value);
- end;
- Procedure TCustomBucketList.GetBucketItem(AItem: JSValue; out ABucket,
- AIndex: Integer);
- begin
- if not FindItem(AItem,ABucket,AIndex) then
- Error(SErrNoSuchItem,[AItem]);
- end;
- Function TCustomBucketList.AddItem(ABucket: Integer; AItem, AData: JSValue
- ): JSValue;
- var
- L : Integer;
- begin
- L:=Length(FBuckets[ABucket].Items);
- if (FBuckets[ABucket].Count=L) then
- begin
- if L<8 then
- L:=8
- else
- L:=L+L div 2;
- SetLength(FBuckets[ABucket].Items,L);
- end;
- with FBuckets[ABucket] do
- begin
- Items[Count].Item:=AItem;
- Items[Count].Data:=AData;
- Result:=AData;
- Inc(Count);
- end;
- end;
- Function TCustomBucketList.DeleteItem(ABucket: Integer; AIndex: Integer): JSValue;
- var
- I,L : Integer;
- begin
- Result:=FBuckets[ABucket].Items[AIndex].Data;
- if FBuckets[ABucket].Count=1 then
- SetLength(FBuckets[ABucket].Items,0)
- else
- begin
- L:=(FBuckets[ABucket].Count-AIndex-1);// No point in moving if last one...
- For I:=0 to L-1 do
- FBuckets[ABucket].Items[AIndex+I]:=FBuckets[ABucket].Items[AIndex+I+1];
- end;
- Dec(FBuckets[ABucket].Count);
- end;
- Procedure TCustomBucketList.Error(Msg: String; Args: array of Const);
- begin
- raise ElistError.CreateFmt(Msg,Args);
- end;
- Function TCustomBucketList.FindItem(AItem: JSValue; out ABucket, AIndex: Integer
- ): Boolean;
- var
- I : Integer;
- B : TBucket;
- begin
- ABucket:=BucketFor(AItem);
- B:=FBuckets[ABucket];
- I:=B.Count-1;
- while (I>=0) and (B.Items[I].Item<>AItem) do
- Dec(I);
- Result:=I>=0;
- if Result then
- AIndex:=I;
- end;
- destructor TCustomBucketList.Destroy;
- begin
- Clear;
- inherited Destroy;
- end;
- Procedure TCustomBucketList.Clear;
- var
- B : TBucket;
- I,J : Integer;
- begin
- for I:=0 to Length(FBuckets)-1 do
- begin
- B:=FBuckets[I];
- for J:=B.Count-1 downto 0 do
- DeleteItem(I,J);
- end;
- SetLength(FBuckets,0);
- end;
- Function TCustomBucketList.Add(AItem, AData: JSValue): JSValue;
- var
- B,I : Integer;
- begin
- if FindItem(AItem,B,I) then
- Error(SDuplicateItem,[AItem]);
- Result:=AddItem(B,AItem,AData);
- end;
- Procedure TCustomBucketList.Assign(AList: TCustomBucketList);
- var
- I,J : Integer;
- begin
- Clear;
- SetLength(FBuckets,Length(Alist.FBuckets));
- for I:=0 to BucketCount-1 do
- begin
- SetLength(FBuckets[i].Items,Length(AList.Fbuckets[I].Items));
- for J:=0 to AList.Fbuckets[I].Count-1 do
- with AList.Fbuckets[I].Items[J] do
- AddItem(I,Item,Data);
- end;
- end;
- Function TCustomBucketList.Exists(AItem: JSValue): Boolean;
- var
- B,I : Integer;
- begin
- Result:=FindItem(AItem,B,I);
- end;
- Function TCustomBucketList.Find(AItem: JSValue; out AData: JSValue): Boolean;
- var
- B,I : integer;
- begin
- Result:=FindItem(AItem,B,I);
- if Result then
- AData:=FBuckets[B].Items[I].Data;
- end;
- Function TCustomBucketList.ForEach(AProc: TBucketProc): Boolean;
- begin
- Result:=Foreach(aProc,Null);
- end;
- Function TCustomBucketList.ForEach(AProc: TBucketProc; AInfo: JSValue): Boolean;
- var
- I,J,S : Integer;
- Bu : TBucket;
- begin
- I:=0;
- Result:=True;
- S:=GetBucketCount;
- while Result and (I<S) do
- begin
- J:=0;
- Bu:=FBuckets[I];
- while Result and (J<Bu.Count) do
- begin
- with Bu.Items[J] do
- AProc(AInfo,Item,Data,Result);
- Inc(J);
- end;
- Inc(I);
- end;
- end;
- Function TCustomBucketList.Remove(AItem: JSValue): JSValue;
- var
- B,I : integer;
- begin
- if FindItem(AItem,B,I) then
- begin
- Result:=FBuckets[B].Items[I].Data;
- DeleteItem(B,I);
- end
- else
- Result:=nil;
- end;
- { TBucketList }
- Function TBucketList.BucketFor(AItem: JSValue): Integer;
- begin
- // JSValues on average have a granularity of 4
- Result:=(longword(AItem) shr 2) and FBucketMask;
- end;
- constructor TBucketList.Create(ABuckets: TBucketListSizes);
- var
- L : Integer;
- begin
- inherited Create;
- L:=1 shl (Ord(Abuckets)+1);
- SetBucketCount(L);
- FBucketMask:=L-1;
- end;
- { TObjectBucketList }
- Function TObjectBucketList.GetData(AItem: TObject): TObject;
- begin
- Result:=TObject(inherited GetData(AItem));
- end;
- Procedure TObjectBucketList.SetData(AItem: TObject; const AData: TObject);
- begin
- inherited SetData(JSValue(AItem),JSValue(AData));
- end;
- Function TObjectBucketList.Add(AItem, AData: TObject): TObject;
- begin
- Result:=TObject(inherited Add(JSValue(AItem),JSValue(AData)));
- end;
- Function TObjectBucketList.Remove(AItem: TObject): TObject;
- begin
- Result:=TObject(inherited Remove(JSValue(AItem)));
- end;
- end.
|