Getting UDTs from the RAM buffer

New to FreeBASIC? Post your questions here.
fzabkar
Posts: 48
Joined: Sep 29, 2018 2:52

Getting UDTs from the RAM buffer

Postby fzabkar » Sep 09, 2020 6:23

How do I get the data at filbuff[ n ] into hdr_royl ?

Is it as simple as ...

Code: Select all

hdr_royl =  filbuff[ n ]

Code: Select all

Dim filbuff As Any Ptr

Type hdrtyp1 Field = 1
   As ULong sig
   As UByte typ
   As UByte ignore1
   As UShort ignore2
   As UShort modid
   As UShort modsiz
   As Integer cksm
   As ULongInt modver
End Type

Dim hdr_royl As hdrtyp1
dodicat
Posts: 6759
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: Getting UDTs from the RAM buffer

Postby dodicat » Sep 09, 2020 8:54

Something like:

Code: Select all

Dim filbuff As Any Ptr

Type hdrtyp1 Field = 1
   As ULong sig
   As UByte typ
   As UByte ignore1
   As UShort ignore2
   As UShort modid
   As UShort modsiz
   As Integer cksm
   As ULongInt modver
End Type

'get some data
dim as hdrtyp1 T(1 to 3)
T(1).sig=10001
T(2).sig=10002
T(3).sig=10003
filbuff=@T(1)




Dim hdr_royl As hdrtyp1

for n as long=0 to 2
hdr_royl=cast(hdrtyp1 ptr,filbuff)[n]

print hdr_royl.sig
next n

sleep



 
D.J.Peters
Posts: 8203
Joined: May 28, 2005 3:28
Contact:

Re: Getting UDTs from the RAM buffer

Postby D.J.Peters » Sep 09, 2020 8:57

You can overlay memory by address with the NEW operator !

Code: Select all

dim as hdrtyp1 ptr hdrtyp = new(&filbuff[n]) hdrtyp1

read about it ! /wiki/KeyPgOpPlacementNew

Joshy
fxm
Posts: 10037
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Getting UDTs from the RAM buffer

Postby fxm » Sep 09, 2020 9:37

Be a little more specific in your question (so that we can answer you precisely):
- do you want to create a new 'hdrtyp1' object, and to initialize it from the RAM buffer values?

Note: As 'filbuff' is an 'Any Ptr', 'filbuff[n]' and also '@filbuff[n]' are not valid (by cons the address 'filbuff + n' is valid).
fxm
Posts: 10037
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Getting UDTs from the RAM buffer

Postby fxm » Sep 09, 2020 9:42

D.J.Peters wrote:You can overlay memory by address with the NEW operator !

Code: Select all

dim as hdrtyp1 ptr hdrtyp = new(&filbuff[n]) hdrtyp1

read about it ! /wiki/KeyPgOpPlacementNew

Joshy

rather ?

Code: Select all

dim as hdrtyp1 ptr hdrtyp = new(filbuff + n) hdrtyp1 (Any)
(if one wants to keep the RAM buffer values)
but:

Code: Select all

dim as hdrtyp1 ptr hdrtyp = filbuff + n
is simpler.
dodicat
Posts: 6759
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: Getting UDTs from the RAM buffer

Postby dodicat » Sep 09, 2020 10:22

Nothing was asked about hdrtyp1 pointers
For a hdrtyp1 ptr you just set it =filbuff with filbuff pointing to valid data.

Code: Select all

Dim filbuff As Any Ptr

Type hdrtyp1 Field = 1
   As ULong sig
   As UByte typ
   As UByte ignore1
   As UShort ignore2
   As UShort modid
   As UShort modsiz
   As Integer cksm
   As ULongInt modver
End Type

'get some data
dim as hdrtyp1 T(1 to 3)
T(1).sig=10001
T(2).sig=10002
T(3).sig=10003
filbuff=@T(1)

Dim hdr_royl As hdrtyp1 ptr

hdr_royl=filbuff

for n as long=0 to 2


print hdr_royl[n].sig


next n


sleep



 
fzabkar
Posts: 48
Joined: Sep 29, 2018 2:52

Re: Getting UDTs from the RAM buffer

Postby fzabkar » Sep 09, 2020 19:01

ISTM that this task is unnecessarily complicated, even convoluted. By comparison, if I want to Get a UDT using file I/O, I simply specify the UDT variable, and the byte offset within the file. I was hoping that RAM I/O could be done in an analogous way. That is, specify the byte offset in memory using Any Ptr, and then read/write the appropriate amount of data by matching it to the variable type. Isn't that the more logical way to go about this task?
MrSwiss
Posts: 3657
Joined: Jun 02, 2013 9:27
Location: Switzerland

Re: Getting UDTs from the RAM buffer

Postby MrSwiss » Sep 09, 2020 19:34

