PDA

View Full Version : Experiment: Type tTest Extends Union uTest



ReneMiner
19-04-2020, 02:58
just try- it will not break anything



uses "console"
$Sep = crlf & repeat$(20, "==-==") & crlf & crlf


printl repeat$(3, crlf) & " I am testing to find out if" in %CCOLOR_FINTENSEWHITE
printl crlf & repeat$(5, $Tab) & "Type can extend Union?" in %CCOLOR_FLIGHTBLUE
printl repeat$(3, crlf)
printl " Now i will create a UNION and a TYPE"
printl $sep & crlf & crlf & "...any key to continue..." in %CCOLOR_FYELLOW
waitkey
printl crlf & crlf
union Bytes16
Chars As asciiz * 16
B(16) as Byte
P(4) as DWord
Q(2) as quad
end union

printl " Union Bytes16" & crlf & " Chars As asciiz * 16" & crlf & " B(16) as Byte" &
crlf & " P(4) as DWord" & crlf & " Q(2) as quad" & crlf & " End Union" in %ccolor_fintensewhite
printl crlf & crlf
printl " Union created that occupies 16 Bytes"
Printl " it can be 16 chars or bytes, 4 Dword or 2 Quad"
printl $sep & crlf & crlf & "...any key to continue..." in %CCOLOR_FYELLOW
waitkey
printl
printl "Now i create " & repeat$(3, crlf)
printl $TAB & $TAb & " Type tTest Extends Bytes16" & crlf In %CCOLOR_FLIGHTGREEN


Type tTest extends Bytes16
function _Create(byval data as string)
if lenf(data) > 16 then
data = left$(data, 16)
else
while lenf(data) < 16
data &= $spc
Wend
EndIf
printl "content of data inside _Create() before storage:"
printl ">>>" & data & "<<<" in %ccolor_flightred
me.Chars=data

end function
function Text$() as string
function = memory_Get(Varptr(Me), 16)
end function
function GetByte(byval Index as Long) as Byte
function = me.B(Index)
end function


function GetDword(byval Index as Long) as dword
function = me.p(index)
end function
function GetQuad(byval Index as Long) as Quad
function = me.q(Index)
end function
end type


printl "I defined an udt that extends Bytes16. No additional subelements"
printl "that would occupy any memory but only functions to test it"
printl crlf & "lets see if the subelements of the union are valid" in %ccolor_flightCyan
printl crlf & $sep & crlf & crlf & "...any key to continue..." in %CCOLOR_FYELLOW
waitkey
printl


dim myUDT as tTest("0123456789ABCDEF")
printl "Dim myUDT as tTest('0123456789ABCDEF') ... done"
printl "i dimensioned a variable of the udt and assigned 16 hex-digits from 0 to F"
printl "by using the _Create-feature." & crlf & "Now check if that was successful:"


printl crlf & $sep & crlf & crlf & "...any key to continue..." in %CCOLOR_FYELLOW
waitkey
printl
print crlf & "the output: >>>" in %ccolor_flightblue
print myUDT.Text$ in %CCOLOR_FINTENSEWHITE
printl "<<<" in %ccolor_flightblue
printl crlf & $Tab & " returned length is 16 bytes but the 'F' is missing" in %ccolor_flightred
printl repeat$(4, crlf) & "ok, then lets have a look at the other unions names..."
printl crlf & $sep & "...any key to continue..." in %CCOLOR_FYELLOW
waitkey
printl
long i
printl $sep & "as Quads:" in %ccolor_flightcyan
printl
printl "1= " & tstr$(myUDT.GetQuad(1)) & " 2= " & tstr$(myUDT.GetQuad(2))
printl $sep & "as Dwords:" in %ccolor_flightcyan
printl "1= " & tstr$(myUDT.GetDword(1)) & $tab & " 2= " & tstr$(myUDT.GetDword(2)) & " 3= " & tstr$(myUDT.GetDword(3)) & $tab & " 4= " & tstr$(myUDT.GetDword(4))
printl $sep & "as Bytes:" in %ccolor_flightcyan
for i = 1 to 15 step 4
printl tstr$(i) & "= " & tstr$(myUDT.GetByte(i)) & $Tab & $spc & tstr$(i+1) & "= " & tstr$(myUDT.GetByte(i+1)) & $Tab & $spc &
tstr$(i+2) & "= " & tstr$(myUDT.GetByte(i+2)) & $Tab & $spc & tstr$(i+3) & "= " & tstr$(myUDT.GetByte(i+3))
next


printl $sep in %CCOLOR_FYELLOW


