Getting UDTs from the RAM buffer

New to FreeBASIC? Post your questions here.
Post Reply
fzabkar
Posts: 154
Joined: Sep 29, 2018 2:52
Location: Australia

Getting UDTs from the RAM buffer

Post by fzabkar »

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: 7983
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: Getting UDTs from the RAM buffer

Post by dodicat »

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: 8586
Joined: May 28, 2005 3:28
Contact:

Re: Getting UDTs from the RAM buffer

Post by D.J.Peters »

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 ! KeyPgOpPlacementNew

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

Re: Getting UDTs from the RAM buffer

Post by fxm »

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
Moderator
Posts: 12107
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Getting UDTs from the RAM buffer

Post by fxm »

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 ! 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: 7983
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: Getting UDTs from the RAM buffer

Post by dodicat »

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: 154
Joined: Sep 29, 2018 2:52
Location: Australia

Re: Getting UDTs from the RAM buffer

Post by fzabkar »

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: 3910
Joined: Jun 02, 2013 9:27
Location: Switzerland

Re: Getting UDTs from the RAM buffer

Post by MrSwiss »

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: 154
Joined: Sep 29, 2018 2:52
Location: Australia

Re: Getting UDTs from the RAM buffer

Post by fzabkar »

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: 7983
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: Getting UDTs from the RAM buffer

Post by dodicat »

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: 3910
Joined: Jun 02, 2013 9:27
Location: Switzerland

Re: Getting UDTs from the RAM buffer

Post by MrSwiss »

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: 7983
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: Getting UDTs from the RAM buffer

Post by dodicat »

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: 154
Joined: Sep 29, 2018 2:52
Location: Australia

Re: Getting UDTs from the RAM buffer

Post by fzabkar »

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.
Post Reply