Re: Fast string
Posted: Wed May 29, 2019 8:32 am
+1 for faster native strings.
Code: Select all
EnableExplicit
Procedure StringAppend(*sb,string.s)
If string=""
ProcedureReturn *sb
EndIf
Protected size,*Offset
If *sb
size=MemorySize(*sb)
*Offset=size
EndIf
size+StringByteLength(string)
*sb=ReAllocateMemory(*sb,size,#PB_Memory_NoClear)
PokeS(*sb+*offset,string,-1,#PB_String_NoZero)
ProcedureReturn *sb
EndProcedure
Procedure AppendString(*sb,string.s)
ProcedureReturn StringAppend(*sb,string)
EndProcedure
Procedure.s SBToString(*sb)
If *sb
ProcedureReturn PeekS(*sb,MemorySize(*sb)/SizeOf(Character),#PB_Unicode)
Else
ProcedureReturn ""
EndIf
EndProcedure
Macro SB2String(n)
SBToString(n)
EndMacro
Procedure SBClear(*sb)
If *sb
FreeMemory(*sb)
EndIf
*sb=0
EndProcedure
Macro SBFree(n)
SBClear(n)
EndMacro
ImportC ""
wcsstr.i(*str1, *str2)
_wcslwr.i(*cs)
wcslen.l(*cs)
EndImport
Procedure FastStringSplit(sString.s, sDelimiters.s, Array StringArray.i(1), Casesense = 1)
Protected String = @sString
Protected Delimiters = @sDelimiters
Protected StringSize = wcslen(String) * 2
Protected DelimitersSize = wcslen(Delimiters) * 2
Protected aString = AllocateMemory(StringSize + 2):CopyMemory(String,aString,StringSize)
If Not aString:ProcedureReturn 0:EndIf
If Casesense = 0
_wcslwr(String)
_wcslwr(Delimiters)
EndIf
Protected String2 = String
Protected ElementStart ,ElementSize
Protected aItem
Repeat
String2 = wcsstr(String2,Delimiters)
If String2 = 0
ElementSize = StringSize - ElementStart
Else
ElementSize = String2 - (String + ElementStart)
EndIf
If ArraySize(StringArray()) < aItem : ReDim StringArray(aItem +99):EndIf
StringArray(aItem) = aString + ElementStart
aItem + 1
PokeW(aString + ElementStart + ElementSize, 0)
ElementStart + ElementSize + DelimitersSize
String2 + DelimitersSize
Until String2 = DelimitersSize
If ElementSize = StringSize
FreeMemory(aString)
If ArraySize(StringArray())=1
StringArray(0)=@sString
EndIf
ProcedureReturn 0
EndIf
ReDim StringArray(aItem-1)
If ArraySize(StringArray())=0
StringArray(0)=@sString
EndIf
ProcedureReturn aString
EndProcedure
Procedure.s makeParsebleNumber(value.s,post.s="",prefix.s="")
Protected result.s=Trim(ReplaceString(Value,#DQUOTE$,""))
If post<>""
result=ReplaceString(result,post,"")
EndIf
If prefix<>""
result=ReplaceString(result,prefix,"")
EndIf
Protected pp=FindString(result,".")
Protected kk=FindString(result,",")
If pp<kk
result=ReplaceString(result,".","")
result=ReplaceString(result,",",".")
Else
result=ReplaceString(result,",","")
EndIf
ProcedureReturn Trim(result)
EndProcedure
Procedure.d extValD(value.s,post.s="",prefix.s="")
Protected result.s=makeParsebleNumber(value)
ProcedureReturn ValD(Trim(result))
EndProcedure
Procedure.f extValF(value.s,post.s="",prefix.s="")
Protected result.s=makeParsebleNumber(value)
ProcedureReturn ValF(Trim(result))
EndProcedure
Procedure.b isLong(value.s)
ProcedureReturn Bool(Str(Val(value))=value)
EndProcedure
A 'normal' string is a pointer to a pointer to a memory area. Every time you change the string, this memory area is newly allocated.Tristano wrote:... I wonder if it has any benefits over "normal" strings.
With a fixed string you can use the full specified length. A reservation for a null terminator is not necessary. However, you can make the string shorter by using a null terminator.Tristano wrote:Since the ".s{Length}" is a fixed width string, does it use Zero terminator? or does it store it's length somewhere?
I believe it's only reallocated when necessary, not every time.A 'normal' string is a pointer to a pointer to a memory area. Every time you change the string, this memory area is newly allocated.