printl "Obviously the udt only accepts the unions subsets names" in %ccolor_flightGreen
printl "else it would raise an Error for invalid subelement-names," in %ccolor_Flightred
printl "but it does not unite the elements that they would share the memory."
printl $sep & crlf & crlf & "...any key to read a suggestion" in %CCOLOR_FYELLOW
waitkey


$Suggest = crlf & rawtext
I would prefer the union within a type as this and to seperate
alternative ways of dividing with something as "[OR] AT" and also
to share the memory using different names and types alike

Type tMyType
Chars As Asciiz * 16
At Chars Shared( B(16) as Byte )
At Chars Shared( pData as Dword, pName as DWord, Styling As Quad )
At Chars Shared( DoublePointer1 As Quad, Style As Long, ExStyle As Long )
end type

end rawtext


printl crlf & $Suggest & crlf
printl $sep & "...any key to end" in %CCOLOR_FYELLOW
waitkey
' try exchange in this script :


'1 * "Extends Bytes16" --> "\n Data as Bytes16"
'4 * "me." --> "me.Bytes16."

Petr Schreiber
19-04-2020, 09:10
Hi Rene,

thank you for really nice visual guideline to your idea :)

I see you are wondering, why you cannot see "F" after assignment of "0123456789ABCDEF".

AS ASCIIZ * N is meant to contain N-1 specified characters, where Nth one is null character. So the content of .Chars in your example is "0123456789ABCDE" + $NUL. Maybe it could be documented more explicitly.

Do I understand correctly, that this:


Type tMyType
Chars As Asciiz * 16
At Chars Shared( B(16) as Byte )
At Chars Shared( pData as Dword, pName as DWord, Styling As Quad )
At Chars Shared( DoublePointer1 As Quad, Style As Long, ExStyle As Long )
end type


...means:
- overlay BYTE B(16) over Chars memory
- overlay pData, pName, Styling in this sequence over Chars memory
- overlay DoublePointer1, Style , ExStyle in this sequence over Chars memory
?

I understand it, but we can already achieve it like this:


Type tMyCustomTypeA
pData as dword
pName as dword
styling as quad

function ToString() as string
return StrFormat$("{1} {2} {3}", me.pData, me.pName, me.styling)
end function
end type


Type tMyCustomTypeB
DoublePointer1 as quad
Style as long
ExStyle as long

function ToString() as string
return StrFormat$("{1} {2} {3}", me.DoublePointer1, me.Style, me.ExStyle)
end function
end type


union uMyUnion
chars as asciiz * 16
B(16) as byte

myCustomA as tMyCustomTypeA
myCustomB as tMyCustomTypeB
end union


dim var as uMyUnion


var.chars = "01234567890ABCDE"


msgbox 0, var.myCustomA.ToString()
msgbox 0, var.myCustomB.ToString()


I personally do not like UNIONs too much, I prefer DIM .. AT / SetAt - but that is a question of personal preference :)


Petr

ReneMiner
19-04-2020, 10:22
yes you are right, this way seems possible, i just was up to have functions to a union of different named sub-elements. I tried previous that experiment to have a double-double-word so to say a DDWord upon a Quad so this udt could be
Alias Quad As TwinPtr

and i wanted to add functions to that TwinPtr without to have addditional dot.subset.dot
I managed it a way like i used 2 Functions to substitute Pointer1 and Pointer2 (pointer1 will tell what kind of variable and pointer2 will point the actual data) and to make sure they don't get exchanged and not to have the unions name inbetween variables name and the subsets i made is as


Type tTwinPtr Quad ' this quad is not a clue to the type but it is to make it 8-aligned which is
' to prevent problems when running 32-Bit apps on a 64-Bit-system
Ptrs As Quad
Function pType() as DWord
Function = HI(Dword, VarPtr(ME))
End Function

Function pData() as Dword
Function = LO(DWord, VarPtr(ME))
End Function

Function _Create(Byval sType As String, Byval pData as Dword)
Local p(2) as Dword At VarPtr(Me)
' it calls a function to store the string containing a Typename and receives Dword pType
' then
p(1) = pType
p(2) = pData
End Function
'...
End Type

Dim ppp As tTwinPtr("t_myUDT", Heap_Alloc(SizeOf(t_myUDT))


this way the user does not need to use additional the unions name and both variables can not be overwritten accidently since the functions only read the value.

OK for the Asciiz i know its something as Windows-native-string, $Null-to mark the fin.
al byte but Eros used it in his Union-example in help. I guess regular STRING * 16 will show up to the F. I try now...