Gambas-it
Gambas3 => Programmazione => Topic aperto da: vuott - 22 Febbraio 2013, 22:42:48
-
Vorrei riportare un messaggio inviato dall'utente Jussi Lahtinen della M.L.I, il quale ha messo a disposizione un codice, da lui scritto, per la serializzazione degli oggetti:
« This is my implementation for object serialization, it's still bit
incomplete, but it's already usable.
And I thought some of you might find it very useful. I use it now to save
objects to file.
Right now it can handle objects with native datatypes (if you use it
recursively it can be made to handle all types).
What do you think? Is there better way to do this?
Maybe with Object.Address() & Object.SizeOf() ?
Example of how to use it:
'This will save the object to file.
Dim MyObject As MyClass
Dim hFile As File
hFile = Open "~/Desktop/testtest" For Create
SaveValues(hFile, MyObject)
Close #hFile
'This will load the object from file.
hFile = Open "~/Desktop/testtest" For Read
LoadValues(hFile, MyObject)
Close #hFile
And the code itself:
Public Function SaveValues(hStream As Stream, hObject As Object)
Dim hCls As Class = Object.Class(hObject)
Dim sTmp As String
For Each sTmp In hCls.Symbols.Sort(gb.Binary)
If hCls[sTmp].Kind = Class.Variable Then
Select Case hCls[sTmp].Type
Case "h" 'short
Write #hStream, Object.GetProperty(hObject, sTmp) As Short
Case "b" 'boolean
Write #hStream, Object.GetProperty(hObject, sTmp) As Boolean
Case "c" 'byte
Write #hStream, Object.GetProperty(hObject, sTmp) As Byte
Case "i" 'integer
Write #hStream, Object.GetProperty(hObject, sTmp) As Integer
Case "l" 'long
Write #hStream, Object.GetProperty(hObject, sTmp) As Long
Case "s"
Write #hStream, Object.GetProperty(hObject, sTmp) As String
Case Else
Error.Raise("Error! Missing variable type definition.")
End Select
Endif
Next
End
Public Function LoadValues(hStream As Stream, hObject As Object)
Dim hCls As Class = Object.Class(hObject)
Dim sTmp As String
Dim h As Short
Dim b As Boolean
Dim c As Byte
Dim i As Integer
Dim l As Long
Dim s As String
For Each sTmp In hCls.Symbols.Sort(gb.Binary)
If hCls[sTmp].Kind = Class.Variable Then
Select Case hCls[sTmp].Type
Case "h" 'short
h = Read #hStream As Short
Object.SetProperty(hObject, sTmp, h)
Case "b" 'boolean
b = Read #hStream As Boolean
Object.SetProperty(hObject, sTmp, b)
Case "c" 'byte
c = Read #hStream As Byte
Object.SetProperty(hObject, sTmp, c)
Case "i" 'integer
i = Read #hStream As Integer
Object.SetProperty(hObject, sTmp, i)
Case "l" 'long
l = Read #hStream As Long
Object.SetProperty(hObject, sTmp, l)
Case "s"
s = Read #hStream As String
Object.SetProperty(hObject, sTmp, s)
Case Else
Error.Raise("Error! Missing variable type definition.")
End Select
Endif
Next
End
Jussi »
-
« If it hits an object property then set a marker in the file and call
itself on that object. There is only one problem with this: your code can
only handle (public) properties. Actually an object serialised by your code
and then deserialised could stop working properly because Private variables
not bound to properties (which weren't saved therefore) may not contain the
right values anymore.
> What do you think? Is there better way to do this?
> Maybe with Object.Address() & Object.SizeOf() ?
I think you can use these to generate a binary dump of an object to a file,
but the thing is: the backing structures you dump most likely contain
pointers to other structures (Gambas objects or structures allocated by a
shared library!) which will become invalid pointers when loaded into another
process.
I think the solution to both above problems is already in Settings.Write().
It is capable of _correctly_ writing and restoring objects if they export a
Settings property. As a matter of fact, the object itself only really knows
what must be serialised and can also provide its private variables.
Alas, I don't see how the serialisation process could be done _without_ the
object being deeply involved by providing its internal information.
Regards,
Tobi »
« >If it hits an object property then set a marker in the file and call
> itself on that object. There is only one problem with this: your code can
> only handle (public) properties. Actually an object serialised by your code
> and then deserialised could stop working properly because Private variables
> not bound to properties (which weren't saved therefore) may not contain the
> right values anymore.
>
You are right.
I didn't think about that, because I wrote this piece of code couple
specific classes in my mind.
So, it's not universal solution.
> I think you can use these to generate a binary dump of an object to a file,
> but the thing is: the backing structures you dump most likely contain
> pointers to other structures (Gambas objects or structures allocated by a
> shared library!) which will become invalid pointers when loaded into
> another
> process.
>
True, that is troublesome to overcome.
> I think the solution to both above problems is already in Settings.Write().
> It is capable of _correctly_ writing and restoring objects if they export a
> Settings property.
Settings property is just pretty limited with it's capabilities when
speaking of serialization,
but of course it's very good for it's intended use.
> As a matter of fact, the object itself only really knows
> what must be serialised and can also provide its private variables.
>
> Alas, I don't see how the serialisation process could be done _without_ the
> object being deeply involved by providing its internal information.
I understand your point.
I think the object should be designed to be serialized, or you have to do
it manually.
Now I wonder how Boost library does serialization!
Jussi »