00001 {*********************************************************}
00002 { }
00003 { Zeos Database Objects }
00004 { Core collection and map classes }
00005 { }
00006 { Originally written by Sergey Seroukhov }
00007 { }
00008 {*********************************************************}
00009
00010 {@********************************************************}
00011 { Copyright (c) 1999-2006 Zeos Development Group }
00012 { }
00013 { License Agreement: }
00014 { }
00015 { This library is distributed in the hope that it will be }
00016 { useful, but WITHOUT ANY WARRANTY; without even the }
00017 { implied warranty of MERCHANTABILITY or FITNESS FOR }
00018 { A PARTICULAR PURPOSE. See the GNU Lesser General }
00019 { Public License for more details. }
00020 { }
00021 { The source code of the ZEOS Libraries and packages are }
00022 { distributed under the Library GNU General Public }
00023 { License (see the file COPYING / COPYING.ZEOS) }
00024 { with the following modification: }
00025 { As a special exception, the copyright holders of this }
00026 { library give you permission to link this library with }
00027 { independent modules to produce an executable, }
00028 { regardless of the license terms of these independent }
00029 { modules, and to copy and distribute the resulting }
00030 { executable under terms of your choice, provided that }
00031 { you also meet, for each linked independent module, }
00032 { the terms and conditions of the license of that module. }
00033 { An independent module is a module which is not derived }
00034 { from or based on this library. If you modify this }
00035 { library, you may extend this exception to your version }
00036 { of the library, but you are not obligated to do so. }
00037 { If you do not wish to do so, delete this exception }
00038 { statement from your version. }
00039 { }
00040 { }
00041 { The project web site is located on: }
00042 { http:
00043 { http:
00044 { svn:
00045 { }
00046 { http:
00047 { http:
00048 { }
00049 { }
00050 { }
00051 { Zeos Development Group. }
00052 {********************************************************@}
00053
00054 unit ZCollections;
00055
00056 interface
00057
00058 {$I ZCore.inc}
00059
00060 uses Classes, ZClasses;
00061
00062 type
00063
00064 {** Implements an iterator for regular TZCollection collection. }
00065 TZIterator = class (TZAbstractObject, IZIterator)
00066 private
00067 FCollection: IZCollection;
00068 FCurrentIndex: Integer;
00069 public
00070 constructor Create(const Col: IZCollection);
00071
00072 function HasNext: Boolean;
00073 function Next: IZInterface;
00074 end;
00075
00076 {** Interface list types. }
00077 TZInterfaceList = array[0..MaxListSize - 1] of IZInterface;
00078 PZInterfaceList = ^TZInterfaceList;
00079
00080 {** Implenments a collection of interfaces. }
00081 TZCollection = class(TZAbstractObject, IZCollection, IZClonnable)
00082 private
00083 FList: PZInterfaceList;
00084 FCount: Integer;
00085 FCapacity: Integer;
00086 protected
00087 class procedure Error(const Msg: string; Data: Integer);
00088 procedure Grow;
00089 procedure SetCapacity(NewCapacity: Integer);
00090 procedure SetCount(NewCount: Integer);
00091 public
00092 constructor Create;
00093 destructor Destroy; override;
00094
00095 function Clone: IZInterface; override;
00096 function ToString: string; override;
00097
00098 function Get(Index: Integer): IZInterface;
00099 procedure Put(Index: Integer; const Item: IZInterface);
00100 function IndexOf(const Item: IZInterface): Integer;
00101 function GetCount: Integer;
00102 function GetIterator: IZIterator;
00103
00104 function First: IZInterface;
00105 function Last: IZInterface;
00106
00107 function Add(const Item: IZInterface): Integer;
00108 procedure Insert(Index: Integer; const Item: IZInterface);
00109 function Remove(const Item: IZInterface): Integer;
00110
00111 procedure Exchange(Index1, Index2: Integer);
00112 procedure Delete(Index: Integer);
00113 procedure Clear;
00114
00115 function Contains(const Item: IZInterface): Boolean;
00116 function ContainsAll(const Col: IZCollection): Boolean;
00117 function AddAll(const Col: IZCollection): Boolean;
00118 function RemoveAll(const Col: IZCollection): Boolean;
00119
00120 property Count: Integer read GetCount;
00121 property Items[Index: Integer]: IZInterface read Get write Put; default;
00122 end;
00123
00124 {** Implements an unmodifiable collection of interfaces. }
00125 TZUnmodifiableCollection = class(TZAbstractObject, IZCollection, IZClonnable)
00126 private
00127 FCollection: IZCollection;
00128 private
00129 procedure RaiseException;
00130 public
00131 constructor Create(Collection: IZCollection);
00132 destructor Destroy; override;
00133
00134 function Clone: IZInterface; override;
00135 function ToString: string; override;
00136
00137 function Get(Index: Integer): IZInterface;
00138 procedure Put(Index: Integer; const Item: IZInterface);
00139 function IndexOf(const Item: IZInterface): Integer;
00140 function GetCount: Integer;
00141 function GetIterator: IZIterator;
00142
00143 function First: IZInterface;
00144 function Last: IZInterface;
00145
00146 function Add(const Item: IZInterface): Integer;
00147 procedure Insert(Index: Integer; const Item: IZInterface);
00148 function Remove(const Item: IZInterface): Integer;
00149
00150 procedure Exchange(Index1, Index2: Integer);
00151 procedure Delete(Index: Integer);
00152 procedure Clear;
00153
00154 function Contains(const Item: IZInterface): Boolean;
00155 function ContainsAll(const Col: IZCollection): Boolean;
00156 function AddAll(const Col: IZCollection): Boolean;
00157 function RemoveAll(const Col: IZCollection): Boolean;
00158
00159 property Count: Integer read GetCount;
00160 property Items[Index: Integer]: IZInterface read Get write Put; default;
00161 end;
00162
00163 {** Implements a hash map of interfaces. }
00164 TZHashMap = class(TZAbstractObject, IZHashMap, IZClonnable)
00165 private
00166 FKeys: IZCollection;
00167 FReadOnlyKeys: IZCollection;
00168 FValues: IZCollection;
00169 FReadOnlyValues: IZCollection;
00170 public
00171 constructor Create;
00172 destructor Destroy; override;
00173
00174 function Clone: IZInterface; override;
00175
00176 function Get(const Key: IZInterface): IZInterface;
00177 procedure Put(const Key: IZInterface; const Value: IZInterface);
00178 function GetKeys: IZCollection;
00179 function GetValues: IZCollection;
00180 function GetCount: Integer;
00181
00182 function Remove(Key: IZInterface): Boolean;
00183 procedure Clear;
00184
00185 property Count: Integer read GetCount;
00186 property Keys: IZCollection read GetKeys;
00187 property Values: IZCollection read GetValues;
00188 end;
00189
00190 {** Implements a stack of interfaces. }
00191 TZStack = class(TZAbstractObject, IZStack, IZClonnable)
00192 private
00193 FValues: IZCollection;
00194 public
00195 constructor Create;
00196 destructor Destroy; override;
00197
00198 function Clone: IZInterface; override;
00199 function ToString: string; override;
00200
00201 function Peek: IZInterface;
00202 function Pop: IZInterface;
00203 procedure Push(Value: IZInterface);
00204 function GetCount: Integer;
00205
00206 property Count: Integer read GetCount;
00207 end;
00208
00209 implementation
00210
00211 uses SysUtils, ZMessages;
00212
00213 { TZIterator }
00214
00215 {**
00216 Creates this iterator for the specified interface list.
00217 @param List a list of interfaces.
00218 }
00219 constructor TZIterator.Create(const Col: IZCollection);
00220 begin
00221 FCollection := Col;
00222 FCurrentIndex := 0;
00223 end;
00224
00225 {**
00226 Checks has the iterated collection more elements.
00227 @return <code>True</code> if iterated collection has more elements.
00228 }
00229 function TZIterator.HasNext: Boolean;
00230 begin
00231 Result := FCurrentIndex < FCollection.Count;
00232 end;
00233
00234 {**
00235 Gets a next iterated element from the collection.
00236 @return a next iterated element from the collection or <code>null</code>
00237 if no more elements.
00238 }
00239 function TZIterator.Next: IZInterface;
00240 begin
00241 if FCurrentIndex < FCollection.Count then
00242 begin
00243 Result := FCollection[FCurrentIndex];
00244 Inc(FCurrentIndex);
00245 end else
00246 Result := nil;
00247 end;
00248
00249 { TZCollection }
00250
00251 {**
00252 Creates this collection and assignes main properties.
00253 }
00254 constructor TZCollection.Create;
00255 begin
00256 end;
00257
00258 {**
00259 Destroys this object and frees the memory.
00260 }
00261 destructor TZCollection.Destroy;
00262 begin
00263 Clear;
00264 end;
00265
00266 {**
00267 Raises a collection error.
00268 @param Msg an error message.
00269 @param Data a integer value to describe an error.
00270 }
00271 class procedure TZCollection.Error(const Msg: string; Data: Integer);
00272
00273 {$IFNDEF FPC}
00274 function ReturnAddr: Pointer;
00275 asm
00276 MOV EAX,[EBP+4]
00277 end;
00278 {$ENDIF}
00279
00280 begin
00281 {$IFDEF FPC}
00282 raise EListError.CreateFmt(Msg,[Data]) at get_caller_addr(get_frame);
00283 {$ELSE}
00284 raise EListError.CreateFmt(Msg, [Data]) at ReturnAddr;
00285 {$ENDIF}
00286 end;
00287
00288 {**
00289 Increases an element count.
00290 }
00291 procedure TZCollection.Grow;
00292 var
00293 Delta: Integer;
00294 begin
00295 if FCapacity > 64 then
00296 Delta := FCapacity div 4
00297 else
00298 begin
00299 if FCapacity > 8 then
00300 Delta := 16
00301 else
00302 Delta := 4;
00303 end;
00304 SetCapacity(FCapacity + Delta);
00305 end;
00306
00307 {**
00308 Sets a new list capacity.
00309 @param NewCapacity a new list capacity.
00310 }
00311 procedure TZCollection.SetCapacity(NewCapacity: Integer);
00312 begin
00313 {$IFOPT R+}
00314 if (NewCapacity < FCount) or (NewCapacity > MaxListSize) then
00315 Error(SListCapacityError, NewCapacity);
00316 {$ENDIF}
00317 if NewCapacity <> FCapacity then
00318 begin
00319 ReallocMem(FList, NewCapacity * SizeOf(IZInterface));
00320 if NewCapacity > FCapacity then
00321 FillChar(FList^[FCount], (NewCapacity - FCapacity) * SizeOf(IZInterface), 0);
00322 FCapacity := NewCapacity;
00323 end;
00324 end;
00325
00326 {**
00327 Sets a new element count.
00328 @param NewCount a new element count.
00329 }
00330 procedure TZCollection.SetCount(NewCount: Integer);
00331 var
00332 I: Integer;
00333 begin
00334 {$IFOPT R+}
00335 if (NewCount < 0) or (NewCount > MaxListSize) then
00336 Error(SListCountError, NewCount);
00337 {$ENDIF}
00338 if NewCount > FCapacity then
00339 SetCapacity(NewCount);
00340 if NewCount < FCount then
00341 begin
00342 for I := FCount - 1 downto NewCount do
00343 FList^[I] := nil;
00344 end;
00345 FCount := NewCount;
00346 end;
00347
00348 {**
00349 Clones the instance of this object.
00350 @return a reference to the clonned object.
00351 }
00352 function TZCollection.Clone: IZInterface;
00353 var
00354 I: Integer;
00355 Collection: IZCollection;
00356 Clonnable: IZClonnable;
00357 begin
00358 Collection := TZCollection.Create;
00359 for I := 0 to FCount - 1 do
00360 begin
00361 if FList^[I].QueryInterface(IZClonnable, Clonnable) = 0 then
00362 Collection.Add(Clonnable.Clone)
00363 else Collection.Add(FList^[I]);
00364 end;
00365 Result := Collection;
00366 end;
00367
00368 {**
00369 Adds a new object at the and of this collection.
00370 @param Item an object to be added.
00371 @return a position of the added object.
00372 }
00373 function TZCollection.Add(const Item: IZInterface): Integer;
00374 begin
00375 Result := FCount;
00376 if Result = FCapacity then
00377 Grow;
00378
00379 FList^[Result] := Item;
00380 Inc(FCount);
00381 end;
00382
00383 {**
00384 Adds all elements from the specified collection into this collection.
00385 @param Col a collection of objects to be added.
00386 @return <code>True</code> is the collection was changed.
00387 }
00388 function TZCollection.AddAll(const Col: IZCollection): Boolean;
00389 var
00390 I: Integer;
00391 begin
00392 Result := Col.Count > 0;
00393 for I := 0 to Col.Count - 1 do
00394 Add(Col[I]);
00395 end;
00396
00397 {**
00398 Clears the content of this collection.
00399 }
00400 procedure TZCollection.Clear;
00401 begin
00402 SetCount(0);
00403 SetCapacity(0);
00404 end;
00405
00406 {**
00407 Checks is the specified object is stored in this collection.
00408 @return <code>True</code> if the object was found in the collection.
00409 }
00410 function TZCollection.Contains(const Item: IZInterface): Boolean;
00411 begin
00412 Result := IndexOf(Item) >= 0;
00413 end;
00414
00415 {**
00416 Checks are all the object in this collection.
00417 @param Col a collection of objects to be checked.
00418 @return <code>True</code> if all objects are in this collection.
00419 }
00420 function TZCollection.ContainsAll(const Col: IZCollection): Boolean;
00421 var
00422 I: Integer;
00423 begin
00424 Result := Col.Count > 0;
00425 for I := 0 to Col.Count - 1 do
00426 begin
00427 if IndexOf(Col[I]) < 0 then
00428 begin
00429 Result := False;
00430 Break;
00431 end;
00432 end;
00433 end;
00434
00435 {**
00436 Deletes an object from the specified position.
00437 }
00438 procedure TZCollection.Delete(Index: Integer);
00439 begin
00440 {$IFOPT R+}
00441 if (Index < 0) or (Index >= FCount) then
00442 Error(SListIndexError, Index);
00443 {$ENDIF}
00444 FList^[Index] := nil;
00445 Dec(FCount);
00446 if Index < FCount then
00447 begin
00448 System.Move(FList^[Index + 1], FList^[Index],
00449 (FCount - Index) * SizeOf(IZInterface));
00450 end;
00451 end;
00452
00453 {**
00454 Exchanges two element in the collection.
00455 @param Index1 an index of the first element.
00456 @param Index2 an index of the second element.
00457 }
00458 procedure TZCollection.Exchange(Index1, Index2: Integer);
00459 var
00460 Item: IZInterface;
00461 begin
00462 {$IFOPT R+}
00463 if (Index1 < 0) or (Index1 >= FCount) then
00464 Error(SListIndexError, Index1);
00465 if (Index2 < 0) or (Index2 >= FCount) then
00466 Error(SListIndexError, Index2);
00467 {$ENDIF}
00468 Item := FList^[Index1];
00469 FList^[Index1] := FList^[Index2];
00470 FList^[Index2] := Item;
00471 end;
00472
00473 {**
00474 Gets the first element from this collection.
00475 @return the first element.
00476 }
00477 function TZCollection.First: IZInterface;
00478 begin
00479 Result := Get(0);
00480 end;
00481
00482 {**
00483 Gets a collection element from the specified position.
00484 @param Index a position index of the element.
00485 @return a requested element.
00486 }
00487 function TZCollection.Get(Index: Integer): IZInterface;
00488 begin
00489 {$IFOPT R+}
00490 if (Index < 0) or (Index >= FCount) then
00491 Error(SListIndexError, Index);
00492 {$ENDIF}
00493 Result := FList^[Index];
00494 end;
00495
00496 {**
00497 Gets a number of the stored element in this collection.
00498 @return a number of stored elements.
00499 }
00500 function TZCollection.GetCount: Integer;
00501 begin
00502 Result := FCount;
00503 end;
00504
00505 {**
00506 Gets a created iterator for this collection.
00507 @return a created iterator for this collection.
00508 }
00509 function TZCollection.GetIterator: IZIterator;
00510 begin
00511 Result := TZIterator.Create(Self);
00512 end;
00513
00514 {**
00515 Defines an index of the specified object inside this colleciton.
00516 @param Item an object to be found.
00517 @return an object position index or -1 if it was not found.
00518 }
00519 function TZCollection.IndexOf(const Item: IZInterface): Integer;
00520 var
00521 I: Integer;
00522 Comparable: IZComparable;
00523 Unknown: IZInterface;
00524 begin
00525 Result := -1;
00526 if (FCount = 0) or (Item = nil) then
00527 Exit;
00528
00529 { Find IComparable objects }
00530 if Item.QueryInterface(IZComparable, Comparable) = 0 then
00531 begin
00532 for I := 0 to FCount - 1 do
00533 begin
00534 if Comparable.Equals(FList^[I]) then
00535 begin
00536 Result := I;
00537 Break;
00538 end;
00539 end;
00540 Comparable := nil;
00541 end
00542 { Find ordinary objects }
00543 else
00544 begin
00545
00546 Unknown := Item;
00547 for I := 0 to FCount - 1 do
00548 begin
00549 if Unknown = FList^[I] then
00550 begin
00551 Result := I;
00552 Break;
00553 end;
00554 end;
00555 Unknown := nil;
00556 end;
00557 end;
00558
00559 {**
00560 Inserts an object into specified position.
00561 @param Index a position index.
00562 @param Item an object to be inserted.
00563 }
00564 procedure TZCollection.Insert(Index: Integer; const Item: IZInterface);
00565 begin
00566 {$IFOPT R+}
00567 if (Index < 0) or (Index > FCount) then
00568 Error(SListIndexError, Index);
00569 {$ENDIF}
00570 if FCount = FCapacity then
00571 Grow;
00572 if Index < FCount then
00573 begin
00574 System.Move(FList^[Index], FList^[Index + 1],
00575 (FCount - Index) * SizeOf(IZInterface));
00576 end;
00577
00578 FList^[Index] := Item;
00579 Inc(FCount);
00580 end;
00581
00582 {**
00583 Gets the last object from this collection.
00584 @return the last object.
00585 }
00586 function TZCollection.Last: IZInterface;
00587 begin
00588 Result := Get(FCount - 1);
00589 end;
00590
00591 {**
00592 Puts a specified object into defined position.
00593 @param Index a position index.
00594 @param Items ab object to be put.
00595 }
00596 procedure TZCollection.Put(Index: Integer; const Item: IZInterface);
00597 begin
00598 {$IFOPT R+}
00599 if (Index < 0) or (Index >= FCount) then
00600 Error(SListIndexError, Index);
00601 {$ENDIF}
00602
00603 FList^[Index] := Item;
00604 end;
00605
00606 {**
00607 Removes an existed object which equals to the specified one.
00608 @param Item an object to be removed.
00609 @return an index of the removed object.
00610 }
00611 function TZCollection.Remove(const Item: IZInterface): Integer;
00612 begin
00613 Result := IndexOf(Item);
00614 if Result >= 0 then
00615 Delete(Result);
00616 end;
00617
00618 {**
00619 Removes all the elements from the specified collection.
00620 @param Col a collection of object to be removed.
00621 @return <code>True</code> if this collection was changed.
00622 }
00623 function TZCollection.RemoveAll(const Col: IZCollection): Boolean;
00624 var
00625 I: Integer;
00626 begin
00627 Result := False;
00628 for I := 0 to Col.Count - 1 do
00629 Result := (Remove(Col[I]) >= 0) or Result;
00630 end;
00631
00632 {**
00633 Gets a string representation for this object.
00634 }
00635 function TZCollection.ToString: string;
00636 var
00637 I: Integer;
00638 TempObject: IZObject;
00639 begin
00640 Result := '';
00641 for I := 0 to FCount - 1 do
00642 begin
00643 if I > 0 then
00644 Result := Result + ',';
00645 if FList^[I].QueryInterface(IZObject, TempObject) = 0 then
00646 Result := Result + TempObject.ToString
00647 else Result := Result + Format('<%p>', [Pointer(FList^[I])]);
00648 end;
00649 Result := '[' + Result + ']';
00650 end;
00651
00652 { TZUnmodifiableCollection }
00653
00654 {**
00655 Constructs this object and assignes main properties.
00656 @param Collection an initial modifiable list of interfaces.
00657 }
00658 constructor TZUnmodifiableCollection.Create(Collection: IZCollection);
00659 begin
00660 inherited Create;
00661 FCollection := Collection;
00662 end;
00663
00664 {**
00665 Destroys this object and frees the memory.
00666 }
00667 destructor TZUnmodifiableCollection.Destroy;
00668 begin
00669 FCollection := nil;
00670 inherited Destroy;
00671 end;
00672
00673 {**
00674 Clones the instance of this object.
00675 @return a reference to the clonned object.
00676 }
00677 function TZUnmodifiableCollection.Clone: IZInterface;
00678 begin
00679 Result := TZUnmodifiableCollection.Create(FCollection);
00680 end;
00681
00682 {**
00683 Raises invalid operation exception.
00684 }
00685 procedure TZUnmodifiableCollection.RaiseException;
00686 begin
00687 raise EInvalidOperation.Create(SImmutableOpIsNotAllowed);
00688 end;
00689
00690 {**
00691 Adds a new object at the and of this collection.
00692 @param Item an object to be added.
00693 @return a position of the added object.
00694 }
00695 function TZUnmodifiableCollection.Add(const Item: IZInterface): Integer;
00696 begin
00697 Result := -1;
00698 RaiseException;
00699 end;
00700
00701 {**
00702 Adds all elements from the specified collection into this collection.
00703 @param Col a collection of objects to be added.
00704 @return <code>True</code> is the collection was changed.
00705 }
00706 function TZUnmodifiableCollection.AddAll(const Col: IZCollection): Boolean;
00707 begin
00708 Result := False;
00709 RaiseException;
00710 end;
00711
00712 {**
00713 Clears the content of this collection.
00714 }
00715 procedure TZUnmodifiableCollection.Clear;
00716 begin
00717 RaiseException;
00718 end;
00719
00720 {**
00721 Checks is the specified object is stored in this collection.
00722 @return <code>True</code> if the object was found in the collection.
00723 }
00724 function TZUnmodifiableCollection.Contains(const Item: IZInterface): Boolean;
00725 begin
00726 Result := FCollection.Contains(Item);
00727 end;
00728
00729 {**
00730 Checks are all the object in this collection.
00731 @param Col a collection of objects to be checked.
00732 @return <code>True</code> if all objects are in this collection.
00733 }
00734 function TZUnmodifiableCollection.ContainsAll(const Col: IZCollection): Boolean;
00735 begin
00736 Result := FCollection.ContainsAll(Col);
00737 end;
00738
00739 {**
00740 Deletes an object from the specified position.
00741 }
00742 procedure TZUnmodifiableCollection.Delete(Index: Integer);
00743 begin
00744 RaiseException;
00745 end;
00746
00747 {**
00748 Exchanges two element in the collection.
00749 @param Index1 an index of the first element.
00750 @param Index2 an index of the second element.
00751 }
00752 procedure TZUnmodifiableCollection.Exchange(Index1, Index2: Integer);
00753 begin
00754 RaiseException;
00755 end;
00756
00757 {**
00758 Gets the first element from this collection.
00759 @return the first element.
00760 }
00761 function TZUnmodifiableCollection.First: IZInterface;
00762 begin
00763 Result := FCollection.First;
00764 end;
00765
00766 {**
00767 Gets a collection element from the specified position.
00768 @param Index a position index of the element.
00769 @return a requested element.
00770 }
00771 function TZUnmodifiableCollection.Get(Index: Integer): IZInterface;
00772 begin
00773 Result := FCollection[Index];
00774 end;
00775
00776 {**
00777 Gets a number of the stored element in this collection.
00778 @return a number of stored elements.
00779 }
00780 function TZUnmodifiableCollection.GetCount: Integer;
00781 begin
00782 Result := FCollection.Count;
00783 end;
00784
00785 {**
00786 Gets a created iterator for this collection.
00787 @return a created iterator for this collection.
00788 }
00789 function TZUnmodifiableCollection.GetIterator: IZIterator;
00790 begin
00791 Result := TZIterator.Create(Self);
00792 end;
00793
00794 {**
00795 Defines an index of the specified object inside this colleciton.
00796 @param Item an object to be found.
00797 @return an object position index or -1 if it was not found.
00798 }
00799 function TZUnmodifiableCollection.IndexOf(const Item: IZInterface): Integer;
00800 begin
00801 Result := FCollection.IndexOf(Item);
00802 end;
00803
00804 {**
00805 Inserts an object into specified position.
00806 @param Index a position index.
00807 @param Item an object to be inserted.
00808 }
00809 procedure TZUnmodifiableCollection.Insert(Index: Integer; const Item: IZInterface);
00810 begin
00811 RaiseException;
00812 end;
00813
00814 {**
00815 Gets the last object from this collection.
00816 @return the last object.
00817 }
00818 function TZUnmodifiableCollection.Last: IZInterface;
00819 begin
00820 Result := FCollection.Last;
00821 end;
00822
00823 {**
00824 Puts a specified object into defined position.
00825 @param Index a position index.
00826 @param Items ab object to be put.
00827 }
00828 procedure TZUnmodifiableCollection.Put(Index: Integer; const Item: IZInterface);
00829 begin
00830 RaiseException;
00831 end;
00832
00833 {**
00834 Removes an existed object which equals to the specified one.
00835 @param Item an object to be removed.
00836 @return an index of the removed object.
00837 }
00838 function TZUnmodifiableCollection.Remove(const Item: IZInterface): Integer;
00839 begin
00840 Result := -1;
00841 RaiseException;
00842 end;
00843
00844 {**
00845 Removes all the elements from the specified collection.
00846 @param Col a collection of object to be removed.
00847 @return <code>True</code> if this collection was changed.
00848 }
00849 function TZUnmodifiableCollection.RemoveAll(const Col: IZCollection): Boolean;
00850 begin
00851 Result := False;
00852 RaiseException;
00853 end;
00854
00855 {**
00856 Gets a string representation for this object.
00857 }
00858 function TZUnmodifiableCollection.ToString: string;
00859 begin
00860 Result := FCollection.ToString;
00861 end;
00862
00863 { TZHashMap }
00864
00865 {**
00866 Creates this hash map and assignes main properties.
00867 }
00868 constructor TZHashMap.Create;
00869 begin
00870 inherited Create;
00871 FKeys := TZCollection.Create;
00872 FValues := TZCollection.Create;
00873 FReadOnlyKeys := TZUnmodifiableCollection.Create(FKeys);
00874 FReadOnlyValues := TZUnmodifiableCollection.Create(FValues);
00875 end;
00876
00877 {**
00878 Destroys this object and frees the memory.
00879 }
00880 destructor TZHashMap.Destroy;
00881 begin
00882 FReadOnlyKeys := nil;
00883 FReadOnlyValues := nil;
00884 FKeys := nil;
00885 FValues := nil;
00886 inherited Destroy;
00887 end;
00888
00889 {**
00890 Clones the instance of this object.
00891 @return a reference to the clonned object.
00892 }
00893 function TZHashMap.Clone: IZInterface;
00894 var
00895 HashMap: TZHashMap;
00896 begin
00897 HashMap := TZHashMap.Create;
00898 HashMap.FKeys := IZCollection(FKeys.Clone);
00899 HashMap.FReadOnlyKeys := IZCollection(FReadOnlyKeys.Clone);
00900 HashMap.FValues := IZCollection(FValues.Clone);
00901 HashMap.FReadOnlyValues := IZCollection(FReadOnlyValues.Clone);
00902 Result := HashMap;
00903 end;
00904
00905 {**
00906 Gets a interface by it's key.
00907 @param Key a key interface.
00908 @return a found value interface or <code>nil</code> otherwise.
00909 }
00910 function TZHashMap.Get(const Key: IZInterface): IZInterface;
00911 var
00912 Index: Integer;
00913 begin
00914 Index := FKeys.IndexOf(Key);
00915 if Index >= 0 then
00916 Result := FValues[Index]
00917 else Result := nil;
00918 end;
00919
00920 {**
00921 Put a new key/value pair interfaces.
00922 @param Key a key interface.
00923 @param Value a value interface.
00924 }
00925 procedure TZHashMap.Put(const Key: IZInterface; const Value: IZInterface);
00926 var
00927 Index: Integer;
00928 begin
00929 Index := FKeys.IndexOf(Key);
00930 if Index >= 0 then
00931 FValues[Index] := Value
00932 else
00933 begin
00934 FKeys.Add(Key);
00935 FValues.Add(Value);
00936 end;
00937 end;
00938
00939 {**
00940 Gets a readonly collection of keys.
00941 @return a readonly collection of keys.
00942 }
00943 function TZHashMap.GetKeys: IZCollection;
00944 begin
00945 Result := FReadOnlyKeys;
00946 end;
00947
00948 {**
00949 Gets a readonly collection of values.
00950 @return a readonly collection of values.
00951 }
00952 function TZHashMap.GetValues: IZCollection;
00953 begin
00954 Result := FReadOnlyValues;
00955 end;
00956
00957 {**
00958 Gets a number of elements in this hash map.
00959 @return a number of elements in this hash map.
00960 }
00961 function TZHashMap.GetCount: Integer;
00962 begin
00963 Result := FKeys.Count;
00964 end;
00965
00966 {**
00967 Removes the element from the map by it's key.
00968 @param Key a key of the element.
00969 @return <code>true</code> of the hash map was changed.
00970 }
00971 function TZHashMap.Remove(Key: IZInterface): Boolean;
00972 var
00973 Index: Integer;
00974 begin
00975 Index := FKeys.IndexOf(Key);
00976 if Index >= 0 then
00977 begin
00978 FKeys.Delete(Index);
00979 FValues.Delete(Index);
00980 Result := True;
00981 end else
00982 Result := False;
00983 end;
00984
00985 {**
00986 Clears this hash map and removes all elements.
00987 }
00988 procedure TZHashMap.Clear;
00989 begin
00990 FKeys.Clear;
00991 FValues.Clear;
00992 end;
00993
00994 { TZStack }
00995
00996 {**
00997 Constructs this object and assignes the main properties.
00998 }
00999 constructor TZStack.Create;
01000 begin
01001 FValues := TZCollection.Create;
01002 end;
01003
01004 {**
01005 Destroys this object and cleanups the memory.
01006 }
01007 destructor TZStack.Destroy;
01008 begin
01009 FValues := nil;
01010 inherited Destroy;
01011 end;
01012
01013 {**
01014 Clones the instance of this object.
01015 @return a reference to the clonned object.
01016 }
01017 function TZStack.Clone: IZInterface;
01018 var
01019 Stack: TZStack;
01020 begin
01021 Stack := TZStack.Create;
01022 Stack.FValues := IZCollection(FValues.Clone);
01023 Result := Stack;
01024 end;
01025
01026 {**
01027 Gets a count of the stored elements.
01028 @return an elements count.
01029 }
01030 function TZStack.GetCount: Integer;
01031 begin
01032 Result := FValues.Count;
01033 end;
01034
01035 {**
01036 Gets an element from the top this stack without removing it.
01037 @return an element from the top of the stack.
01038 }
01039 function TZStack.Peek: IZInterface;
01040 begin
01041 if FValues.Count > 0 then
01042 Result := FValues[FValues.Count - 1]
01043 else Result := nil;
01044 end;
01045
01046 {**
01047 Gets an element from the top this stack and remove it.
01048 @return an element from the top of the stack.
01049 }
01050 function TZStack.Pop: IZInterface;
01051 begin
01052 if FValues.Count > 0 then
01053 begin
01054 Result := FValues[FValues.Count - 1];
01055 FValues.Delete(FValues.Count - 1);
01056 end else
01057 Result := nil;
01058 end;
01059
01060 {**
01061 Puts a new element to the top of this stack.
01062 @param Value a new element to be put.
01063 }
01064 procedure TZStack.Push(Value: IZInterface);
01065 begin
01066 FValues.Add(Value);
01067 end;
01068
01069 {**
01070 Gets a string representation for this object.
01071 }
01072 function TZStack.ToString: string;
01073 begin
01074 Result := FValues.ToString;
01075 end;
01076
01077 end.