The way you are going about it is a 'stony road' (the Any Ptr, that is).
If you use a UDT Ptr instead, things become quite simple:

Code: Select all

' static initialized type (for this DEMO only!)
Type UDT_t                              ' size FBC64 = 32, FBC32 = 20
    As ULong    id   = 1
    As ULong    slen = 4
    As String   info = "test"
End Type
Type pUDT   As UDT_t Ptr                ' type ptr alias (aka: forward declaration)
' end type

' methods to acess the members of a type
Dim As UDT_t    my1                     ' for direct 'type.member' access
Dim As pUDT     pmy1 = @my1             ' for indirect 'type_ptr->member' access

Print "type size "; Str(SizeOf(UDT_t))
Print
Print "type.member access"
Print "id        "; my1.id
Print "slen      "; my1.slen
Print "info      "; my1.info
Print
Print "type_ptr->member access"
Print "id        "; pmy1->id
Print "slen      "; pmy1->slen
Print "info      "; pmy1->info

Sleep
fzabkar
Posts: 48
Joined: Sep 29, 2018 2:52

Re: Getting UDTs from the RAM buffer

Postby fzabkar » Sep 09, 2020 21:19

Thanks to all.

One other annoyance is the way that UDTs handle strings. There are many times when I wish to Get a binary String which contains 0x00 characters. This works OK for String variables on their own, but I have trouble when these Strings (or WStrings or Zstrings) are members of a UDT. Is there any way to specify a UDT where the member strings are not terminated by zeros, and where zeros can be part of the string itself?
dodicat
Posts: 6759
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: Getting UDTs from the RAM buffer

Postby dodicat » Sep 09, 2020 21:24

You could make a custom function using the offsets of any ptr.

Code: Select all



Type hdrtyp1 Field = 1
   As ULong sig
   As UByte typ
   As UByte ignore1
   As UShort ignore2
   As UShort modid
   As UShort modsiz
   As Integer cksm
   As ULongInt modver
End Type


function show(p as any ptr,n as long) as double
  dim as integer i=cint(p)
select case n
case 1
return (*cast(ulong ptr,i))
case 2
i+=4
return (*cast(ubyte ptr,i))
case 3
i+= 1+4
return (*cast(ubyte ptr,i))
case 4
i+= 1+1+4
return (*cast(ushort ptr,i))
case 5
i+= 2+1+1+4
return (*cast(ushort ptr,i))
case 6
i+= 2+ 2+1+1+4
return (*cast(ushort ptr,i))
case 7
i+=2+2+ 2+1+1+4
return (*cast(integer ptr,i))
case 8
i+=sizeof(integer)+2+2+ 2+1+1+4
return (*cast(ulongint ptr,i))
end select
end function

'get some data
dim as hdrtyp1 T

with T
    .sig=1
    .typ=2
    .ignore1=3
    .ignore2=4
    .modid=5
    .modsiz=6
    .cksm=-7
    .modver=8
    end with

Dim filbuff As Any Ptr=@T

for n as long=1 to 8
    print show(filbuff,n)
    next
 
 
sleep



 
MrSwiss
Posts: 3657
Joined: Jun 02, 2013 9:27
Location: Switzerland

Re: Getting UDTs from the RAM buffer

Postby MrSwiss » Sep 09, 2020 21:31

fzabkar wrote:There are many times when I wish to Get a binary String which contains 0x00 characters.

FB's String (a type in fact) is the only one that allowes Chr(0) inside the string data (also Null terminated).
ZString and/or WString cannot accept Chr(0) because it is treated as terminator.
dodicat
Posts: 6759
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: Getting UDTs from the RAM buffer

Postby dodicat » Sep 09, 2020 21:49

For saving to file e.t.c. you could use a fixed ubyte array

Code: Select all


type udt
    as ubyte u(100)
    dim as long n
    declare constructor
    declare constructor(as string)
    declare operator cast() as string
end type

constructor udt
'Hi!
end constructor

constructor udt(s as string)
n=len(s)-1
for m as long=0 to n
    u(m)=s[m]
    next m
end constructor

operator udt.cast() as string
dim as string s
for m as long=0 to n
    s+=chr(u(m))
next m
return s
end operator


dim as udt u=any

u=udt("FreeBASIC"+chr(0)+"..."+chr(0))
print "'";u;"'"
sleep

 

 
fzabkar
Posts: 48
Joined: Sep 29, 2018 2:52

Re: Getting UDTs from the RAM buffer

Postby fzabkar » Sep 09, 2020 23:51

Many thanks. There are quite a few concepts I need to get my head around.

At present I'm revisiting my old programs and fixing some of the ugly coding. I'll probably end up writing code that is less efficient, but which I find easiest to comprehend. I expect I'll have a lot more questions along the way.

Return to “Beginners”

Who is online

Users browsing this forum: No registered users and 11 guests