Unfortunately it still returns a strange result when I try it with the string I used.
I also included a similar partly asm solution to remove a field.
Code: Select all
Procedure.s StringField_SwapFields_Orig(String$, FieldA, FieldB, Separator$=" ") ; by AND51
If FieldA <> FieldB
String$=Separator$+String$+Separator$
If FieldA > FieldB
Swap FieldA, FieldB
EndIf
Protected FieldA$=StringField(String$, FieldA+1, Separator$), FieldB$=StringField(String$, FieldB+1, Separator$)
FieldA=FindString(String$, FieldA$, 1)
FieldB=FindString(String$, FieldB$, 1)
ProcedureReturn Mid(Left(String$, FieldA-1)+FieldB$+Mid(String$, FieldA+Len(FieldA$), FieldB-FIeldA-Len(FieldA$))+FieldA$+Right(String$, Len(String$)-(FieldB+Len(FieldB$))+1), Len(Separator$)+1, Len(String$)-Len(Separator$)*2)
Else
ProcedureReturn String$
EndIf
EndProcedure
Procedure.s StringField_RemoveField_Orig(String$, Index, Separator$=" ") ; by AND51
Protected n.l=CountString(String$, Separator$), position.q
If Index > n
Index=n
EndIf
For n=1 To Index
position=FindString(String$, Separator$, position+1)
Next
ProcedureReturn Left(String$, position)+Right(String$, Len(String$)-(position+Len(StringField(String$, Index+1, Separator$)))-Len(Separator$))
EndProcedure
Procedure.s StringField_SwapFields(String.s, FieldA.l, FieldB.l, Separator.s = " ")
Protected *Orig.l, *Copy.l, PosA.l, PosB.l, LenA.l, LenB.l
Protected esi.l,ebx.l
; esp + 48 contains ptr to the original string
!mov eax,dword [esp+48]
!mov dword [p.p_Orig],eax
; passed String contains a copy
!mov eax,dword [p.v_String]
!mov dword [p.p_Copy],eax
; swap fields if required and check if fields > 0 and not equal
!mov eax,[p.v_FieldA]
!mov edx,[p.v_FieldB]
!cmp edx,eax
!je sf_err
!jg sf_cont
!xchg eax,edx
!mov [p.v_FieldA],eax
!mov [p.v_FieldB],edx
!sf_cont:
!cmp eax,1
!jl sf_err
; store esi and ebx registers
!mov [p.v_esi],esi
!mov [p.v_ebx],ebx
; scan for both fields
!mov edx,[p.v_Separator]
!mov ah,[edx]
!mov esi,[p.v_String]
!xor ecx,ecx
!cld
!sf_pre_loop:
!mov edx,esi
!sf_scan_loop:
!lodsb
!and al,al
!jz sf_end_fnd
!cmp al,ah
!jnz sf_scan_loop
!inc ecx
!cmp ecx,[p.v_FieldB]
!jz sf_fldB_fnd
!cmp ecx,[p.v_FieldA]
!jnz sf_pre_loop
!mov ebx,edx
!sub ebx,[p.v_String]
!mov [p.v_PosA],ebx
!mov ebx,esi
!sub ebx,edx
!dec ebx
!mov [p.v_LenA],ebx
!jmp sf_pre_loop
!sf_fldB_fnd:
!mov ebx,edx
!sub ebx,[p.v_String]
!mov [p.v_PosB],ebx
!mov ebx,esi
!sub ebx,edx
!dec ebx
!mov [p.v_LenB],ebx
!sf_end_fnd:
!inc ecx
!cmp ecx,[p.v_FieldB]
!jz sf_fldB_fnd
; retrieve esi and ebx registers
!mov esi,[p.v_esi]
!mov ebx,[p.v_ebx]
; check if both fields exist
!cmp byte [p.v_PosB],0
!je sf_err
MoveMemory(*Orig+PosB,*Copy+PosA,LenB)
MoveMemory(*Orig+PosA,*Copy+PosB+LenB-LenA,LenA)
MoveMemory(*Orig+PosA+LenA,*Copy+PosA+LenB,PosB-PosA-LenA)
!sf_err:
ProcedureReturn String
EndProcedure
Procedure.s StringField_RemoveField(String.s, Field.l, Separator.s = " ")
Protected *Orig.l, *Copy.l, PosF.l, LenF.l, LenS.l
Protected esi.l,ebx.l
; esp + 44 contains ptr to the original string
!mov eax,dword [esp+44]
!mov dword [p.p_Orig],eax
; passed String contains a copy
!mov eax,dword [p.v_String]
!mov dword [p.p_Copy],eax
; swap fields if required and check if fields > 0 and not equal
!mov eax,[p.v_Field]
!cmp eax,1
!jl rf_err
; store esi and ebx registers
!mov [p.v_esi],esi
!mov [p.v_ebx],ebx
; scan for field
!mov edx,[p.v_Separator]
!mov ah,[edx]
!mov esi,[p.v_String]
!xor ecx,ecx
!cld
!rf_pre_loop:
!mov edx,esi
!rf_scan_loop:
!lodsb
!and al,al
!jz rf_end_fnd
!cmp al,ah
!jnz rf_scan_loop
!inc ecx
!cmp ecx,[p.v_Field]
!jnz rf_pre_loop
!rf_fld_fnd:
!mov ebx,edx
!sub ebx,[p.v_String]
!mov [p.v_PosF],ebx
!mov ebx,esi
!sub ebx,edx
!dec ebx
!mov [p.v_LenF],ebx
!cmp dword [p.v_LenS],0
!jz rf_scan_loop
!rf_end_fnd:
!mov ebx,esi
!sub ebx,[p.v_String]
!dec ebx
!mov [p.v_LenS],ebx
!inc ecx
!cmp ecx,[p.v_Field]
!jz rf_fld_fnd
; retrieve esi and ebx registers
!mov esi,[p.v_esi]
!mov ebx,[p.v_ebx]
; check if field length > 0
!cmp byte [p.v_LenF],0
!je rf_err
If LenF = LenS
PokeB(*Copy,0)
Else
MoveMemory(*Orig+PosF+LenF+1,*Copy+PosF,LenS-PosF-LenF)
PokeB(*Copy+LenS-LenF-1,0)
EndIf
!rf_err:
ProcedureReturn String
EndProcedure
t = GetTickCount_()
s.s = "hai there, this is a test to see if swapping some fields will work for this string."
For i=1 To 100001
s = StringField_SwapFields_Orig(s,0,3)
Next
Debug s
t = GetTickCount_()-t
Debug t
t = GetTickCount_()
s.s = "hai there, this is a test to see if swapping some fields will work for this string."
For i=1 To 100001
s = StringField_SwapFields(s,1,4,".")
Next
Debug s
t = GetTickCount_()-t
Debug t
t = GetTickCount_()
s.s = "hai there, this is a test to see if removing a field will work for this string."
For i=1 To 100001
s1.s = StringField_RemoveField_Orig(s,13)
Next
Debug s1
t = GetTickCount_()-t
Debug t
t = GetTickCount_()
s.s = "hai there, this is a test to see if removing a field will work for this string."
For i=1 To 100001
s1.s = StringField_RemoveField(s,14)
Next
Debug s1
t = GetTickCount_()-t
Debug t