summaryrefslogtreecommitdiff
path: root/docview/src/docdump/iterator_impl.pas
diff options
context:
space:
mode:
authorGraeme Geldenhuys <graeme@mastermaths.co.za>2009-11-27 15:45:14 +0200
committerGraeme Geldenhuys <graeme@mastermaths.co.za>2009-11-27 15:45:14 +0200
commit441add90d3183e0f5e8020442a21c9b3bf62c6ab (patch)
tree6f648c4400c170d82ac7cbaa698329deafb4e1f8 /docview/src/docdump/iterator_impl.pas
parentab9a941d02281b95f00dd74f69a744ac302743e3 (diff)
parenta1f68b05ed682e9a3640684d99a6d228cec80a35 (diff)
downloadfpGUI-441add90d3183e0f5e8020442a21c9b3bf62c6ab.tar.xz
Merged separate DocView project as our subdirectory
Diffstat (limited to 'docview/src/docdump/iterator_impl.pas')
-rw-r--r--docview/src/docdump/iterator_impl.pas480
1 files changed, 480 insertions, 0 deletions
diff --git a/docview/src/docdump/iterator_impl.pas b/docview/src/docdump/iterator_impl.pas
new file mode 100644
index 00000000..4ad88052
--- /dev/null
+++ b/docview/src/docdump/iterator_impl.pas
@@ -0,0 +1,480 @@
+unit iterator_impl;
+
+{$mode objfpc}{$H+}
+
+interface
+
+uses
+ Classes
+ ,SysUtils
+ ,Regex { to be used with filtered string iterator }
+ ,iterator_intf
+ ,contnrs
+ ;
+
+type
+
+ TTBStringsIterator = class(TInterfacedObject, ITBStringIterator, ITBStringAndObjectIterator)
+ private
+ FStrings: TStrings;
+ FCursor: Integer;
+ { Interface methods should always be private because
+ we will only ever access them via an Interface,
+ never via an Object instance }
+
+ { Interface: ITBStringIterator and ITBStringAndObjectIterator }
+ function HasNext: Boolean;
+ function Next: string;
+ function HasPrevious: Boolean;
+ function Previous: string;
+ { Interface: ITBStringAndObjectIterator }
+ function HasNextObject: Boolean;
+ function NextObject: TObject;
+ function HasPreviousObject: Boolean;
+ function PreviousObject: TObject;
+ public
+ constructor CreateCustom(const ASource: TStrings); virtual;
+ end;
+
+
+ TTBListIterator = class(TInterfacedObject, ITBIterator)
+ private
+ FList: TList;
+ FCursor: Integer;
+ { Interface: ITBIterator }
+ function HasNext: Boolean;
+ function Next: TObject;
+ function HasPrevious: Boolean;
+ function Previous: TObject;
+ public
+ constructor CreateCustom(const ASource: TList); virtual;
+ end;
+
+
+ TTBCollectionIterator = class(TInterfacedObject, ITBIterator)
+ private
+ FCollection: TCollection;
+ FCursor: Integer;
+ { Interface: ITBIterator }
+ function HasNext: Boolean;
+ function Next: TObject;
+ function HasPrevious: Boolean;
+ function Previous: TObject;
+ public
+ constructor CreateCustom(const ASource: TCollection); virtual;
+ end;
+
+
+ TTBInterfaceListIterator = class(TInterfacedObject, ITBInterfaceIterator)
+ private
+ FList: TInterfaceList;
+ FCursor: integer;
+ { Interface: ITBinterfaceIterator }
+ function HasNext: Boolean;
+ function Next: IInterface;
+ function HasPrevious: Boolean;
+ function Previous: IInterface;
+ public
+ constructor CreateCustom(const ASource: TInterfaceList); virtual;
+ end;
+
+
+ TTBFilteredStringsIterator = class(TTBStringsIterator, ITBFilteredStringIterator)
+ private
+ FNextIndex: Integer;
+ FRegex: TRegexEngine;
+ { Interface: ITBFilteredStringIterator }
+ function GetFilter: string;
+ procedure SetFilter(const AValue: string);
+ { Interface: ITBStringIterator and ITBStringAndObjectIterator }
+ function HasNext: Boolean;
+ function Next: string;
+ function HasPrevious: Boolean;
+ function Previous: string;
+ public
+ constructor CreateCustom(const ASource: TStrings); override;
+ destructor Destroy; override;
+ end;
+
+
+ TTBObjectListIterator = class(TInterfacedObject, ITBIterator)
+ private
+ FList: TObjectList;
+ FCursor: Integer;
+ { Interface: ITBIterator }
+ function HasNext: Boolean;
+ function Next: TObject;
+ function HasPrevious: Boolean;
+ function Previous: TObject;
+ public
+ constructor CreateCustom(const ASource: TObjectList); virtual;
+ end;
+
+
+
+implementation
+
+
+{ TTBStringsIterator }
+
+function TTBStringsIterator.HasNext: Boolean;
+begin
+ Result := False;
+ if Assigned(FStrings) then
+ if FCursor < FStrings.Count - 1 then
+ Result := True;
+end;
+
+function TTBStringsIterator.Next: string;
+begin
+ Result := '';
+ if HasNext then
+ begin
+ Inc(FCursor, 1);
+ Result := FStrings.Strings[FCursor];
+ end;
+end;
+
+function TTBStringsIterator.HasPrevious: Boolean;
+begin
+ Result := False;
+ if Assigned(FStrings) then
+ if FCursor > 0 then
+ Result := True;
+end;
+
+function TTBStringsIterator.Previous: string;
+begin
+ Result := '';
+ if HasPrevious then
+ begin
+ Dec(FCursor, 1);
+ Result := FStrings.Strings[FCursor];
+ end;
+end;
+
+function TTBStringsIterator.HasNextObject: Boolean;
+begin
+ Result := False;
+ if Assigned(FStrings) then
+ if FCursor < FStrings.Count - 1 then
+ Result := FStrings.Objects[FCursor] <> nil;
+end;
+
+function TTBStringsIterator.NextObject: TObject;
+begin
+ Result := nil;
+ if HasNextObject then
+ // Note that Next(...) increments the FCursor
+ Result := FStrings.Objects[FCursor];
+end;
+
+function TTBStringsIterator.HasPreviousObject: Boolean;
+begin
+ Result := False;
+ if Assigned(FStrings) then
+ if FCursor > 0 then
+ Result := FStrings.Objects[FCursor] <> nil;
+end;
+
+function TTBStringsIterator.PreviousObject: TObject;
+begin
+ Result := nil;
+ if HasPreviousObject then
+ // Note that Previous(...) decrements the FCursor
+ Result := FStrings.Objects[FCursor];
+end;
+
+constructor TTBStringsIterator.CreateCustom(const ASource: TStrings);
+begin
+ inherited Create;
+ FStrings := ASource;
+ FCursor := -1;
+end;
+
+
+{ TTBListIterator }
+
+function TTBListIterator.HasNext: Boolean;
+begin
+ Result := False;
+ if Assigned(FList) then
+ if FCursor < FList.Count - 1 then
+ Result := True;
+end;
+
+function TTBListIterator.Next: TObject;
+begin
+ Result := nil;
+ if HasNext then
+ begin
+ Inc(FCursor, 1);
+ result := TObject(FList.Items[FCursor]);
+ end;
+end;
+
+function TTBListIterator.HasPrevious: Boolean;
+begin
+ Result := False;
+ if Assigned(FList) then
+ begin
+ if FCursor > 0 then
+ Result := True;
+ end;
+end;
+
+function TTBListIterator.Previous: TObject;
+begin
+ Result := nil;
+ if HasPrevious then
+ begin
+ Dec(FCursor, 1);
+ Result := TObject(FList.Items[FCursor]);
+ end;
+end;
+
+constructor TTBListIterator.CreateCustom(const ASource: TList);
+begin
+ inherited Create;
+ FList := ASource;
+ FCursor := -1;
+end;
+
+
+{ TTBCollectionIterator }
+
+function TTBCollectionIterator.HasNext: Boolean;
+begin
+ Result := False;
+ if Assigned(FCollection) then
+ if FCursor < FCollection.Count - 1 then
+ Result := True;
+end;
+
+function TTBCollectionIterator.Next: TObject;
+begin
+ Result := nil;
+ if HasNext then
+ begin
+ Inc(FCursor, 1);
+ result := FCollection.Items[FCursor];
+ end;
+end;
+
+function TTBCollectionIterator.HasPrevious: Boolean;
+begin
+ Result := False;
+ if Assigned(FCollection) then
+ if FCursor > 0 then
+ Result := True;
+end;
+
+function TTBCollectionIterator.Previous: TObject;
+begin
+ Result := nil;
+ if HasPrevious then
+ begin
+ Dec(FCursor, 1);
+ Result := FCollection.Items[FCursor];
+ end;
+end;
+
+constructor TTBCollectionIterator.CreateCustom(const ASource: TCollection);
+begin
+ inherited Create;
+ FCollection := ASource;
+ FCursor := -1;
+end;
+
+
+{ TTBFilteredStringsIterator }
+
+function TTBFilteredStringsIterator.GetFilter: string;
+begin
+ Result := FRegex.RegexString;
+end;
+
+procedure TTBFilteredStringsIterator.SetFilter(const AValue: string);
+const
+ cFilterErr = 'Error in Filter string at position %d with ErrorCode %d. Filter string <%s>';
+var
+ LErrorCode: TRegexError;
+ LErrorPos: integer;
+begin
+ if AValue <> FRegex.RegexString then
+ begin
+ FRegex.RegexString := AValue;
+ if not FRegex.Parse(LErrorPos, LErrorCode) then
+ raise Exception.CreateFmt(cFilterErr, [LErrorPos, Ord(LErrorCode), AValue]);
+ end;
+ FNextIndex := -1;
+end;
+
+function TTBFilteredStringsIterator.HasNext: Boolean;
+var
+ LIndex: integer;
+ LMatchPos: integer;
+ LOffset: integer;
+begin
+ Result := False;
+ if GetFilter = '' then
+ begin
+ Result := inherited HasNext;
+ if Result then
+ FNextIndex := FCursor + 1;
+ end
+ else
+ begin
+ if FCursor < FStrings.Count - 1 then
+ begin
+ { If we haven't already calculated the next matching item }
+ if FNextIndex = -1 then
+ begin
+ LIndex := FCursor + 1;
+ { Peek ahead to find the next matching string }
+ while (LIndex < FStrings.Count) and (FNextIndex = -1) do
+ begin
+ { reset MatchString parameters }
+ LOffset := 0;
+ LMatchPos := 0;
+ if FRegex.MatchString(FStrings.Strings[LIndex], LMatchPos, LOffset) then
+ FNextIndex := LIndex;
+ Inc(LIndex);
+ end;
+ end;
+ if FNextIndex <> -1 then
+ Result := True;
+ end;
+ end; { if..else }
+end;
+
+function TTBFilteredStringsIterator.Next: string;
+begin
+ Result := '';
+ if HasNext then
+ begin
+ FCursor := FNextIndex;
+ FNextIndex := -1;
+ Result := FStrings.Strings[FCursor];
+ end;
+end;
+
+function TTBFilteredStringsIterator.HasPrevious: Boolean;
+begin
+ Result := False; // Filtered String is uni-directional
+end;
+
+function TTBFilteredStringsIterator.Previous: string;
+begin
+ Result := '';
+ raise EUniDirectionalIterator.Create('Filtered String Iterator is uni-directional (forward) only.');
+end;
+
+constructor TTBFilteredStringsIterator.CreateCustom(const ASource: TStrings);
+begin
+ inherited CreateCustom(ASource);
+ FRegex := TRegexEngine.Create('');
+ FRegex.IgnoreCase := True;
+ FNextIndex := -1;
+end;
+
+destructor TTBFilteredStringsIterator.Destroy;
+begin
+ FRegex.Free;
+ inherited Destroy;
+end;
+
+
+{ TTBInterfaceListIterator }
+
+function TTBInterfaceListIterator.HasNext: Boolean;
+begin
+ Result := False;
+ if Assigned(FList) then
+ if FCursor < FList.Count - 1 then
+ Result := True;
+end;
+
+function TTBInterfaceListIterator.Next: IInterface;
+begin
+ Result := nil;
+ if HasNext then
+ begin
+ Inc(FCursor, 1);
+ Result := FList.Items[FCursor];
+ end;
+end;
+
+function TTBInterfaceListIterator.HasPrevious: Boolean;
+begin
+ Result := False;
+ if Assigned(FList) then
+ if FCursor > 0 then
+ Result := True;
+end;
+
+function TTBInterfaceListIterator.Previous: IInterface;
+begin
+ Result := nil;
+ if HasPrevious then
+ begin
+ Dec(FCursor, 1);
+ Result := FList.Items[FCursor];
+ end;
+end;
+
+constructor TTBInterfaceListIterator.CreateCustom(const ASource: TInterfaceList);
+begin
+ inherited Create;
+ FList := ASource;
+ FCursor := -1;
+end;
+
+{ TTBObjectListIterator }
+
+function TTBObjectListIterator.HasNext: Boolean;
+begin
+ Result := False;
+ if Assigned(FList) then
+ if FCursor < FList.Count - 1 then
+ Result := True;
+end;
+
+function TTBObjectListIterator.Next: TObject;
+begin
+ result := nil;
+ if HasNext then
+ begin
+ Inc(FCursor);
+ result := FList.Items[FCursor];
+ end;
+end;
+
+function TTBObjectListIterator.HasPrevious: Boolean;
+begin
+ Result := False;
+ if Assigned(FList) then
+ if FCursor > 0 then
+ Result := True;
+end;
+
+function TTBObjectListIterator.Previous: TObject;
+begin
+ result := nil;
+ if HasPrevious then
+ begin
+ Dec(FCursor);
+ result := FList.Items[FCursor];
+ end;
+end;
+
+constructor TTBObjectListIterator.CreateCustom(const ASource: TObjectList);
+begin
+ inherited Create;
+ FList := ASource;
+ FCursor := -1;
+end;
+
+
+end.
+