254 lines
8.6 KiB
ObjectPascal
254 lines
8.6 KiB
ObjectPascal
{**************************************************************************************************}
|
|
{ }
|
|
{ Project JEDI Code Library (JCL) }
|
|
{ }
|
|
{ The contents of this file are subject to the Mozilla Public License Version 1.1 (the "License"); }
|
|
{ you may not use this file except in compliance with the License. You may obtain a copy of the }
|
|
{ License at http://www.mozilla.org/MPL/ }
|
|
{ }
|
|
{ Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF }
|
|
{ ANY KIND, either express or implied. See the License for the specific language governing rights }
|
|
{ and limitations under the License. }
|
|
{ }
|
|
{ The Original Code is AbstractContainer.pas and DCL_Util.pas. }
|
|
{ }
|
|
{ The Initial Developer of the Original Code is Jean-Philippe BEMPEL aka RDM. Portions created by }
|
|
{ Jean-Philippe BEMPEL are Copyright (C) Jean-Philippe BEMPEL (rdm_30 att yahoo dott com) }
|
|
{ All rights reserved. }
|
|
{ }
|
|
{ Contributors: }
|
|
{ Daniele Teti (dade2004) }
|
|
{ Robert Marquardt (marquardt) }
|
|
{ }
|
|
{**************************************************************************************************}
|
|
{ }
|
|
{ The Delphi Container Library }
|
|
{ }
|
|
{**************************************************************************************************}
|
|
|
|
// Last modified: $Date: 2006-09-14 22:02:40 +0200 (jeu., 14 sept. 2006) $
|
|
|
|
unit JclAbstractContainers;
|
|
|
|
{$I jcl.inc}
|
|
|
|
interface
|
|
|
|
uses
|
|
{$IFDEF UNITVERSIONING}
|
|
JclUnitVersioning,
|
|
{$ENDIF UNITVERSIONING}
|
|
{$IFDEF CLR}
|
|
System.Threading,
|
|
{$ELSE}
|
|
{$IFDEF MSWINDOWS}
|
|
Windows,
|
|
{$ENDIF MSWINDOWS}
|
|
{$ENDIF CLR}
|
|
{$IFDEF HAS_UNIT_LIBC}
|
|
Libc,
|
|
{$ENDIF HAS_UNIT_LIBC}
|
|
SysUtils, Classes, JclBase, JclContainerIntf, JclSysUtils;
|
|
|
|
type
|
|
{$IFDEF KEEP_DEPRECATED}
|
|
TJclIntfCriticalSection = JclSysUtils.TJclIntfCriticalSection;
|
|
{$ENDIF KEEP_DEPRECATED}
|
|
|
|
TJclAbstractContainer = class(TInterfacedObject)
|
|
{$IFDEF THREADSAFE}
|
|
private
|
|
FCriticalSection: TJclIntfCriticalSection;
|
|
protected
|
|
function EnterCriticalSection: IInterface;
|
|
public
|
|
constructor Create;
|
|
destructor Destroy; override;
|
|
{$ENDIF THREADSAFE}
|
|
end;
|
|
|
|
TJclStrCollection = class(TJclAbstractContainer, IJclStrCollection)
|
|
protected
|
|
{ IJclStrCollection }
|
|
function Add(const AString: string): Boolean; virtual; abstract;
|
|
function AddAll(ACollection: IJclStrCollection): Boolean; virtual; abstract;
|
|
procedure Clear; virtual; abstract;
|
|
function Contains(const AString: string): Boolean; virtual; abstract;
|
|
function ContainsAll(ACollection: IJclStrCollection): Boolean; virtual; abstract;
|
|
function Equals(ACollection: IJclStrCollection): Boolean; virtual; abstract;
|
|
function First: IJclStrIterator; virtual; abstract;
|
|
function IsEmpty: Boolean; virtual; abstract;
|
|
function Last: IJclStrIterator; virtual; abstract;
|
|
function Remove(const AString: string): Boolean; overload; virtual; abstract;
|
|
function RemoveAll(ACollection: IJclStrCollection): Boolean; virtual; abstract;
|
|
function RetainAll(ACollection: IJclStrCollection): Boolean; virtual; abstract;
|
|
function Size: Integer; virtual; abstract;
|
|
procedure LoadFromStrings(Strings: TStrings);
|
|
procedure SaveToStrings(Strings: TStrings);
|
|
procedure AppendToStrings(Strings: TStrings);
|
|
procedure AppendFromStrings(Strings: TStrings);
|
|
function GetAsStrings: TStrings;
|
|
function GetAsDelimited(const Separator: string = AnsiLineBreak): string;
|
|
procedure AppendDelimited(const AString: string; const Separator: string = AnsiLineBreak);
|
|
procedure LoadDelimited(const AString: string; const Separator: string = AnsiLineBreak);
|
|
end;
|
|
|
|
{$IFDEF UNITVERSIONING}
|
|
const
|
|
UnitVersioning: TUnitVersionInfo = (
|
|
RCSfile: '$URL: https://jcl.svn.sourceforge.net:443/svnroot/jcl/tags/JCL-1.100-Build2646/jcl/source/common/JclAbstractContainers.pas $';
|
|
Revision: '$Revision: 1769 $';
|
|
Date: '$Date: 2006-09-14 22:02:40 +0200 (jeu., 14 sept. 2006) $';
|
|
LogPath: 'JCL\source\common'
|
|
);
|
|
{$ENDIF UNITVERSIONING}
|
|
|
|
implementation
|
|
|
|
//=== { TJclAbstractContainer } ==============================================
|
|
|
|
{$IFDEF THREADSAFE}
|
|
|
|
constructor TJclAbstractContainer.Create;
|
|
begin
|
|
inherited Create;
|
|
FCriticalSection := TJclIntfCriticalSection.Create;
|
|
end;
|
|
|
|
destructor TJclAbstractContainer.Destroy;
|
|
begin
|
|
FCriticalSection.Free;
|
|
inherited Destroy;
|
|
end;
|
|
|
|
function TJclAbstractContainer.EnterCriticalSection: IInterface;
|
|
begin
|
|
Result := FCriticalSection as IInterface;
|
|
end;
|
|
|
|
{$ENDIF THREADSAFE}
|
|
|
|
//=== { TJclStrCollection } ==================================================
|
|
|
|
procedure TJclStrCollection.AppendDelimited(const AString, Separator: string);
|
|
{$IFDEF CLR}
|
|
var
|
|
I, StartIndex: Integer;
|
|
begin
|
|
I := Pos(Separator, AString);
|
|
if I <> 0 then
|
|
begin
|
|
Dec(I); // to .NET string index base
|
|
StartIndex := 0;
|
|
repeat
|
|
Add(AString.Substring(StartIndex, I - StartIndex + 1));
|
|
StartIndex := I + 1;
|
|
I := AString.IndexOf(Separator, StartIndex);
|
|
until I < 0;
|
|
end
|
|
else
|
|
Add(AString);
|
|
end;
|
|
{$ELSE}
|
|
var
|
|
Item: string;
|
|
SepLen: Integer;
|
|
PString, PSep, PPos: PChar;
|
|
begin
|
|
PString := PChar(AString);
|
|
PSep := PChar(Separator);
|
|
PPos := StrPos(PString, PSep);
|
|
if PPos <> nil then
|
|
begin
|
|
SepLen := StrLen(PSep);
|
|
repeat
|
|
//SetLength(Item, PPos - PString + 1);
|
|
SetLength(Item, PPos - PString);
|
|
Move(PString^, Item[1], PPos - PString);
|
|
//Item[PPos - PString + 1] := #0;
|
|
Add(Item);
|
|
PString := PPos + SepLen;
|
|
PPos := StrPos(PString, PSep);
|
|
until PPos = nil;
|
|
if StrLen(PString) > 0 then //ex. hello#world
|
|
Add(PString);
|
|
end
|
|
else //There isnt a Separator in AString
|
|
Add(AString);
|
|
end;
|
|
{$ENDIF CLR}
|
|
|
|
procedure TJclStrCollection.AppendFromStrings(Strings: TStrings);
|
|
var
|
|
I: Integer;
|
|
begin
|
|
for I := 0 to Strings.Count - 1 do
|
|
Add(Strings[I]);
|
|
end;
|
|
|
|
procedure TJclStrCollection.AppendToStrings(Strings: TStrings);
|
|
var
|
|
It: IJclStrIterator;
|
|
begin
|
|
It := First;
|
|
Strings.BeginUpdate;
|
|
try
|
|
while It.HasNext do
|
|
Strings.Add(It.Next);
|
|
finally
|
|
Strings.EndUpdate;
|
|
end;
|
|
end;
|
|
|
|
function TJclStrCollection.GetAsDelimited(const Separator: string): string;
|
|
var
|
|
It: IJclStrIterator;
|
|
begin
|
|
It := First;
|
|
Result := '';
|
|
if It.HasNext then
|
|
Result := It.Next;
|
|
while It.HasNext do
|
|
Result := Result + Separator + It.Next;
|
|
end;
|
|
|
|
function TJclStrCollection.GetAsStrings: TStrings;
|
|
begin
|
|
Result := TStringList.Create;
|
|
try
|
|
AppendToStrings(Result);
|
|
except
|
|
Result.Free;
|
|
raise;
|
|
end;
|
|
end;
|
|
|
|
procedure TJclStrCollection.LoadDelimited(const AString, Separator: string);
|
|
begin
|
|
Clear;
|
|
AppendDelimited(AString, Separator);
|
|
end;
|
|
|
|
procedure TJclStrCollection.LoadFromStrings(Strings: TStrings);
|
|
begin
|
|
Clear;
|
|
AppendFromStrings(Strings);
|
|
end;
|
|
|
|
procedure TJclStrCollection.SaveToStrings(Strings: TStrings);
|
|
begin
|
|
Strings.Clear;
|
|
AppendToStrings(Strings);
|
|
end;
|
|
|
|
{$IFDEF UNITVERSIONING}
|
|
initialization
|
|
RegisterUnitVersion(HInstance, UnitVersioning);
|
|
|
|
finalization
|
|
UnregisterUnitVersion(HInstance);
|
|
{$ENDIF UNITVERSIONING}
|
|
|
|
end.
|
|
|