Object serialization
![Task](http://static.miraheze.org/rosettacodewiki/thumb/b/ba/Rcode-button-task-crushed.png/64px-Rcode-button-task-crushed.png)
You are encouraged to solve this task according to the task description, using any language you may know.
Create a set of data types based upon inheritance. Each data type or class should have a print command that displays the contents of an instance of that class to standard output. Create instances of each class in your inheritance hierarchy and display them to standard output. Write each of the objects to a file named objects.dat in binary form using serialization or marshalling. Read the file objects.dat and print the contents of each serialized object.
Ada
This file contains the package specification containing the public definitions of the inheritance tree rooted at the type Message. Each type in the inheritance tree has its own print procedure.
with Ada.Calendar; use Ada.Calendar; package Messages is type Message is tagged record Timestamp : Time; end record; procedure Print(Item : Message); procedure Display(Item : Message'Class); type Sensor_Message is new Message with record Sensor_Id : Integer; Reading : Float; end record; procedure Print(Item : Sensor_Message); type Control_Message is new Message with record Actuator_Id : Integer; Command : Float; end record; procedure Print(Item : Control_Message); end Messages;
The next portion contains the implementation of the procedures defined in the package specification.
with Ada.Text_Io; use Ada.Text_Io; with Ada.Integer_Text_Io; use Ada.Integer_Text_Io; with Ada.Float_Text_IO; use Ada.Float_Text_IO; package body Messages is ----------- -- Print -- ----------- procedure Print (Item : Message) is The_Year : Year_Number; The_Month : Month_Number; The_Day : Day_Number; Seconds : Day_Duration; begin Split(Date => Item.Timestamp, Year => The_Year, Month => The_Month, Day => The_Day, Seconds => Seconds); Put("Time Stamp:"); Put(Item => The_Year, Width => 4); Put("-"); Put(Item => The_Month, Width => 1); Put("-"); Put(Item => The_Day, Width => 1); New_Line; end Print; ----------- -- Print -- ----------- procedure Print (Item : Sensor_Message) is begin Print(Message(Item)); Put("Sensor Id: "); Put(Item => Item.Sensor_Id, Width => 1); New_Line; Put("Reading: "); Put(Item => Item.Reading, Fore => 1, Aft => 4, Exp => 0); New_Line; end Print; ----------- -- Print -- ----------- procedure Print (Item : Control_Message) is begin Print(Message(Item)); Put("Actuator Id: "); Put(Item => Item.Actuator_Id, Width => 1); New_Line; Put("Command: "); Put(Item => Item.Command, Fore => 1, Aft => 4, Exp => 0); New_Line; end Print; ------------- ---Display -- ------------- procedure Display(Item : Message'Class) is begin Print(Item); end Display; end Messages;
The final section of code creates objects of the three message types and performs the printing, writing, and reading. The Ada attributes 'Class'Output serialize the object and write it to the specified stream. The 'Class'Input attributes call a function automatically provided by the compiler which reads from the specified stream file and returns the object read. The Display procedure takes an object in the inheritance tree rooted at Message and dispatches the correct print procedure.
with Messages; use Messages; with Ada.Streams.Stream_Io; use Ada.Streams.Stream_Io; with Ada.Calendar; use Ada.Calendar; with Ada.Text_Io; procedure Streams_Example is S1 : Sensor_Message; M1 : Message; C1 : Control_Message; Now : Time := Clock; The_File : Ada.Streams.Stream_Io.File_Type; The_Stream : Ada.Streams.Stream_IO.Stream_Access; begin S1 := (Now, 1234, 0.025); M1.Timestamp := Now; C1 := (Now, 15, 0.334); Display(S1); Display(M1); Display(C1); begin Open(File => The_File, Mode => Out_File, Name => "Messages.dat"); exception when others => Create(File => The_File, Name => "Messages.dat"); end; The_Stream := Stream(The_File); Sensor_Message'Class'Output(The_Stream, S1); Message'Class'Output(The_Stream, M1); Control_Message'Class'Output(The_Stream, C1); Close(The_File); Open(File => The_File, Mode => In_File, Name => "Messages.dat"); The_Stream := Stream(The_File); Ada.Text_Io.New_Line(2); while not End_Of_File(The_File) loop Display(Message'Class'Input(The_Stream)); end loop; Close(The_File); end Streams_Example;
Output results:
Time Stamp:2007-3-9 Sensor Id: 1234 Reading: 0.0250 Time Stamp:2007-3-9 Time Stamp:2007-3-9 Actuator Id: 15 Command: 0.3340 Time Stamp:2007-3-9 Sensor Id: 1234 Reading: 0.0250 Time Stamp:2007-3-9 Time Stamp:2007-3-9 Actuator Id: 15 Command: 0.3340
Ruby
class Being def initialize(speciality=nil) @speciality=speciality end def to_s "(object_id = #{object_id})\n"+"(#{self.class}):".ljust(12)+to_s4Being+(@speciality ? "\n"+" "*12+@speciality : "") end def to_s4Being "I am a collection of cooperative molecules with a talent for self-preservation." end end class Earthling < Being def to_s4Being "I originate from a blue planet.\n"+" "*12+to_s4Earthling end end class Mamal < Earthling def initialize(type) @type=type end def to_s4Earthling "I am champion in taking care of my offspring and eating eveything I can find, except mamals of type #{@type}." end end class Fish < Earthling def initialize(iq) @iq=(iq>1 ? :instrustableValue : iq) end def to_s4Earthling "Although I think I can think, I can't resist biting in hooks." end end class Moonling < Being def to_s4Being "My name is Janneke Maan, and apparently some Earthlings will pay me a visit." end end diverseCollection=[] diverseCollection << (marsian=Being.new("I come from Mars and like playing hide and seek.")) diverseCollection << (me=Mamal.new(:human)) diverseCollection << (nemo=Fish.new(0.99)) diverseCollection << (jannakeMaan=Moonling.new) puts "BEGIN ORIGINAL DIVERSE COLLECTION" diverseCollection.each do |being| puts "",being.to_s end puts "END ORIGINAL DIVERSE COLLECTION" puts "\n"+"*"*50+"\n\n" #Marshal the diverse Array of beings File.open('diverseCollection.bin','w') do |fo| fo << Marshal.dump(diverseCollection) end #load the Array of diverse beings sameDiverseCollection=Marshal.load(File.read('diverseCollection.bin')) puts "BEGIN LOADED DIVERSE COLLECTION" puts( sameDiverseCollection.collect do |being| being.to_s end.join("\n\n") ) puts "END LOADED DIVERSE COLLECTION"