Writing and reading Marshal data to attributes?
-
Writing data to attribute:
` > len = 10.mm
0.393700787401575out = Marshal.dump( len )
f0.39370078740157483
out.size
26
model.set_attribute( 'test', 'foo', out )
f0.39370078740157483`Reading it:
` > data = model.get_attribute( 'test', 'foo' )
f0.39370078740157483Marshal.load( data )
Error: #<ArgumentError: (eval):14:inload': marshal data too short> (eval):14 (eval):14 data.size 23
I could make it work by base64 encode the data - but is there another way?
` > b64 = TT::Binary.encode64( out )
BAhmGzAuMzkzNzAwNzg3NDAxNTc0ODMAJk0=model.set_attribute( 'test', 'foo', b64 )
BAhmGzAuMzkzNzAwNzg3NDAxNTc0ODMAJk0=data = model.get_attribute( 'test', 'foo' )
BAhmGzAuMzkzNzAwNzg3NDAxNTc0ODMAJk0=decoded = TT::Binary.decode64( data )
f0.39370078740157483
decoded.size
26
obj = Marshal.load( decoded )
0.393700787401575`Bonus question:
Why does the Length object come back as a Float?` > len.class
Lengthobj.class
Float` -
It begs the question... why save it as a 'length'?
Why not turn it into a float in the first place before setting attributes etc
out = Marshal.dump( len.to_f )
Then when it's read back in it's a float which is taken as 'inches' anyway - you can use a .to_l on it later to put it into current units - remember that the user might have changed units in the meanwhile anyway...Saving stuff as attributes other that integer/float/string/boolean/array[of any of these] is known to cause heartache...
-
@tig said:
It begs the question... why save it as a 'length'?
It was just an example of one data type.
@tig said:
Saving stuff as attributes other that integer/float/string/boolean/array[of any of these] is known to cause heartache...
Marshal.dump
returns a string with binary data - serialized representation of the marshalled object. I'm looking into this class because I was hoping it'd let me easily store and load various objects. -
But 'binary data' can't be saved as an attribute ?
-
I'm suspecting that SketchUp doesn't handle 0 characters well - it terminates the string. And possibly it might be confused by the binary data and converts some stuff to unicode. I had cases where the data read back was longer. In other cases shorter.
So at the moment I bease64 encode/decode it. (Though I'm interesting in other methods that might be more efficient.)In any case -regardless of saving as attributes - I'm wondering by Lengths comes back as Floats. Geom::Point3d objects can't be Marshalled - they throw an error about .marshal_dump being missing. So I wonder if the Length overload class is missing the marshal handling code so Ruby calls the superclass' (Float) marshal methods...
-
I wonder if you ever found a solution on dumping Marshal'ed Sketchup Objects.
I also save my own Ruby instances as Marshaled data in an attributes dict and also use base 64 encode them. (actually just pack('m') but that's the same as base64 does# SAVING # create a dump object for each instance dumped_instances = [] @@instances.each do |inst| dumped_instances << [(Marshal.dump inst)].pack("m") end#do # save to the dictionary Sketchup.active_model.set_attribute "myDict", "mClassInstances", dumped_instances # LOADING # load all instances dumped_instances = Sketchup.active_model.get_attribute "myDict", "mClassInstances" if dumped_instances #create instances dumped_instances.each do |dump| instance = Marshal.load dump.unpack("m")[0] @@instances << instance end#do end#if
-
Not directly, no. SketchUp's classes are defined in C and doesn't implement all features. (For instance some support only clone, but not dup etc.)
I had to write out Geom::Point3d and Geom::Vector3d objects- which I ended up just converting to arrays. Same thing you can do with SketchUp::Color objects.
-
I was actually hoping to find a way to dump
Sketchup;;Material
to an attribute_dictionary
But the materials with a texture give me a headache -
That will be troublesome. Even if you create your own wrapper class that takes a
Sketchup::Material
into a class that does support marshalling you have the issue of the Ruby API not being able to set the Colourize property. And you'd have to figure out a way to handle the texture, as you say. You could write that Base64 encoded or something, but you cannot restore it to reference the original filename.Why do you need to store the whole Material object?
Advertisement