fxm wrote:
b) 'GET (file I/O)' behavior summary:
- When a real zstring variable (zbuffer) is passed, the behavior should be the same than for a fix-len string (dim as string N ...). So the amount parameter should be forbidden. Instead, it is ignored (except for the '0' value). => NOK
- When a dereferenced zstring pointer (pzbuffer) is passed, the amount parameter is also authorized but seems to be ignored. But to work, the pointed buffer must begin with at least as many non-zero elements as the number of elements to read. => NOK
- When an ubyte (zbuffer[0] or (pzbuffer)[0]) is passed, the behavior is correct with the amount parameter well used. => OK


When the zstring buffer is dynamically allocated, only a 'zstring ptr' is directly available, so this bug is encountered when using 'GET (file I/O)':

When a dereferenced 'zstring ptr' is passed, the pointed buffer must begin with at least as many non-zero elements as the number of elements to read.
(no problem when a real zstring variable is passed)

Therefore for this bad 'GET (file I/O)' behavior, a workaround (other than initializing the values of the buffer elements) is to use an equivalent zstring structure in a Type, and place it to the address of the dynamically allocated memory:

Open "test.bin" For Binary Access Write As #99
Put #99, , "Hello FreeBASIC"
Close #99

Dim As Zstring Ptr pzbuffer1 = Callocate(33, Sizeof(Zstring))
'' Using a dereferenced zstring pointer to the dynamically allocated memory
Open "test.bin" For Binary Access Read As #99
Print "returned by 'Get(#99, , *pzbuffer1)' (0 = success): " & Get(#99, , *pzbuffer1),, "in zbuffer cleared"
Close #99
Print "  '" & *pzbuffer1 & "'",, "zbuffer length: " & Len(*pzbuffer1)
Print
Deallocate(pzbuffer1)

Dim As Zstring Ptr pzbuffer2 = Callocate(33, Sizeof(Zstring))
'' Using a zstring structure ('zt') placed at the address of the dynamically allocated memory
Type zt
    Dim As Zstring * 33 zbuffer
End Type
Dim As zt Ptr pzt = Cptr(Any Ptr, pzbuffer2)
Open "test.bin" For Binary Access Read As #99
Print "returned by 'Get(#99, , pzt->zbuffer)' (0 = success): " & Get(#99, , pzt->zbuffer),, "in zbuffer cleared"
Close #99
Print "  '" & *pzbuffer2 & "'", "zbuffer length: " & Len(*pzbuffer2)
Print
Deallocate(pzbuffer2)

Sleep
 

Last edit: fxm (freebasic.net) 2021-11-08