(********************************************************)
(* *)
(* Object Modeler Class Library *)
(* *)
(* Open Source Released 2000 *)
(* *)
(* *)
(* Unit naming convetions: *)
(* *)
(* Either a descriptive name such as Buttons or Grids *)
(* or a descriptive name followed by one of these *)
(* suffixes: *)
(* *)
(* XXXCtrls *)
(* XXXIntf *)
(* XXXMgr *)
(* XXXObj *)
(* XXXReg *)
(* XXXSvr *)
(* XXXTools *)
(* XXXTypes *)
(* XXXUtils *)
(* *)
(********************************************************)
function TrimSeparator(const S: string; Separator: Char): string;
var
P: PChar;
begin
Result := '';
if S <> '' then
begin
P := PChar(S);
while (P^ <> #0) and (P^ <> Separator) do
Inc(P);
if P^ <> #0 then
Inc(P);
Result := P;
end;
end;
function TComplexField.GetCount: Integer;
var
P: PChar;
begin
Result := 0;
if FData <> '' then
begin
P := PChar(FData);
while P^ <> #0 do
begin
while P^ in ComplexSeperators do
Inc(P);
if P^ in ComplexCharacters then
Inc(Result);
while P^ in ComplexCharacters do
Inc(P);
end;
end;
end;
function TComplexField.IndexOf(const S: string): Integer;
var
TempStr: string;
I: Integer;
begin
Result := -1;
TempStr := UpperCase(S);
for I := 0 to Count - 1 do
if TempStr = UpperCase(Item[I]) then
begin
Result := I;
Break;
end;
end;
function TComplexField.GetItem(Index: Integer): string;
var
StartPos: PChar;
P: PChar;
I: Integer;
begin
Result := '';
if (Index < 0) or (Index > Count - 1) then
raise EComplexFieldError.Create(SRangeIndexError);
P := PChar(FData);
I := 0;
while P^ <> #0 do
begin
while P^ in ComplexSeperators do
Inc(P);
StartPos := P;
if P^ in ComplexCharacters then
begin
while P^ in ComplexCharacters do
Inc(P);
if I = Index then
begin
SetString(Result, StartPos, P - StartPos);
Break;
end;
Inc(I);
end;
end;
end;
procedure TComplexField.SetItem(Index: Integer; const Value: string);
var
P: PChar;
StartPos: PChar;
I: Integer;
begin
if (Index < 0) or (Index > Count - 1) then
raise EComplexFieldError.Create(SRangeIndexError);
P := PChar(FData);
StartPos := P;
I := -1;
while P^ <> #0 do
begin
while P^ in ComplexSeperators do
Inc(P);
StartPos := P;
while P^ in ComplexCharacters do
Inc(P);
Inc(I);
if I = Index then
Break;
end;
FData := Copy(FData, 1, StartPos - PChar(FData)) + Value +
Copy(FData, P - PChar(FData) + 1, Length(FData));
end;
{ TEnumString }
constructor TEnumString.Create(Strings: TStrings);
begin
inherited Create;
FStrings := Strings;
end;
{ TEnumString.IEnumString }
function TEnumString.Next(celt: Longint;
out elt; pceltFetched: PLongint): HResult;
var
I: Integer;
begin
I := 0;
while (I < celt) and (FIndex < FStrings.Count) do
begin
TPointerList(elt)[I] := PWideChar(WideString(FStrings[FIndex]));
Inc(I);
Inc(FIndex);
end;
if pceltFetched <> nil then pceltFetched^ := I;
if I = celt then Result := S_OK else Result := S_FALSE;
end;
function TEnumString.Skip(celt: Longint): HResult;
begin
if (FIndex + celt) <= FStrings.Count then
begin
Inc(FIndex, celt);
Result := S_OK;
end
else
begin
FIndex := FStrings.Count;
Result := S_FALSE;
end;
end;
function TEnumString.Reset: HResult;
begin
FIndex := 0;
Result := S_OK;
end;
function TEnumString.Clone(out enm: IEnumString): HResult;
begin
try
enm := TEnumString.Create(FStrings);
Result := S_OK;
except
Result := E_UNEXPECTED;
end;
end;
{ The AdvanceToken function does a case insensitive search of Buffer for
SearchStr, and returns True if a match is found. Buffer is modified to
point to the character after the match. }
function AdvanceToken(var Buffer: PChar; const SearchStr: string): Boolean;
{ The GetComponentName function returns the name of the Component parameter. If
the component has no name, the function creates a unique name. }
function GetComponentName(Component: TComponent): string;
{ The GetComponentPath function returns a string that represents the ownership
of the Component parameter. }
function GetComponentPath(Component: TComponent): string;
{ The MaskConvert function returns a formated string from Source as defined by
Mask. Any characters in Source that don't match the Mask string are replaced
with DefaultChar. Mask can contain the following special characters:
'C' Filters source string for the first occurance of an Alpha character
'D' Filters source string for the first occurance of an Numeric character
'?' Accepts any character
function MaskConvert(const Source: string; const Mask: string; DefaultChar: Char): string;
{ The SearchAndReplace procedure performs a case-sensitive search for SearchStr
and calls ReplaceFunc for each a match found. If ReplaceFunc returns True then
SearchStr is replaced with S. }
type
TReplaceFunc = function (var S: string): Boolean;
{ The TrimSeparator function returns a copy of S from the character after the
Separator parameter to the end of the string. }
function TrimSeparator(const S: string; Separator: Char): string;
{ TComplexField class }
type
EComplexFieldError = class(Exception);
TComplexField = class
private
FData: string;
function GetCount: Integer;
function GetItem(Index: Integer): string;
procedure SetItem(Index: Integer; const Value: string);
public
function IndexOf(const S: string): Integer;
property Count: Integer read GetCount;
property Data: string read FData write FData;
property Item[index: Integer]: string read GetItem write SetItem; default;
end;
{ TEnumString class }
TEnumString = class(TInterfacedObject, IEnumString)
private
FStrings: TStrings;
FIndex: Integer;
protected
{ IEnumString }
function Next(celt: Longint; out elt;
pceltFetched: PLongint): HResult; stdcall;
function Skip(celt: Longint): HResult; stdcall;
function Reset: HResult; stdcall;
function Clone(out enm: IEnumString): HResult; stdcall;
public
constructor Create(Strings: TStrings);
end;
implementation
uses
StrConst;
function AdvanceToken(var Buffer: PChar; const SearchStr: string): Boolean;
var
Token: PChar;
begin
Token := PChar(SearchStr);
while Buffer^ <> #0 do
begin
if UpCase(Buffer^) = Token^ then
Inc(Token)
else if Token <> PChar(SearchStr) then
begin
Token := PChar(SearchStr);
if UpCase(Buffer^) = Token^ then
Inc(Token);
end;
Inc(Buffer);
if Token^ = #0 then
Break;
end;
Result := Token^ = #0;
end;
function GetComponentName(Component: TComponent): string;
var
S: string;
I: Integer;
begin
Result := Component.Name;
if Result = '' then
begin
S := Component.ClassName;
I := 1;
if Component.Owner <> nil then
while Component.Owner.FindComponent(PChar(@S[2]) + IntToStr(I)) <> nil do
Inc(I);
Result := PChar(@S[2]) + IntToStr(I);
end;
end;
function GetComponentPath(Component: TComponent): string;
var
S: string;
begin
if Component <> nil then
begin
S := GetComponentPath(Component.Owner);
if S <> '' then
Result := S + DotSep + GetComponentName(Component)
else
Result := S + GetComponentName(Component);
end
else
Result := '';
end;
function MaskConvert(const Source: string; const Mask: string; DefaultChar: Char): string;
var
P: PChar;
I: Integer;
procedure DefaultAction;
begin
if UpCase(Mask[I]) in ['C', 'D', '?'] then
Result := Result + DefaultChar
else
Result := Result + Mask[I];
end;
begin
P := PChar(Source);
Result := '';
for I := 1 to Length(Mask) do
if P^ <> #0 then
begin
case UpCase(Mask[I]) of
'C':
begin
while (P^ <> #0) and (not (P^ in Alpha)) do
Inc(P);
if P^ <> #0 then
Result := Result + P^
else
begin
DefaultAction;
Continue;
end;
end;
'D':
begin
while (P^ <> #0) and (not (P^ in Numeric)) do
Inc(P);
if P^ <> #0 then
Result := Result + P^
else
begin
DefaultAction;
Continue;
end;
end;
'?':
Result := Result + P^
else
begin
Result := Result + Mask[I];
Continue;
end;
end;
Inc(P);
end
else
DefaultAction;
end;
(********************************************************)
(* *)
(* Object Modeler Class Library *)
(* *)
(* Open Source Released 2000 *)
(* *)
(********************************************************)
unit StrConst;
{$I STD.INC}
interface
resourcestring
SRangeIndexError = 'Index outside of range bounds';
SLauncherFileError = 'Cannot launch specified filename';
SLauncherTerminateError = 'Cannot terminate application';
SInvalidMode = 'Pipe does not support this operation';
SNoStorageSpecified = 'No storage specified in call to open stream';
SNotConnected = 'Pipe not connected';
SStorageNotOpen = 'Storage not open';
SStreamNotOpen = 'Stream not open';
SMutexCreateError = 'Unable to create mutex';
SMapppingCreateError = 'Unable to create file mapping';
SViewMapError = 'Cannot map view of file';
SFileOpenError = 'Cannot open file';
SNotLocked = 'Data not locked';
SElapsedTime = 'Cannot get elapsed time';
STimerError = 'Cannot %s timer';
SCannotFocusSprite = 'Cannot focus a disabled or invisible sprite';
SNameNotUnique = 'Name "%s" is not unique';
SSocketCreateError = 'Error creating socket';
SWinSocketError = 'Windows socket error: %s (%d), on API ''%s''';
SInvalidPropertyKind = 'Invalid property kind';
SInvalidPropertyValue = 'Invalid property value';
SUnexpectedToken = 'Unexpected token at position %d';
SOpenFailed = 'Unable to open com port';
SWriteFailed = 'WriteFile function failed';
SReadFailed = 'ReadFile function failed';
SInvalidAsync = 'Invalid Async parameter';
SPurgeFailed = 'PurgeComm function failed';
SAsyncCheck = 'Unable to get async status';
SSetStateFailed = 'SetCommState function failed';
STimeoutsFailed = 'SetCommTimeouts failed';
SSetupComFailed = 'SetupComm function failed';
SClearComFailed = 'ClearCommError function failed';
SModemStatFailed = 'GetCommModemStatus function failed';
SEscapeComFailed = 'EscapeCommFunction function failed';
STransmitFailed = 'TransmitCommChar function failed';
SSyncMeth = 'Cannot set SyncMethod while connected';
SEnumPortsFailed = 'EnumPorts function failed';
SStoreFailed = 'Failed to store settings';
SLoadFailed = 'Failed to load settings';
SRegFailed = 'Terminal link (un)registration failed';
SLedStateFailed = 'Cannot change led state if com port is selected';
SNoParentStructure = 'No parent structure available';
SInvalidStructureName = '"%s" is not a valid structure name';
SDuplicateName = 'Duplicate names not allowed';
SNoOpenStructure = 'Cannot open structure';
SCannotPerformOperation = 'Cannot perform operation';