- I'm grateful for your interesting and comprehensive summary.
- Here's how I've seen the situation:
- I was happy with VarSetCapacity for *structs*.
- I wanted 'StrSetCapacity' or similar, for *big strings*: to remove the A_IsUnicode check, for readability, and for clarifying where structs/big strings had been created.
- I had written something similar to BufferAlloc, but still preferred VarSetCapacity 99% of the time:
- Func(&vData+4) beats Func(oData.Ptr+4) for readability, for functions that need pointers (only NumGet/NumPut have an Offset parameter).
- ... I'd be happy to rewrite old code for a benefit, or even where it's cost neutral, but removing & and adding .Ptr etc in every script would be painstaking/careful work for less readable code.
- I almost never need to pass binary data around a script. And can use XXXPut/XXXGet functions to achieve this.
- I have never needed a safety check of address plus size. So for me, that doesn't count as an argument.
- (I'm not too fond of 'smart parameters', e.g. NumPut/NumGet/StrPut/StrGet. Something which BufferAlloc appears to be encouraging the use of: a separate Offset parameter. I'd rather parameters had a consistent location, and were either used or not used. Are they common in any programming languages? Does the parameter checking affect performance? I'd considered A_ZBIndex/A_ZeroIndex, as an aid to removing the NumGet/NumPut Offset parameter.)
- If VarSetCapacity were removed, I might create 'VarSetSize' (or 'StrSetSize') like so:
Code: Select all
JEE_VarSetSize(ByRef vVar, oParams*)
{
if oParams.Length()
{
vSize := oParams.1
vFillByte := oParams.2 ? oParams.2 : 0
vChars := Ceil(vSize / (A_IsUnicode?2:1))
vVar := Format("{:" vChars "}", "")
DllCall("ntdll\RtlFillMemory", "Ptr",&vVar, "UPtr",vSize, "UChar",vFillByte)
}
return StrLen(vVar)*(A_IsUnicode?2:1)
}
JEE_VarSetSize(vData, 16)
MsgBox(JEE_VarSetSize(vData))
- Something like that would be useful built-in, or VarSetCapacity maintained, to clearly signal when structs were created, or if need be:
Code: Select all
;if StrRept and A_ChrSize were added:
vData := StrRept("_", vSize/A_ChrSize+1)
- A key need re. data is handling for hex/base64.
- Would it be worth submitting these as pull requests?
- Otherwise you're welcome to adapt the code or suggest edits in the thread.
C++: AHK source code: Base64Get/Base64Put and HexGet/HexPut - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=75&t=64694
- I think that rearranging the order of the NumPut parameters would be a bit of a 'disaster', and forum members would be dealing with the confusion forever afterwards.
- I would suggest an additional function be created if desired.
- One alternative, would be to allow the Number parameter (and Type parameter) to accept an array.
NumPut(Number, VarOrAddress [, Offset := 0][, Type := "UPtr"])
- E.g. Number [1, 2, 3, 4], plus Type "Int" would write 4 Ints.
The use of VarSetCapacity is a very minor thing to update, with clear benefits. No one has to update VarSetCapacity or anything else in their old scripts, unless they want to use v2.
...
Notice I only changed the first line, removed & and replaced + with ,.
- Replacing strings with Buffer objects, is probably the most involved automated conversion task I've yet to see. It would affect VarSetCapacity/DllCall/NumGet/NumPut/custom function calls and other miscellaneous lines. Any dynamic references to variables adding to the complexity.
- I did the cost-benefit analysis, and decided it's better to use string buffers to store binary data, 99% of the time. E.g. as mentioned above, it would just decrease script readability to convert the scripts.
- I fully welcome the addition of BufferAlloc, e.g. for passing binary data via function return values, and for passing pointers instead of data.
- One curio, oBuffer[4] might be handy cf. oBuffer.Ptr+4, although possibly this idea was already in the aether.
- I'd be interested in any advantages of StrBuffer over current string handling, but am fine with the current string functionality.