📄 rm_stbase.pas
字号:
push eax
mov edi, eax { EDI = ^Buffer }
mov esi, ecx { ESI = ^Match }
mov ecx, edx { ECX = BufLength }
mov edx, MatLength { EDX = MatLength }
xor ebx, ebx { EBX will be used for comparison }
or edx, edx { Is MatLength 0? }
jz @@NotFound
mov al, [esi] { Get first character }
inc esi
and eax, 0FFh { Zero all but lower byte }
push ecx { Save registers }
push edx
push eax
call CharUpper { Upcase character }
pop edx
pop ecx
mov bl, al { Move uppercased char to BL }
dec edx { Dec MatLength }
sub ecx, edx { Is MatLength > BufLength? }
jbe @@NotFound
@@Next:
mov al, [edi]
inc edi
push ecx { Save registers }
push edx
push eax
call CharUpper { Upcase character in buffer }
pop edx
pop ecx
cmp bl, al { Match? }
je @@CompRest { Compare rest of string }
@@RestNoMatch:
dec ecx { End of string? }
jnz @@Next { Try next char }
jmp @@NotFound { Done if not found }
@@CompRest:
or edx, edx { Was there only one character? }
jz @@Found { If so, we're done }
push ebx { Save registers }
push ecx
push edi
push esi
mov ecx, edx
@@CompLoop:
mov al, [esi]
inc esi
push ecx { Save registers }
push edx
push eax
call CharUpper { Upcase character in buffer }
mov bl, al
mov al, [edi]
inc edi
push eax
call CharUpper { Upcase character in buffer }
pop edx
pop ecx
cmp bl, al
jne @@NoComp
dec ecx
jnz @@CompLoop
@@NoComp:
pop esi { Restore registers }
pop edi
pop ecx
pop ebx
jne @@RestNoMatch { Try again if no match }
{Calculate number of bytes searched and return}
@@Found:
pop ebx
mov esi, Pos
dec edi
sub edi, ebx
mov eax, 1
mov [esi], edi
jmp @@SDone
{Match was not found}
@@NotFound:
pop eax
xor eax, eax
@@SDone:
pop esi
pop edi
pop ebx
end;
{---primitives for converting strings to integers---}
procedure ValLongInt(S : ShortString; var LI : Longint; var ErrorCode : integer);
var
LenS : byte absolute S;
Offset : Integer;
NBCInx : Integer;
begin
{trim trailing spaces}
while (LenS > 0) and (S[LenS] = ' ') do
dec(LenS);
{empty strings are invalid}
if (LenS = 0) then begin
LI := 0;
ErrorCode := -1;
end;
{from now on S must have at least one non-blank char}
{find the first non-blank char}
NBCInx := 1;
while (S[NBCInx] = ' ') do
inc(NBCInx);
{check for a string of the form nnnnH}
Offset := 0;
if (upcase(S[LenS]) = 'H') then begin
{if the first non-blank char is the final character, then the
string is just of the form <spaces>H and is invalid}
if (NBCInx = LenS) then begin
LI := 0;
ErrorCode := LenS;
Exit;
end;
Move(S[NBCInx], S[NBCInx+1], LenS-NBCInx);
S[NBCInx] := '$';
Offset := -1;
end
{check for a string of the form 0Xnnnn}
else begin
if (NBCInx < LenS) and
(S[NBCInx] = '0') and (upcase(S[NBCInx+1]) = 'X') then begin
S[NBCInx] := ' ';
S[NBCInx+1] := '$';
end;
end;
Val(S, LI, ErrorCode);
if (ErrorCode <> 0) then begin
LI := 0;
Inc(ErrorCode, Offset);
end;
end;
procedure ValSmallint(const S : ShortString; var SI : smallint; var ErrorCode : integer);
const
SmallestInt16 = -32767;
LargestInt16 = 32767;
var
LI : Longint;
begin
ValLongInt(S, LI, ErrorCode);
if (ErrorCode <> 0) then
SI := 0
else {the conversion succeeded} begin
if (SmallestInt16 <= LI) and (LI <= LargestInt16) then
SI := LI
else begin
ErrorCode := length(S);
SI := 0;
end;
end;
end;
procedure ValWord(const S : ShortString; var Wd : word; var ErrorCode : integer);
const
SmallestWord = 0;
LargestWord = 65535;
var
LI : Longint;
begin
ValLongInt(S, LI, ErrorCode);
if (ErrorCode <> 0) then
Wd := 0
else {the conversion succeeded} begin
if (SmallestWord <= LI) and (LI <= LargestWord) then
Wd := LI
else begin
ErrorCode := length(S);
Wd := 0;
end;
end;
end;
{---------------------------------------------------}
function IsOrInheritsFrom(Root, Candidate : TClass) : boolean;
begin
Result := (Root = Candidate) or Candidate.InheritsFrom(Root);
end;
procedure RaiseContainerError(Code : LongInt);
var
E : ESTContainerError;
begin
E := ESTContainerError.CreateResTP(Code, 0);
E.ErrorCode := Code;
raise E;
end;
procedure RaiseContainerErrorFmt(Code : Longint; Data : array of const);
var
E : ESTContainerError;
begin
E := ESTContainerError.CreateResFmtTP(Code, Data, 0);
E.ErrorCode := Code;
raise E;
end;
{$IFNDEF HStrings}
function StNewStr(S : string) : PShortString;
begin
GetMem(Result, succ(length(S)));
Result^ := S;
end;
procedure StDisposeStr(PS : PShortString);
begin
if (PS <> nil) then
FreeMem(PS, succ(length(PS^)));
end;
{$ENDIF}
{----------------------------------------------------------------------}
constructor TStNode.Create(AData : Pointer);
begin
Data := AData;
end;
{----------------------------------------------------------------------}
function TStContainer.AssignPointers(Source : TPersistent;
AssignData : TIteratePointerFunc) : boolean;
begin
Result := false;
if (Source is TStContainer) then
if TStContainer(Source).StoresPointers then
begin
Clear;
TStContainer(Source).ForEachPointer(AssignData, Self);
Result := true;
end;
end;
function TStContainer.AssignUntypedVars(Source : TPersistent;
AssignData : TIterateUntypedFunc) : boolean;
var
RowCount : Cardinal;
ColCount : Cardinal;
ElSize : Cardinal;
begin
Result := false;
if (Source is TStContainer) then
if TStContainer(Source).StoresUntypedVars then
begin
Clear;
TStContainer(Source).GetArraySizes(RowCount, ColCount, ElSize);
SetArraySizes(RowCount, ColCount, ElSize);
TStContainer(Source).ForEachUntypedVar(AssignData, Self);
Result := true;
end;
end;
procedure TStContainer.ForEachPointer(Action : TIteratePointerFunc;
OtherData : pointer);
begin
{do nothing}
end;
procedure TStContainer.ForEachUntypedVar(Action : TIterateUntypedFunc;
OtherData : pointer);
begin
{do nothing}
end;
procedure TStContainer.GetArraySizes(var RowCount, ColCount, ElSize : Cardinal);
begin
RowCount := 0;
ColCount := 0;
ElSize := 0;
end;
procedure TStContainer.SetArraySizes(RowCount, ColCount, ElSize : Cardinal);
begin
{do nothing}
end;
procedure TStContainer.SetCompare(C : TCompareFunc);
begin
FCompare := C;
end;
procedure TStContainer.SetDisposeData(D : TDisposeDataProc);
begin
FDisposeData := D;
end;
procedure TStContainer.SetLoadData(L : TLoadDataFunc);
begin
FLoadData := L;
end;
procedure TStContainer.SetStoreData(S : TStoreDataProc);
begin
FStoreData := S;
end;
function TStContainer.StoresPointers : boolean;
begin
Result := false;
end;
function TStContainer.StoresUntypedVars : boolean;
begin
Result := false;
end;
constructor TStContainer.CreateContainer(NodeClass : TStNodeClass; Dummy : Integer);
begin
{$IFDEF ThreadSafe}
Windows.InitializeCriticalSection(conThreadSafe);
{$ENDIF}
FCompare := AbstractCompare;
conNodeClass := NodeClass;
inherited Create;
end;
procedure TStContainer.DecNodeProtection;
begin
Dec(conNodeProt);
end;
destructor TStContainer.Destroy;
begin
if conNodeProt = 0 then
Clear;
{$IFDEF ThreadSafe}
Windows.DeleteCriticalSection(conThreadSafe);
{$ENDIF}
inherited Destroy;
end;
procedure TStContainer.DisposeNodeData(P : TStNode);
begin
{$IFDEF ThreadSafe}
EnterCS;
try
{$ENDIF}
if Assigned(P) then
DoDisposeData(P.Data);
{$IFDEF ThreadSafe}
finally
LeaveCS;
end;
{$ENDIF}
end;
function TStContainer.DoCompare(Data1, Data2 : Pointer) : Integer;
begin
Result := 0;
if Assigned(FOnCompare) then
FOnCompare(Self, Data1, Data2, Result)
else if Assigned(FCompare) then
Result := FCompare(Data1, Data2);
end;
procedure TStContainer.DoDisposeData(Data : Pointer);
begin
if Assigned(FOnDisposeData) then
FOnDisposeData(Self, Data)
else if Assigned(FDisposeData) then
FDisposeData(Data);
end;
function TStContainer.DoLoadData(Reader : TReader) : Pointer;
begin
Result := nil;
if Assigned(FOnLoadData) then
FOnLoadData(Self, Reader, Result)
else if Assigned(FLoadData) then
Result := FLoadData(Reader)
else
RaiseContainerError(stscNoLoadData);
end;
procedure TStContainer.DoStoreData(Writer : TWriter; Data : Pointer);
begin
if Assigned(FOnStoreData) then
FOnStoreData(Self, Writer, Data)
else if Assigned(FStoreData) then
FStoreData(Writer, Data)
else
RaiseContainerError(stscNoStoreData);
end;
procedure TStContainer.EnterCS;
begin
{$IFDEF ThreadSafe}
EnterCriticalSection(conThreadSafe);
{$ENDIF}
end;
procedure TStContainer.IncNodeProtection;
begin
Inc(conNodeProt);
end;
procedure TStContainer.LeaveCS;
begin
{$IFDEF ThreadSafe}
LeaveCriticalSection(conThreadSafe);
{$ENDIF}
end;
procedure TStContainer.LoadFromFile(const FileName : string);
var
S : TStream;
begin
S := TFileStream.Create(FileName, fmOpenRead + fmShareDenyWrite);
try
LoadFromStream(S);
finally
S.Free;
end;
end;
procedure TStContainer.StoreToFile(const FileName : string);
var
S : TStream;
begin
S := TFileStream.Create(FileName, fmCreate);
try
StoreToStream(S);
finally
S.Free;
end;
end;
{*** TStComponent ***}
function TStComponent.GetVersion : string;
begin
Result := StVersionStr;
end;
procedure TStComponent.SetVersion(const Value : string);
begin
end;
{ TStBaseEdit }
function TStBaseEdit.GetVersion : string;
begin
Result := StVersionStr;
end;
procedure TStBaseEdit.SetVersion(const Value : string);
begin
end;
initialization
{$IFDEF VERSION3ONLY} { Delphi/Builder 3 doesn't like widestring typed constants }
StHexDigitsW := '0123456789ABCDEF';
DosDelimSetW := '\:';
{$ENDIF}
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -