Tom Del Rosso
2021-09-01 19:30:18 UTC
Here's a subroutine to get the length of a string that uses successive
approximation so it runs very fast because it only loops 13 times (once
for each bit of the resulting number) no matter how long the string is.
:GetStringLength
rem Takes string variable NAME which must have no spaces. Returns
variable: StringLength
rem Environment variables go up to 8191 characters so approximation
starts with 4096 which is the MSB.
rem Practical limit is 8185 because "set x=" has 6 characters
if [%1]==[] set "StringLength=" & goto :eof
if not defined %1 set /a StringLength=0 & goto :eof
set /a GetStringLength_PlaceValue=4096
set /a GetStringLength_Guess=0
:GetStringLength_Loop
set /a GetStringLength_Guess^|=GetStringLength_PlaceValue
set /a GetStringLength_Skip=GetStringLength_Guess-1
call set "GetStringLength_Char=%%%1:~%GetStringLength_Skip%,1%%"
if not defined GetStringLength_Char set /a
GetStringLength_Guess^^=GetStringLength_PlaceValue
set /a GetStringLength_PlaceValue/=2
if %GetStringLength_PlaceValue% GTR 0 goto :GetStringLength_Loop
set /a StringLength=GetStringLength_Guess
set "GetStringLength_String="
set "GetStringLength_PlaceValue="
set "GetStringLength_Guess="
set "GetStringLength_Skip="
set "GetStringLength_Char="
goto :eof
approximation so it runs very fast because it only loops 13 times (once
for each bit of the resulting number) no matter how long the string is.
:GetStringLength
rem Takes string variable NAME which must have no spaces. Returns
variable: StringLength
rem Environment variables go up to 8191 characters so approximation
starts with 4096 which is the MSB.
rem Practical limit is 8185 because "set x=" has 6 characters
if [%1]==[] set "StringLength=" & goto :eof
if not defined %1 set /a StringLength=0 & goto :eof
set /a GetStringLength_PlaceValue=4096
set /a GetStringLength_Guess=0
:GetStringLength_Loop
set /a GetStringLength_Guess^|=GetStringLength_PlaceValue
set /a GetStringLength_Skip=GetStringLength_Guess-1
call set "GetStringLength_Char=%%%1:~%GetStringLength_Skip%,1%%"
if not defined GetStringLength_Char set /a
GetStringLength_Guess^^=GetStringLength_PlaceValue
set /a GetStringLength_PlaceValue/=2
if %GetStringLength_PlaceValue% GTR 0 goto :GetStringLength_Loop
set /a StringLength=GetStringLength_Guess
set "GetStringLength_String="
set "GetStringLength_PlaceValue="
set "GetStringLength_Guess="
set "GetStringLength_Skip="
set "GetStringLength_Char="
goto :eof