whats new ¦  programming tips ¦  indy articles ¦  intraweb articles ¦  informations ¦  links ¦  interviews
 misc ¦  tutorials ¦  Add&Win Game

Tips (1541)

Database (90)
Files (137)
Forms (107)
Graphic (114)
IDE (21)
Indy (5)
Internet / LAN (130)
IntraWeb (0)
Math (76)
Misc (126)
Multimedia (45)
Objects/
ActiveX (51)

OpenTools API (3)
Printing (35)
Strings (83)
System (266)
VCL (242)

Top15

Tips sort by
component


Search Tip

Add new Tip

Add&Win Game

Advertising

31 Visitors Online


 
...Find a Substring in a String starting from any position in the String?
Autor: cnsSmartPos
[ Print tip ]  

Tip Rating (27):  
     


//-----------------------------------------------------------------------------
// Name: cnsSmartPos
// Author: Com-N-Sense
// Date:
// Purpose: Find a substring in a string starting from any position in the string.
// Params: SubStr - a substring for search.
//         S - the source string to search within
//         StartPos - the index position to start the search.
// Result: Integer - the position of the substring,
//                   zero - if the substring was not found
// Remarks: This is the original Delphi "Pos" function modified to support
//          the start pos parameter.
//-----------------------------------------------------------------------------
function SmartPosAsm(const substr : AnsiString; const s : AnsiString; StartPos : Cardinal) : Integer;
type
  
StrRec = packed record
    
allocSiz: Longint;
    refCnt: Longint;
    length: Longint;
  end;
const
  
skew = sizeof(StrRec);
asm
{     ->EAX     Pointer to substr               }
{       EDX     Pointer to string               }
{     <-EAX     Position of substr in s or 0    }
        
TEST    EAX,EAX
        JE      @@noWork

        TEST    EDX,EDX
        JE      @@stringEmpty

        PUSH    EBX
        PUSH    ESI
        PUSH    EDI

        MOV     ESI,EAX                         { Point ESI to substr           }
        
MOV     EDI,EDX                         { Point EDI to s                }

        
MOV     EAX,ECX
        MOV     ECX,[EDI-skew].StrRec.length    { ECX = Length(s)               }
        
ADD     EDI,EAX
        SUB     ECX,EAX

        PUSH    EDI                             { remember s position to calculate index        }

        
MOV     EDX,[ESI-skew].StrRec.length    { EDX = Length(substr)          }

        
DEC     EDX                             { EDX = Length(substr) - 1              }
        
JS      @@fail                          { < 0 ? return 0                        }
        
MOV     AL,[ESI]                        { AL = first char of substr             }
        
INC     ESI                             { Point ESI to 2'nd char of substr      }

        
SUB     ECX,EDX                         { #positions in s to look at    }
                                                { = Length(s) - Length(substr) + 1      }
        
JLE     @@fail
@@loop:
        REPNE   SCASB
        JNE     @@fail
        MOV     EBX,ECX                         { save outer loop counter               }
        
PUSH    ESI                             { save outer loop substr pointer        }
        
PUSH    EDI                             { save outer loop s pointer             }

        
MOV     ECX,EDX
        REPE    CMPSB
        POP     EDI                             { restore outer loop s pointer  }
        
POP     ESI                             { restore outer loop substr pointer     }
        
JE      @@found
        MOV     ECX,EBX                         { restore outer loop counter    }
        
JMP     @@loop

@@fail:
        POP     EDX                             { get rid of saved s pointer    }
        
XOR     EAX,EAX
        JMP     @@exit

@@stringEmpty:
        XOR     EAX,EAX
        JMP     @@noWork

@@found:
        POP     EDX                             { restore pointer to first char of s    }
        
MOV     EAX,EDI                         { EDI points of char after match        }
        
SUB     EAX,EDX                         { the difference is the correct index   }
@@exit:
        POP     EDI
        POP     ESI
        POP     EBX
@@noWork:
end//SmartPosAsm

function cnsSmartPos(const substr : AnsiString; const s : AnsiString; StartPos : Cardinal) : Integer;
begin
  
dec(StartPos);
  Result := SmartPosAsm(SubStr,S,StartPos);
  if Result > 0 then Result := Result + StartPos;
end//cnsSmartPos

 

Rate this tip:

poor
very good


Copyright © by SwissDelphiCenter.ch
All trademarks are the sole property of their respective owners