Jump to content

Recommended Posts

Posted (edited)

How about using MSDN CharLowerBuff function for AutoIt function StringLower (same for CharUpperBuff function and StringUpper)

Before:

StringLower ( "string" )
After:

StringLower ( "string", stringlen )

StringLower( "string", 0 or empty ) ;=> lowercase all
StringLower( "string", X >= 0 )     ;=> lowercase x chars
So there are no changes for old scripts

Ref:

'?do=embed' frameborder='0' data-embedContent>>

CharLowerBuff:

$string = "UPPER_TO_LOWER"
$length = 5

$ret = DllCall("user32.dll", "DWORD", "CharLowerBuff", "str", $string, "DWORD", $length)

MsgBox(0, "CharLowerBuff()", $ret[1])    ; ==> upper_TO_LOWER
Edited by kaesereibe
Posted

Convince/educate me. :) What is the advantage over the current string manipulation methods? Couldn't this just be created as a UDF function? How many people are going to benefit from making such a change?

Posted (edited)

There were three questions, and not doing it (if you don't want) would also be backwards compatible. :rolleyes: I'm not saying it's a bad idea - I just need convincing that it's worth the effort.

Edited by czardas
Posted (edited)

I talk and I have example.

There are which is suit the case and also which is doesn't suit the case.

For an example manipulation string where that string to be manipulated are reside

on buffer or pointer to string then what are you doing maybe is can be right. By

eliminating DllStructGetData and DllStructSetData.

When your manipulation like upercassing or lowercasing on all of it or in the middle

of string then stringmid, string prepend and append expression can be eliminated.

Usage it on windowproc is the recommended way or the another recommend are

when you build an text editor one level up from scratch by general with usage tons

of function manipulation borrowed from some library.

By that reason then why not, and if your reason doesn't meet my criteria then

I tell you maybe now is not the time you playing with these. Wait for and you see

the another time the one that I gave you maybe useful.

This are part of my unpublished UDF.

Sample how to usage are script on below, yes scroll down until very bottom.

The output text are tested with AutoIt3 v3.3.10.2.

.

;===== RTLCODE == RTLCODE == RTLCODE == RTLCODE == RTLCODE == RTLCODE == RTLCODE == RTLCODE == RTLCODE =====
;================================================= Corefx.RTL.au3 ==========================================

Global Const _
$__intptr = (@AutoItX64) ? ('Int64') : ('Int32'), _
$__invptr = (@AutoItX64) ? ('Int32') : ('Int64'), _
$__kernel = __rtl_module1('kernel32.dll'), _
$__fnaddr = __rtl_fnaddr(), _
$__krngma = __rtl_krngma(), _
$__ntdll  = __rtl_module('ntdll.dll'), _
$__strlen = __rtl_strlen(), _
$__wcslen = __rtl_wcslen(), _
$__user  = __rtl_module('user32.dll')

Global _
$__pragma

Func __pragma_link($_)
   If IsFunc($_) Then $_ = FuncName($_)
   If IsPtr($_) Then
      If $_ <> 0 Then
         $__pragma = $_
         Return
         EndIf
      Return SetError(1, 0, 0)
      EndIf
   Switch $_
      Case 'ntdll'
      $__pragma = $__ntdll
      Case 'kernel32'
      $__pragma = $__kernel
      Case 'user32'
      $__pragma = $__user
      Case Else
         Local $v = 'MOD_' & $_
         $__pragma = eval($v)
      EndSwitch
EndFunc

Func __rtl_module1($_)
   Local $r = DllCall('kernel32.dll', 'ptr', 'GetModuleHandleA', 'str', $_)
   Return $r[0]
EndFunc

func __rtl_module($_)
   Local $r = DllCallAddress('ptr', $__krngma, 'str', $_)
   Return $r[0]
endfunc

func __rtl_krngma()
   Local $r = DllCallAddress('ptr', $__fnaddr, 'ptr', $__kernel, 'str', 'GetModuleHandleA')
   Return $r[0]
endfunc

Func __rtl_fnaddr()
   Local $r = DllCall('kernel32.dll', 'ptr', 'GetProcAddress', 'ptr', $__kernel, 'str', 'GetProcAddress')
   If @error Or $r[0] = 0 Then Return SetError(1, 0, 0)
   Return $r[0]
EndFunc

Func __name__($_, $F = 33)
   Local $r = DllCallAddress('ptr', $__fnaddr, 'ptr', $__pragma, 'str', $_)
;~    If $r[0] = 0 Then
;~    If IsFunc($F) Then $F = $F()

;~    If $_cor_dbg_osver <> 0 Then
;~    If $_cor_dbg_osver >= $F Then
;~       ConsoleWrite("! __pragma_link . __name__('" & $_ & "')" & '  ' & $_cor_dbg_osver & '  ' & $F & @CR)
;~       EndIf
;~       EndIf
;~    EndIf
   Return $r[0]
EndFunc

Func __rtl_acoracs(ByRef $v, ByRef $x, ByRef $_)
   Switch VarGetType($_)
      Case 'ptr'
         $v = 'ptr'
         $x = $v
      Case $__intptr
         If $_ >= 0 And $_ <= 255 Then
            $v = 'byte'
            Else
            $v = 'ptr'
            EndIf
            $x = $v
      Case $__invptr
         If $_ >= 0 And $_ <= 255 Then
            $v = 'byte'
            $x = $v
            Else
            If $__invptr = 'int64' Then
               $v = 'ptr'
               $_ = int64toptr($_)
               Else
               Return SetError(1, 0, 0)
               EndIf
            EndIf
      Case 'String'
         If StringLen($_) = 1 Then
            $v = 'byte'
            $_ = Asc($_)
            Else
            $v = 'str'
            EndIf
         $x = $v
      Case 'DLLStruct'
         $v = 'ptr'
         $x = 'struct*'
      EndSwitch
EndFunc

Func __rtl_wcorwcs(ByRef $v, ByRef $x, ByRef $_)
   Switch VarGetType($_)
      Case 'ptr'
         $v = 'ptr'
         $x = $v
      Case $__intptr
         If $_ >= 0 And $_ <= 255 Then
            $v = 'byte'
            Else
            $v = 'ptr'
            EndIf
            $x = $v
      Case $__invptr
         If $_ >= 0 And $_ <= 255 Then
            $v = 'word'
            $x = $v
            Else
            If $__invptr = 'int64' Then
               $v = 'ptr'
               $_ = int64toptr($_)
               Else
               Return SetError(1, 0, 0)
               EndIf
            EndIf
      Case 'String'
         If StringLen($_) = 1 Then
            $v = 'word'
            $_ = AscW($_)
            Else
            $v = 'wstr'
            EndIf
         $x = $v
      Case 'DLLStruct'
         $v = 'ptr'
         $x = 'struct*'
      EndSwitch
EndFunc

Func rtl_strlen($_)
   Local $r = DllCallAddress('uint_ptr:cdecl', $__strlen, _a_($_), $_)
   Return $r[0]
EndFunc

Func rtl_wcslen($_)
   Local $r = DllCallAddress('uint_ptr:cdecl', $__wcslen, _w_($_), $_)
   Return $r[0]
EndFunc

func __rtl_strlen()
   Local $r = DllCallAddress('ptr', $__fnaddr, 'ptr', $__ntdll, 'str', 'strlen')
   Return $r[0]
endfunc

func __rtl_wcslen()
   Local $r = DllCallAddress('ptr', $__fnaddr, 'ptr', $__ntdll, 'str', 'wcslen')
   Return $r[0]
endfunc

Func user32()
   Return $__user
EndFunc

Func int64toptr($i64)
   Local $t64, $t32, $l32, $h32
   $t64 = DllStructCreate('int64')
   DllStructSetData($t64,1, $i64)
   $t32 = DllStructCreate('ptr;int', DllStructGetPtr($t64))
   $h32 = DllStructGetData($t32,2)
   Return ($h32 = -1 Or $h32 = 0)?(DllStructGetData($t32,1)):(Ptr(0))
EndFunc

; AnsiChar-String pass type
func _a_(byref Const $lpString)
   switch vargettype($lpString)
      case 'Ptr', $__intptr, $__invptr
         return 'ptr'
      case 'String'
         return 'str'
      case 'DLLStruct'
         return 'struct*'
      endswitch
endfunc

; WideChar-String pass type
func _w_(byref Const $lpString)
   switch vargettype($lpString)
      case 'Ptr', $__intptr, $__invptr
         return 'ptr'
      case 'String'
         return 'wstr'
      case 'DLLStruct'
         return 'struct*'
      endswitch
endfunc

Func addrof($_)
   Return DllStructGetPtr($_)
EndFunc

;===== UDFCODE == UDFCODE == UDFCODE == UDFCODE == UDFCODE == UDFCODE == UDFCODE == UDFCODE == UDFCODE =====
;======================= WinUser.WinUI.WindowsUserInterface.Resources.Strings.au3 ==========================

__pragma_link ( user32 )
Global Const _
$ptr_user32_CharLowerA = __name__('CharLowerA'), _
$ptr_user32_CharLowerW = __name__('CharLowerW'), _
$ptr_user32_CharUpperA = __name__('CharUpperA'), _
$ptr_user32_CharUpperW = __name__('CharUpperW'), _
$ptr_user32_CharLowerBuffA = __name__('CharLowerBuffA'), _
$ptr_user32_CharLowerBuffW = __name__('CharLowerBuffW'), _
$ptr_user32_CharUpperBuffA = __name__('CharUpperBuffA'), _
$ptr_user32_CharUpperBuffW = __name__('CharUpperBuffW')

Func WinAPI_CharLowerA($lpsz)
   Local $v, $x
   __rtl_acoracs($v, $x, $lpsz)
   If @error Then Return SetError(1, 0, '')
   Local $r = DllCallAddress($v, $ptr_user32_CharLowerA, $x, $lpsz)
   If @error Then Return SetError(1, 0, 0)
   Return (IsNumber($r[0]))?(Chr($r[0])):($r[0])
EndFunc

Func WinAPI_CharLowerW($lpsz)
   Local $v, $x
   __rtl_wcorwcs($v, $x, $lpsz)
   If @error Then Return SetError(1, 0, '')
   Local $r = DllCallAddress($v, $ptr_user32_CharLowerW, $x, $lpsz)
   If @error Then Return SetError(1, 0, 0)
   Return (IsNumber($r[0]))?(ChrW($r[0])):($r[0])
EndFunc

Func WinAPI_CharUpperA($lpsz)
   Local $v, $x
   __rtl_acoracs($v, $x, $lpsz)
   If @error Then Return SetError(1, 0, '')
   Local $r = DllCallAddress($v, $ptr_user32_CharUpperA, $x, $lpsz)
   If @error Then Return SetError(1, 0, 0)
   Return (IsNumber($r[0]))?(Chr($r[0])):($r[0])
EndFunc

Func WinAPI_CharUpperW($lpsz)
   Local $v, $x
   __rtl_wcorwcs($v, $x, $lpsz)
   If @error Then Return SetError(1, 0, '')
   Local $r = DllCallAddress($v, $ptr_user32_CharUpperA, $x, $lpsz)
   If @error Then Return SetError(1, 0, '')
   Return (IsNumber($r[0]))?(ChrW($r[0])):($r[0])
EndFunc

Func WinAPI_CharLowerBuffA($lpsz, $cchLength)
   Local $r = DllCallAddress('dword', $ptr_user32_CharLowerBuffA, _a_($lpsz), $lpsz, 'dword', $cchLength)
   If @error Then Return SetError(1, 0, 0)
   Return $r[0]
EndFunc

Func WinAPI_CharLowerBuffW($lpsz, $cchLength = -1)
   Local $r = DllCallAddress('dword', $ptr_user32_CharLowerBuffW, _w_($lpsz), $lpsz, 'dword', $cchLength)
   If @error Then Return SetError(1, 0, 0)
   Return $r[0]
EndFunc

Func WinAPI_CharUpperBuffA($lpsz, $cchLength)
   Local $r = DllCallAddress('dword', $ptr_user32_CharUpperBuffA, _a_($lpsz), $lpsz, 'dword', $cchLength)
   If @error Then Return SetError(1, 0, 0)
   Return $r[0]
EndFunc

Func WinAPI_CharUpperBuffW($lpsz, $cchLength)
   Local $r = DllCallAddress('dword', $ptr_user32_CharUpperBuffW, _w_($lpsz), $lpsz, 'dword', $cchLength)
   If @error Then Return SetError(1, 0, 0)
   Return $r[0]
EndFunc

;===== USERCODE == USERCODE == USERCODE == USERCODE == USERCODE == USERCODE == USERCODE == USERCODE =====

; AnsiChar <delphi>, char <C/C++>

ConsoleWrite('WinAPI_CharLowerA     -> ' & WinAPI_CharLowerA('A') & @CRLF)
ConsoleWrite('WinAPI_CharUpperA     -> ' & WinAPI_CharUpperA('a') & @CRLF)
ConsoleWrite('WinAPI_CharLowerA     -> ' & WinAPI_CharLowerA(asc('A')) & @CRLF)
ConsoleWrite('WinAPI_CharUpperA     -> ' & WinAPI_CharUpperA(asc('a')) & @CRLF)

; AnsiCharString <delphi>, lpstr, char* <C/C++>

; LowerCase AnsiString
$sttest = DllStructCreate('char ourstr[60]')
$sttest.ourstr = 'LOWERCASE'
WinAPI_CharLowerA($sttest)
ConsoleWrite('WinAPI_CharLowerA     -> ' & $sttest.ourstr & @CRLF)

; UpperCase AnsiString
$sttest = DllStructCreate('char ourstr[60]')
$sttest.ourstr = 'uppercase'
WinAPI_CharUpperA($sttest)
ConsoleWrite('WinAPI_CharUpperA     -> ' & $sttest.ourstr & @CRLF)

; All LowerCase
$sttest = DllStructCreate('char ourstr[60]')
$sttest.ourstr = 'THE QUICK BROWN FOX JUMP OVER LAZY DOG.'
WinAPI_CharLowerBuffA($sttest, rtl_strlen($sttest))
ConsoleWrite('WinAPI_CharLowerBuffA -> ' & $sttest.ourstr & @CRLF)

; Partial LowerCase
$sttest = DllStructCreate('char ourstr[60]')
$sttest.ourstr = 'THE QUICK BROWN FOX JUMP OVER LAZY DOG.'
WinAPI_CharLowerBuffA(addrof($sttest) + 6, rtl_strlen($sttest)-12)
ConsoleWrite('WinAPI_CharLowerBuffA -> ' & $sttest.ourstr & @CRLF)

; All UpperCase
$sttest = DllStructCreate('char ourstr[60]')
$sttest.ourstr = 'The quick brown fox jump over lazy dog.'
WinAPI_CharUpperBuffA($sttest, rtl_strlen($sttest))
ConsoleWrite('WinAPI_CharUpperBuffA -> ' & $sttest.ourstr & @CRLF)

; Partial UpperCase
$sttest = DllStructCreate('char ourstr[60]')
$sttest.ourstr = 'The quick brown fox jump over lazy dog.'
WinAPI_CharUpperBuffA(addrof($sttest) + 6, rtl_strlen($sttest)-12)
ConsoleWrite('WinAPI_CharUpperBuffA -> ' & $sttest.ourstr & @CRLF)



; WideChar <delphi>, wchar_t <C/C++>

ConsoleWrite('WinAPI_CharLowerW     -> ' & WinAPI_CharLowerW('W') & @CRLF)
ConsoleWrite('WinAPI_CharUpperW     -> ' & WinAPI_CharUpperW('w') & @CRLF)
ConsoleWrite('WinAPI_CharLowerW     -> ' & WinAPI_CharLowerW(ascw('W')) & @CRLF)
ConsoleWrite('WinAPI_CharUpperW     -> ' & WinAPI_CharUpperW(ascw('w')) & @CRLF)

; WideCharString <delphi>, lpwstr, wchar_t* <C/C++>

; LowerCase WideString
$sttest = DllStructCreate('wchar ourstr[60]')
$sttest.ourstr = 'LOWERCASE'
WinAPI_CharLowerW($sttest)
ConsoleWrite('WinAPI_CharLowerW     -> ' & $sttest.ourstr & @CRLF)

; UpperCase WideString
$sttest = DllStructCreate('wchar ourstr[60]')
$sttest.ourstr = 'uppercase'
WinAPI_CharUpperW($sttest)
ConsoleWrite('WinAPI_CharUpperW     -> ' & $sttest.ourstr & @CRLF)

; All LowerCase
$sttest = DllStructCreate('wchar ourstr[60]')
$sttest.ourstr = 'THE QUICK BROWN FOX JUMP OVER LAZY DOG.'
WinAPI_CharLowerBuffW($sttest, rtl_wcslen($sttest))
ConsoleWrite('WinAPI_CharLowerBuffW -> ' & $sttest.ourstr & @CRLF)

; Partial LowerCase
$sttest = DllStructCreate('wchar ourstr[60]')
$sttest.ourstr = 'THE QUICK BROWN FOX JUMP OVER LAZY DOG.'
WinAPI_CharLowerBuffW(addrof($sttest) + 6, rtl_wcslen($sttest)-12)
ConsoleWrite('WinAPI_CharLowerBuffW -> ' & $sttest.ourstr & @CRLF)

; All UpperCase
$sttest = DllStructCreate('wchar ourstr[60]')
$sttest.ourstr = 'The quick brown fox jump over lazy dog.'
WinAPI_CharUpperBuffW($sttest, rtl_wcslen($sttest))
ConsoleWrite('WinAPI_CharUpperBuffW -> ' & $sttest.ourstr & @CRLF)

; Partial UpperCase
$sttest = DllStructCreate('wchar ourstr[60]')
$sttest.ourstr = 'The quick brown fox jump over lazy dog.'
WinAPI_CharUpperBuffW(addrof($sttest) + 6, rtl_wcslen($sttest)-12)
ConsoleWrite('WinAPI_CharUpperBuffW -> ' & $sttest.ourstr & @CRLF)

.

Output:

.

>"C:\Program Files (x86)\AutoIt3\SciTE\..\autoit3.exe" /ErrorStdOut "F:\CoreFXP\Sample.String\this.au3"    
WinAPI_CharLowerA     -> a
WinAPI_CharUpperA     -> A
WinAPI_CharLowerA     -> a
WinAPI_CharUpperA     -> A
WinAPI_CharLowerA     -> lowercase
WinAPI_CharUpperA     -> UPPERCASE
WinAPI_CharLowerBuffA -> the quick brown fox jump over lazy dog.
WinAPI_CharLowerBuffA -> THE QUick brown fox jump over lazY DOG.
WinAPI_CharUpperBuffA -> THE QUICK BROWN FOX JUMP OVER LAZY DOG.
WinAPI_CharUpperBuffA -> The quICK BROWN FOX JUMP OVER LAZy dog.
WinAPI_CharLowerW     -> w
WinAPI_CharUpperW     -> W
WinAPI_CharLowerW     -> w
WinAPI_CharUpperW     -> W
WinAPI_CharLowerW     -> lowercase
WinAPI_CharUpperW     -> Uppercase
WinAPI_CharLowerBuffW -> the quick brown fox jump over lazy dog.
WinAPI_CharLowerBuffW -> THE quick brown fox jump over LAZY DOG.
WinAPI_CharUpperBuffW -> THE QUICK BROWN FOX JUMP OVER LAZY DOG.
WinAPI_CharUpperBuffW -> The QUICK BROWN FOX JUMP OVER lazy dog.
>Exit code: 0    Time: 0.141
Edited by prazetto

# Button. Progressbar - Graphical AutoIt3 Control (UDF) # GTK on AutoIt3 - GTK+ Framework | Widgets

cig computer instruction graphics  http://code.hstn.me

Posted

Sure, there is value in moving the native AutoIt functions to UDFs, under the right circumstances and for the right reasons. What we could do is move basic AutoIt functions to UDFs. GUI, Strings, networking (TCP/UDP), etc. then include it all together in a compatibility library which older scripts can include as they migrate to the new version.

Currently the main benefit of doing that is that we open source the UDFs so everyone can work on them, and I'm sure that if you built a GUI or networking UDF which is backwards compatible and better than the current native implementation, we'd definitely use it.

For strings, AutoIt is obviously too slow to make that sort of transition useful right now. Though I haven't measured it, I assume that even a single DllCall will be an order of magnitude slower than a call to the native StringLower. We have been debating about whether we should build a compiler for AutoIt for as long as I've been a member on these forums mainly for the speed benefit, and if we did, strings would definitely be up for inclusion in a backwards compatibility library.

Posted (edited)

@Manadar

What are you saying is exactly right, and for sure you are know about this than another user.

Then allow me to describe to other.

DLLCall("libraryname.dll"..

is slower than

Global $mlibraryname = DllOpen("libraryname.dll")

DLLCall($mlibraryname...

is slower than

DLLCallAddress(..., ptr_function ...

The fastest one is DLLCallAddress! Why?

DLLCall("libraryname.dll".. always increment & decrement reference to library and call GetProcAddress then calling the address pointer.

DLLCall($mlibraryname.. always call GetProcAddress then calling the address pointer.

DLLCallAddress(..., ptr_function ... directly call the address pointer.

DLLCallAddress skip all unnecessary step.

That's why now I'm decided to use DLLCallAddress as wrapper of library function.

However be careful check for null pointer if you not sure if the function are exported

by library or you typed wrongly the symbol name.

This DLLCallAddress function are one of greatest addition feature on AutoIt3.

As for native function of AutoIt3 is hard to beat its speed in simple expression

of string manipulation. But when its complex its can be beaten by another like

calling an library or shellcode or machinecode. But that defeat the point

to writting script on AutoIt3 in the first place if in the end you also write it

in another language. By the way AutoIt3 is always be greatest scripting

language on windows in my heart.

Edited by prazetto

# Button. Progressbar - Graphical AutoIt3 Control (UDF) # GTK on AutoIt3 - GTK+ Framework | Widgets

cig computer instruction graphics  http://code.hstn.me

Posted (edited)

Interesting...

Local $hTimer = 0
Local $sString = "TOLOWER"
Local $iCount = 3
ConsoleWrite(_StringLower($sString, $iCount) & @CRLF)
ConsoleWrite(_WinAPI_CharLowerBuff($sString, $iCount) & @CRLF)

$hTimer = TimerInit()
For $i = 0 To 10000
    _WinAPI_CharLowerBuff($sString, $iCount)
Next
ConsoleWrite(TimerDiff($hTimer) & @CRLF)

$hTimer = TimerInit()
For $i = 0 To 10000
    _StringLower($sString, $iCount)
Next
ConsoleWrite(TimerDiff($hTimer) & @CRLF)

Func _StringLower($sString, $iCount = Default)
    If $iCount = Default Or $iCount < 0 Then $iCount = StringLen($sString)
    Return StringLower(StringLeft($sString, $iCount)) & StringMid($sString, $iCount + 1) ; By Malkey
EndFunc   ;==>_StringLower

Func _WinAPI_CharLowerBuff($sString, $iCount = Default)
    If $iCount = Default Or $iCount <= 0 Then $iCount = StringLen($sString)
    Local $aReturn = DllCall("user32.dll", "dword", "CharLowerBuffW", "wstr", $sString, "dword", $iCount) ; By various
    If @error Or Not $aReturn[0] Then Return SetError(@error, @extended, $sString)
    Return $aReturn[1]
EndFunc   ;==>_WinAPI_CharLowerBuff
Edited by guinness

UDF List:

 
_AdapterConnections()_AlwaysRun()_AppMon()_AppMonEx()_ArrayFilter/_ArrayReduce_BinaryBin()_CheckMsgBox()_CmdLineRaw()_ContextMenu()_ConvertLHWebColor()/_ConvertSHWebColor()_DesktopDimensions()_DisplayPassword()_DotNet_Load()/_DotNet_Unload()_Fibonacci()_FileCompare()_FileCompareContents()_FileNameByHandle()_FilePrefix/SRE()_FindInFile()_GetBackgroundColor()/_SetBackgroundColor()_GetConrolID()_GetCtrlClass()_GetDirectoryFormat()_GetDriveMediaType()_GetFilename()/_GetFilenameExt()_GetHardwareID()_GetIP()_GetIP_Country()_GetOSLanguage()_GetSavedSource()_GetStringSize()_GetSystemPaths()_GetURLImage()_GIFImage()_GoogleWeather()_GUICtrlCreateGroup()_GUICtrlListBox_CreateArray()_GUICtrlListView_CreateArray()_GUICtrlListView_SaveCSV()_GUICtrlListView_SaveHTML()_GUICtrlListView_SaveTxt()_GUICtrlListView_SaveXML()_GUICtrlMenu_Recent()_GUICtrlMenu_SetItemImage()_GUICtrlTreeView_CreateArray()_GUIDisable()_GUIImageList_SetIconFromHandle()_GUIRegisterMsg()_GUISetIcon()_Icon_Clear()/_Icon_Set()_IdleTime()_InetGet()_InetGetGUI()_InetGetProgress()_IPDetails()_IsFileOlder()_IsGUID()_IsHex()_IsPalindrome()_IsRegKey()_IsStringRegExp()_IsSystemDrive()_IsUPX()_IsValidType()_IsWebColor()_Language()_Log()_MicrosoftInternetConnectivity()_MSDNDataType()_PathFull/GetRelative/Split()_PathSplitEx()_PrintFromArray()_ProgressSetMarquee()_ReDim()_RockPaperScissors()/_RockPaperScissorsLizardSpock()_ScrollingCredits_SelfDelete()_SelfRename()_SelfUpdate()_SendTo()_ShellAll()_ShellFile()_ShellFolder()_SingletonHWID()_SingletonPID()_Startup()_StringCompact()_StringIsValid()_StringRegExpMetaCharacters()_StringReplaceWholeWord()_StringStripChars()_Temperature()_TrialPeriod()_UKToUSDate()/_USToUKDate()_WinAPI_Create_CTL_CODE()_WinAPI_CreateGUID()_WMIDateStringToDate()/_DateToWMIDateString()Au3 script parsingAutoIt SearchAutoIt3 PortableAutoIt3WrapperToPragmaAutoItWinGetTitle()/AutoItWinSetTitle()CodingDirToHTML5FileInstallrFileReadLastChars()GeoIP databaseGUI - Only Close ButtonGUI ExamplesGUICtrlDeleteImage()GUICtrlGetBkColor()GUICtrlGetStyle()GUIEventsGUIGetBkColor()Int_Parse() & Int_TryParse()IsISBN()LockFile()Mapping CtrlIDsOOP in AutoItParseHeadersToSciTE()PasswordValidPasteBinPosts Per DayPreExpandProtect GlobalsQueue()Resource UpdateResourcesExSciTE JumpSettings INISHELLHOOKShunting-YardSignature CreatorStack()Stopwatch()StringAddLF()/StringStripLF()StringEOLToCRLF()VSCROLLWM_COPYDATAMore Examples...

Updated: 22/04/2018

Posted

The "native" version i.e. the one using string functions, came out on top for me too.

UDF List:

 
_AdapterConnections()_AlwaysRun()_AppMon()_AppMonEx()_ArrayFilter/_ArrayReduce_BinaryBin()_CheckMsgBox()_CmdLineRaw()_ContextMenu()_ConvertLHWebColor()/_ConvertSHWebColor()_DesktopDimensions()_DisplayPassword()_DotNet_Load()/_DotNet_Unload()_Fibonacci()_FileCompare()_FileCompareContents()_FileNameByHandle()_FilePrefix/SRE()_FindInFile()_GetBackgroundColor()/_SetBackgroundColor()_GetConrolID()_GetCtrlClass()_GetDirectoryFormat()_GetDriveMediaType()_GetFilename()/_GetFilenameExt()_GetHardwareID()_GetIP()_GetIP_Country()_GetOSLanguage()_GetSavedSource()_GetStringSize()_GetSystemPaths()_GetURLImage()_GIFImage()_GoogleWeather()_GUICtrlCreateGroup()_GUICtrlListBox_CreateArray()_GUICtrlListView_CreateArray()_GUICtrlListView_SaveCSV()_GUICtrlListView_SaveHTML()_GUICtrlListView_SaveTxt()_GUICtrlListView_SaveXML()_GUICtrlMenu_Recent()_GUICtrlMenu_SetItemImage()_GUICtrlTreeView_CreateArray()_GUIDisable()_GUIImageList_SetIconFromHandle()_GUIRegisterMsg()_GUISetIcon()_Icon_Clear()/_Icon_Set()_IdleTime()_InetGet()_InetGetGUI()_InetGetProgress()_IPDetails()_IsFileOlder()_IsGUID()_IsHex()_IsPalindrome()_IsRegKey()_IsStringRegExp()_IsSystemDrive()_IsUPX()_IsValidType()_IsWebColor()_Language()_Log()_MicrosoftInternetConnectivity()_MSDNDataType()_PathFull/GetRelative/Split()_PathSplitEx()_PrintFromArray()_ProgressSetMarquee()_ReDim()_RockPaperScissors()/_RockPaperScissorsLizardSpock()_ScrollingCredits_SelfDelete()_SelfRename()_SelfUpdate()_SendTo()_ShellAll()_ShellFile()_ShellFolder()_SingletonHWID()_SingletonPID()_Startup()_StringCompact()_StringIsValid()_StringRegExpMetaCharacters()_StringReplaceWholeWord()_StringStripChars()_Temperature()_TrialPeriod()_UKToUSDate()/_USToUKDate()_WinAPI_Create_CTL_CODE()_WinAPI_CreateGUID()_WMIDateStringToDate()/_DateToWMIDateString()Au3 script parsingAutoIt SearchAutoIt3 PortableAutoIt3WrapperToPragmaAutoItWinGetTitle()/AutoItWinSetTitle()CodingDirToHTML5FileInstallrFileReadLastChars()GeoIP databaseGUI - Only Close ButtonGUI ExamplesGUICtrlDeleteImage()GUICtrlGetBkColor()GUICtrlGetStyle()GUIEventsGUIGetBkColor()Int_Parse() & Int_TryParse()IsISBN()LockFile()Mapping CtrlIDsOOP in AutoItParseHeadersToSciTE()PasswordValidPasteBinPosts Per DayPreExpandProtect GlobalsQueue()Resource UpdateResourcesExSciTE JumpSettings INISHELLHOOKShunting-YardSignature CreatorStack()Stopwatch()StringAddLF()/StringStripLF()StringEOLToCRLF()VSCROLLWM_COPYDATAMore Examples...

Updated: 22/04/2018

Posted (edited)

I'm still trying to figure out what practical use this might have. Sure it has specific use, but for what I don't know. What language / variant is front case loaded? I can't even find words to descriibe the concept. Why do this at all? Do not say because it's possible (I'm not buying that). I'm guessing there must be a reason for someone to have spent time designing this: I just don't have a clue what that reason might be - none whatsoever!

Edited by czardas
Posted (edited)

@guinness

As developer you are playing unfair, thats your script is not fair and square.
My performance test showing in another different result.

Uh, no is complete reverse of your script. :)

@czardas
Its not so different because the two are do same thing. Just where is suit you place it
on implementing in your script. If its AutoIt3 string then we all know to usage Native
AutoIt3 function are the best way but when its are another then its also another case.

.

Global $p_CharLowerBuffW = GetAddr('user32.dll', 'CharLowerBuffW')

; Lets assume and think in your head we already have these string in memory that created
; by another library. However in this test we artificially generate lpwstr by AutoIt3.

$twstr = DllStructCreate('wchar str[61]')
$twstr.str = "BBBBBCCCCCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBBBCCCCCC"
$pwstr = DllStructGetPtr($twstr)

PStringLowerMidNativeW($pwstr, 10, 50, 60)
ConsoleWrite($twstr.str & @CRLF)

$twstr = DllStructCreate('wchar str[61]')
$twstr.str = "BBBBBCCCCCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBBBCCCCCC"
$pwstr = DllStructGetPtr($twstr)

PStringLowerMidWinapiW($pwstr, 10, 50, 60)
ConsoleWrite($twstr.str & @CRLF)

Global $twstrarray[9999999]
Global $lpstrarray[9999999]

; create 1600 job to be lowercased on the middle of string
; for first 800 shall take care by native and last 800 shall take care by winapi
For $loop = 0 To 1600
   $twstrarray[$loop] = DllStructCreate('wchar str[61]')
   $twstrarray[$loop].str = "BBBBBCCCCCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBBBCCCCCC"
   $lpstrarray[$loop] = DllStructGetPtr($twstrarray[$loop])
   Next

Local $hTimer = 0

$hTimer = TimerInit()
For $loop = 0 To 799 ; 800 first job take care by native
    PStringLowerMidNativeW($lpstrarray[$loop], 10, 50, 60)
Next
$timediff1 = TimerDiff($hTimer)
ConsoleWrite('PStringLowerMidNativeW --> ' & $timediff1 & @CRLF)

$hTimer = TimerInit()
For $loop = 799 To 1600 ; 800 last job take care by winapi
    PStringLowerMidWinapiW($lpstrarray[$loop], 10, 50, 60)
Next
$timediff2 = TimerDiff($hTimer)
ConsoleWrite('PStringLowerMidWinapiW --> ' & $timediff2 & @CRLF)

StatisticPerf('PStringLowerMidNativeW', 'PStringLowerMidWinapiW', $timediff1, $timediff2)


; Both PStringLowerMidNativeW and PStringLowerMidWinapiW doesn't included
; with memory range check or null_ptr check expression for error, assume
; it all are valid cause this test perormace.

Func PStringLowerMidNativeW($P, $start, $end, $len)
   Local $twstr, $str
   $twstr = DllStructCreate('wchar [' & $len & ']', $P)
   $str = DllStructGetData($twstr, 1)
   $str = StringLeft($str, $start) & StringLower(StringMid($str, $start+1, $end-$start)) & StringRight($str, $len - $end)
   DllStructSetData($twstr, 1, $str)
EndFunc

; remeber we play with wide string, 1 wchar_t is 2 byte in memory
Func PStringLowerMidWinapiW($P, $start, $end, $len)
   DllCallAddress("dword", $p_CharLowerBuffW, "ptr", $P+($start*2), "dword", $end-$start)
EndFunc

Func GetAddr($lib, $symbol)
   Local $user32 = DllCall('kernel32.dll', 'ptr', 'GetModuleHandleA', 'str', $lib)
   Local $addr = DllCall('kernel32.dll', 'ptr', 'GetProcAddress', 'ptr', $user32[0], 'str', $symbol)
   Return $addr[0]
EndFunc

Func StatisticPerf($name1, $name2, $time1, $time2)
   Local $procentage, $comma, $procediff
   If $time1 > $time2 Then
      $procentage = ((($time1-$time2) / $time1) * 100)
      $comma = StringInStr($procentage, '.')
      If $comma > 0 Then
         $procentage = StringLeft($procentage, $comma+ 2)
         EndIf
      $procediff = '±' & $procentage & '%'
      $procentage = '±' & $procentage + 100 & '%'
      ConsoleWrite('! The ' & $name2 & ' ' & $procentage & ' is faster than ' & $name1 & ' with difference ' & $procediff & @CRLF)
      ConsoleWrite('! The ' & $name2 & ' completing job in ' & $time2 & ' mS' & @CRLF)
      ConsoleWrite('! The ' & $name1 & ' completing job in ' & $time1 & ' mS' & @CRLF)
      ConsoleWrite('! The difference beween two are ' & $time1-$time2 & ' mS' & @CRLF)
      EndIf
   If $time2 > $time1 Then
      $procentage = ((($time2-$time1) / $time2) * 100)
      $comma = StringInStr($procentage, '.')
      If $comma > 0 Then
         $procentage = StringLeft($procentage, $comma+ 2)
         EndIf
      $procediff = '±' & $procentage & '%'
      $procentage = '±' & $procentage + 100 & '%'
      ConsoleWrite('! The ' & $name1 & ' ' & $procentage & ' is faster than ' & $name2 & ' with difference ' & $procediff & @CRLF)
      ConsoleWrite('! The ' & $name1 & ' completing job in ' & $time1 & ' mS' & @CRLF)
      ConsoleWrite('! The ' & $name2 & ' completing job in ' & $time2 & ' mS' & @CRLF)
      ConsoleWrite('! The difference beween two are ' & $time2-$time1 & ' mS' & @CRLF)
      EndIf
EndFunc

.

This are output which I tested with AutoIt3 v3.3.10.2 in

Microsoft Windows XP Professional x64 Edition Version 2003 Service Pack 2
Intel® Core2 Duo CPU  E7500  @ 2.93 GHz, 3.74 GB of RAM

.

>"C:\Program Files (x86)\AutoIt3\SciTE\..\autoit3.exe" /ErrorStdOut "C:\Documents and Settings\Administrator\Desktop\yyy.au3"    
BBBBBCCCCCaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaBBBBBCCCCCC
BBBBBCCCCCaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaBBBBBCCCCCC
PStringLowerMidNativeW --> 17.9764865325605
PStringLowerMidWinapiW --> 10.5822212751449
! The PStringLowerMidWinapiW ±141.13% is faster than PStringLowerMidNativeW with difference ±41.13%
! The PStringLowerMidWinapiW completing job in 10.5822212751449 mS
! The PStringLowerMidNativeW completing job in 17.9764865325605 mS
! The difference beween two are 7.39426525741561 mS
>Exit code: 0    Time: 0.336

.

Edited by prazetto

# Button. Progressbar - Graphical AutoIt3 Control (UDF) # GTK on AutoIt3 - GTK+ Framework | Widgets

cig computer instruction graphics  http://code.hstn.me

Posted

ANSI functions are useless with native AutoIt strings.

Also how can few ms difference matter in a function that obviously will not be used in tight loops?

If one intend or need to, say, titlecase a whole text, then I'd bet a regexp (e.g. #2914) will outperform most or all other solutions. Even if it doesn't, it still seems a simpler way of coding than this overly complex subsystem.

Finally your test is very unfair in that it forces the native function to zig-zag with a completely useless structure.

This version is much closer to a practical test:

Global $p_CharLowerBuffW = GetAddr('user32.dll', 'CharLowerBuffW')

; Lets assume and think in your head we already have these string in memory that created
; by another library. However in this test we artificially generate lpwstr by AutoIt3.

Global Const $Kstr = "BBBBBCCCCCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBBBCCCCCC"
Local $str = $Kstr

PStringLowerMidNativeW($str, 10, 50)
ConsoleWrite($str & @CRLF)

$twstr = DllStructCreate('wchar str[' & StringLen($Kstr) + 1 & ']')
$twstr.str = $Kstr
$pwstr = DllStructGetPtr($twstr)

PStringLowerMidWinapiW($pwstr, 10, 50);, StringLen($Kstr))
ConsoleWrite($twstr.str & @CRLF)

Global $twstrarray[800]

; 800 shall take care by native
For $loop = 0 To 799
   $twstrarray[$loop] = $Kstr
Next

Local $hTimer = TimerInit()
For $loop = 0 To 799 ; 800 first job take care by native
    PStringLowerMidNativeW($twstrarray[$loop], 10, 50)
Next
$timediff1 = TimerDiff($hTimer)
ConsoleWrite('PStringLowerMidNativeW --> ' & $timediff1 & @CRLF)

Global $lpstrarray[800]
; 800 shall take care by winapi
For $loop = 0 To 799
   $twstrarray[$loop] = DllStructCreate('wchar str[' & StringLen($Kstr) + 1 & ']')
   $twstrarray[$loop].str = $Kstr
   $lpstrarray[$loop] = DllStructGetPtr($twstrarray[$loop])
Next

$hTimer = TimerInit()
For $loop = 0 To 799 ; 800 last job take care by winapi
    PStringLowerMidWinapiW($lpstrarray[$loop], 10, 50);, StringLen($Kstr))
Next
$timediff2 = TimerDiff($hTimer)
ConsoleWrite('PStringLowerMidWinapiW --> ' & $timediff2 & @CRLF)

StatisticPerf('PStringLowerMidNativeW', 'PStringLowerMidWinapiW', $timediff1, $timediff2)


; Contrary to PStringLowerMidNativeW, and PStringLowerMidWinapiW doesn't include
; memory range check or null_ptr check expression for error, assume
; it all are valid cause this test perormace.

Func PStringLowerMidNativeW(ByRef $str, $start, $end)
   $str = StringLeft($str, $start) & StringLower(StringMid($str, $start + 1, $end - $start)) & StringMid($str, $end + 1)
EndFunc

; remeber we play with wide string, 1 wchar_t is 2 byte in memory
Func PStringLowerMidWinapiW($P, $start, $end)
   DllCallAddress("dword", $p_CharLowerBuffW, "ptr", $P+($start*2), "dword", $end-$start)
EndFunc

Func GetAddr($lib, $symbol)
   Local $user32 = DllCall('kernel32.dll', 'ptr', 'GetModuleHandleA', 'str', $lib)
   Local $addr = DllCall('kernel32.dll', 'ptr', 'GetProcAddress', 'ptr', $user32[0], 'str', $symbol)
   Return $addr[0]
EndFunc

Func StatisticPerf($name1, $name2, $time1, $time2)
   Local $procentage, $comma, $procediff
   If $time1 > $time2 Then
      $procentage = ((($time1-$time2) / $time1) * 100)
      $comma = StringInStr($procentage, '.')
      If $comma > 0 Then
         $procentage = StringLeft($procentage, $comma+ 2)
         EndIf
      $procediff = '±' & $procentage & '%'
      $procentage = '±' & $procentage + 100 & '%'
      ConsoleWrite('! The ' & $name2 & ' ' & $procentage & ' is faster than ' & $name1 & ' with difference ' & $procediff & @CRLF)
      ConsoleWrite('! The ' & $name2 & ' completing job in ' & $time2 & ' mS' & @CRLF)
      ConsoleWrite('! The ' & $name1 & ' completing job in ' & $time1 & ' mS' & @CRLF)
      ConsoleWrite('! The difference beween two are ' & $time1-$time2 & ' mS' & @CRLF)
      EndIf
   If $time2 > $time1 Then
      $procentage = ((($time2-$time1) / $time2) * 100)
      $comma = StringInStr($procentage, '.')
      If $comma > 0 Then
         $procentage = StringLeft($procentage, $comma+ 2)
         EndIf
      $procediff = '±' & $procentage & '%'
      $procentage = '±' & $procentage + 100 & '%'
      ConsoleWrite('! The ' & $name1 & ' ' & $procentage & ' is faster than ' & $name2 & ' with difference ' & $procediff & @CRLF)
      ConsoleWrite('! The ' & $name1 & ' completing job in ' & $time1 & ' mS' & @CRLF)
      ConsoleWrite('! The ' & $name2 & ' completing job in ' & $time2 & ' mS' & @CRLF)
      ConsoleWrite('! The difference beween two are ' & $time2-$time1 & ' mS' & @CRLF)
      EndIf
EndFunc

and unsurprisingly confirms that native functions are faster.

This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.
Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe here
RegExp tutorial: enough to get started
PCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta.

SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.
SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.
An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.
SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)
A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!
SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)

Posted (edited)

@jchd

Maybe I tell you something to convince you.

Are you by any chance kidding me? An then you telling me 'is very unfair in that it forces

the native function to zig-zag with a completely useless structure.'

No, how about if I register 'PStringLowerMidNativeW' with DLLCallBackRegister

and pointer that I got from DllCalbackkGetPtr I passes to an dll library or for

hooking an library do you think AutoIt3 byref are working unless its specified

that requester to do so with passing variant pointer compatible to AutoIt3 data type.

The name that you so called 'completely useless structure' is heart of every WideCharString

(Unicode UTF16) and the  param $P in PStringLowerMidNativeW and PStringLowerMidWinApiW

are param datatype is pwidecharstring (Delphi/Pascal) and wchar_t* or lpwstr (in CC++) .

How dare you change $P to ByRef $str, aren't the prototype become different and is AutoIt3 variant.

And the prefix name for function is P should at least tell you what's is meaning behind it.

#Also how can few ms difference matter in a function that obviously will not be used in tight loops?

Whatcha that is just an example and also I think its not required to gave an example as complex such

as control component of gui written in AutoIt3. The speed is an matter for me with make sure every

function that I usage inside it are the fastest one, that's is all.

#ANSI functions are useless with native AutoIt strings.

Yes, I agree. repeated word that I point to czardas is 'If its AutoIt3 string then we all know to

usage Native AutoIt3 function are the best way but when its are another then its also another case.'

As for caching an variable on non performance test block and passing AutoIt3 string as byref

in performance test block you are more unfair toward me jchd :) Now PStringLowerMidNativeW

and PStringLowerMidWinApiW have different prototype. So what is the point to compare now!?

Edited by prazetto

# Button. Progressbar - Graphical AutoIt3 Control (UDF) # GTK on AutoIt3 - GTK+ Framework | Widgets

cig computer instruction graphics  http://code.hstn.me

Posted

 

'If its AutoIt3 string then we all know to usage Native AutoIt3 function are the best way but when its are another then its also another case.'

Then you're only globalizing a corner case. By far the most common use of string functions is for processing native AutoIt strings.

Making a native style function not use a ByRef argument and simply return it doesn't change the fact that it's still faster and way simpler to handle for beginners.

This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.
Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe here
RegExp tutorial: enough to get started
PCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta.

SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.
SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.
An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.
SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)
A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!
SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...