Read / Write types

Previous topic - Next topic

Minion

Not sure if this is possible or not (perhaps an undocumented feature that Ive not heard about) but is it possible to write and read types ? Would really save a lot of time being able to write a type instead of of writing each individual field from it (and read them of course).

S.O.P.M.

How do you mean that? You can copy array contents in one go. And also type contents to another type if they've the same structure. But what exactly do you want to do? I mean if you need all the data of a type isn't it necessary to copy each value individually to certain variables, variable fields or other types, if you want to process the data? A little bit more details please :)
Notebook PC Samsung E372 Core i5 @ 2,6 GHz; 4 GB RAM; Win 7 Home Premium

Minion

what im trying to do (very basically) is this ...

Code (glbasic) Select

TYPE Tthing
x
y
z
a$
b$
c$
ENDTYPE

LOCAL temp AS Tthing

LOCAL ok

temp.x = 99
temp.y = 50
temp.z = 1
temp.a$= "abc"
temp.b$= "123"
temp.c$= "test"




ok = OPENFILE(0, "file.dat", FALSE)
WRITE 0,temp
CLOSEFILE


ok = OPENFILE(0, "file.dat",TRUE)
READ 0, temp
CLOSEFILE



... in its simplest form. Of course I`d want to write out an array of said type etc (its just to show the principle here etc). as it is i have to run thru the whole type saving each individual "bit"


matchy

#3
If the metadata could be indexed then perhaps but would be nice future feature. ;) It would be very handy, at least for speedy streaming io packets.  :glare:

MrTAToad

There is no proper way of writing a complete TYPE, aside from the fact you can't get the size of it, a TYPE holds a lot more that just what you define, and thus you would get a whole lot of gibberish with it...

In GLBasic, a TYPE is a C++ class which comes with a lot of stuff - if you want to use a proper structure, you would need to use INLINE, whereupon SIZEOF should be available and you could write the complete structure in one go.

At the moment, you need to write the contents one item at a time.

kanonet

MrT I was also thinking about using INLINE and sizeof, but I think this would not work if your TYPE contains arrays (and maybe strings too?). So ATM I think there is no solution for types in general, but it would be easy to add this feature, since the GPC creates the class it could simply add a helper function, e.g. to pack all data of a type into a string.
Lenovo Thinkpad T430u: Intel i5-3317U, 8GB DDR3, NVidia GeForce 620M, Micron RealSSD C400 @Win7 x64

S.O.P.M.

This raises the question (I really would like to know) how much memory does it take if, let's say, I define some types with a handful members. Or an array with an index of 128 by one dimension. Do I have to do everything to reduce the use of many variables or is there no reason to worry about - at least modern computers and smartphones have a good amount of RAM.
Notebook PC Samsung E372 Core i5 @ 2,6 GHz; 4 GB RAM; Win 7 Home Premium

MrTAToad

#7
It would depend on whether its inline or not.

If using BASIC, then the memory define with be a class for the type and if its a string, then a class for that too - its not useful to calculate the size of a class (as the code could change between compiles etc).  However, it is usually more than a straight C structure (because all that defines is the content size), but of course would depend on the contents of variables.

For example :

Code (glbasic) Select
struct {
float a,b;
double c;
char text[256];
} dummy


Would take around 272 bytes (slightly more if alignment is introduced), but certainly around there.

Code (glbasic) Select

TYPE dummy
a,b,c
text$
ENDTYPE


Would be impossible to calculate as two classes are used - one for the string and one for the dummy type.

If memory is an absolutely critical element, then everything would have to be done INLINE for absolute optimal space usage.  You wouldn't lose anything (although arrays are slightly harder to use), and you do have access to the machine's operating system functions then.

However, even on a Pi, memory isn't in that short supply - so you shouldn't really worry about that.


MrTAToad

Quote from: kanonet on 2014-Jul-14
MrT I was also thinking about using INLINE and sizeof, but I think this would not work if your TYPE contains arrays (and maybe strings too?). So ATM I think there is no solution for types in general, but it would be easy to add this feature, since the GPC creates the class it could simply add a helper function, e.g. to pack all data of a type into a string.
There is no extremely simple way of doing it - the obvious way would be just to write everything out as a set of comma seperated values.  It may get a bit tedious if the type had many variables, but it would be the only way.

kanonet

Yes and its also how the relational and assignment operators are created - so since the GPC does already process this informations, they could simply get used to create a helper function.
Lenovo Thinkpad T430u: Intel i5-3317U, 8GB DDR3, NVidia GeForce 620M, Micron RealSSD C400 @Win7 x64

Slydog

#10
Are you trying to initialize the data for an instance, then save the data to a file (and/or print to the screen)?
Something like this:?

Code (glbasic) Select
CONSTANT FILEMODE_APPEND = -1
CONSTANT FILEMODE_WRITE = 0
CONSTANT FILEMODE_READ = 1

TYPE TThing
x%
y%
z%
a$
b$
c$

FUNCTION Set: x%, y%, z%, a$, b$, c$
self.x = x
self.y = y
self.z = z
self.a$ = a$
self.b$ = b$
self.c$ = c$
ENDFUNCTION

// Debugging: return current TYPE values as a string (for storing to a file, or displaying on the screen, or debug window)
FUNCTION ToString$:
RETURN "[x:" + x + "] [y:" + y + "] [z:" + z + "] [a:" + a$ + "] [b:" + b$ + "] [c:" + c$ + "]"
ENDFUNCTION

FUNCTION FilePut: fileName$
LOCAL id%
id = GENFILE()
OPENFILE(id, fileName$, FILEMODE_APPEND)
WRITELONG id, self.x
WRITELONG id, self.y
WRITELONG id, self.z
WRITESTR id, self.a$ // You may want to force a string size here, to know where the value starts using FILESEEK below
WRITESTR id, self.b$
WRITESTR id, self.c$
CLOSEFILE id
ENDFUNCTION

// Not functional, you would need to fix the string size above to a certain size in order to be able to know the sizeOfRecord, or use another method
FUNCTION FileGet: fileName$, index%, sizeOfRecord%
LOCAL id%
LOCAL position%
id = GENFILE()
position = index * sizeOfRecord
OPENFILE(id, fileName$, FILEMODE_READ)
FILESEEK(id, position, 0)
...
CLOSEFILE id
ENDFUNCTION
ENDTYPE


// USAGE

LOCAL thing AS TThing
thing.Set(99, 50, 1, "abc", "123", "test")
DEBUG "thing: " + thing.ToString()
thing.FilePut("log.txt")
// For an array of 'TThing', you would just loop through each, and x.FilePut() to store the entire array to a file.


[Edit]
For writing and reading to/from a file, you could also use a field delimiter, such as '|'.  Then when reading back, just break the record into field strings using a string split command.
My current project (WIP) :: TwistedMaze <<  [Updated: 2015-11-25]