comp.lang.ada
 help / color / mirror / Atom feed
From: Ludovic Brenta <ludovic@ludovic-brenta.org>
Subject: Re: Load an object from a file
Date: Fri, 3 Apr 2009 06:37:46 -0700 (PDT)
Date: 2009-04-03T06:37:46-07:00	[thread overview]
Message-ID: <443d72ca-5bbd-46a3-84c6-e8bd984e5b80@k41g2000yqh.googlegroups.com> (raw)
In-Reply-To: 49d5fa88$0$2862$ba620e4c@news.skynet.be

Olivier Scalbert wrote on comp.lang.ada:
> Hello everybody !
>
> In my Ada self-study context, I was asking myself how can I create and
> fill objects or records from a file.
> As an example, I have tried to represent a java class file format
> structure and fill it with a .class java file.
>
> The ClassFile structure is something like:
>
>      ClassFile {
>         u4 magic;
>         u2 minor_version;
>         u2 major_version;
>         u2 constant_pool_count;
>         cp_info constant_pool[constant_pool_count-1];
>         u2 access_flags;
>         u2 this_class;
>         u2 super_class;
>         u2 interfaces_count;
>         u2 interfaces[interfaces_count];
>         u2 fields_count;
>         field_info fields[fields_count];
>         u2 methods_count;
>         method_info methods[methods_count];
>         u2 attributes_count;
>         attribute_info attributes[attributes_count];
>      }
>
> JVM Specs can be found there:http://java.sun.com/docs/books/jvms/second_edition/html/ClassFile.doc...
>
> I have no problem to represent and to fill from file, the first four fields.
> But I do not know what is the best (Ada) way of representing the array
> of info constant_pool as the size is only known at run time.(=
> constant_pool_cout).

I would create a record type with one discriminant for each array,
like so:

type Constant_Pool_Array is array (Positive range <>) of cp_info;
type Interfaces_Array is array (Positive range <>) of u2;
-- etc.

type Class_File
  (constant_pool_count,
   interfaces_count,
   fields_count,
   methods_count,
   attributes_count : u2)
is record
   ...
   constant_pool : Constant_Pool_Array (2 .. constant_pool_count);
   ...
   interfaces : Interfaces_Array (1 .. interfaces_count);
   ... etc.
end record;

> Also how can I fill this array ?

You would normally simply call the predefined Class_File'Read but this
wouldn't work since the order of the components in type Class_File
does not match the order in the file. So, you'd specify your own Read:

function Input(
   Stream : not null access Ada.Streams.Root_Stream_Type'Class)
   return Class_File); -- see RM 13.13(22) and following
for Class_File'Input use Input; -- as per RM 13.13(38/2)

function Input(
   Stream : not null access Ada.Streams.Root_Stream_Type'Class)
   return Class_File)
is
   Constant_Pool_Count : u2;
   type Constant_Pool_Array_Access is access Constant_Pool_Array;
   procedure Free is new Ada.Unchecked_Deallocation
     (Constant_Pool_Array, Constant_Pool_Array_Access);
   Constant_Pool : Constant_Pool_Array_Access;
begin
   ...
   u2'Read (Stream, Constant_Pool_Count);
   Constant_Pool := new Constant_Pool_Array (1 .. Constant_Pool - 1);
   Constant_Pool_Array'Read (Stream, Constant_Pool.all);
   ...

After reading all members, construct the result:

declare
   Result : Class_File
  (constant_pool_count => Constant_Pool_Count,
   interfaces_count => Interfaces_Count,
   fields_count => Fields_Count,
   methods_count => Methods_Count,
   attributes_count => Attricutes_Count);
begin
   Result.Constant_Pool := Constant_Pool.all;
   ...
   Free (Constant_Pool);
   ...
   return Result;
end;
end Input;

You can also eliminate the use of access types and dynamic allocation
and deallocation by nesting declare blocks, e.g.

u2'Read (Stream, Constant_Pool_Count);
declare
   Constant_Pool : Constant_Pool_Array (1 .. Constant_Pool_Count);
begin
   Constant_Pool_Array'Read (Stream, Constant_Pool);
   ...
   u2'Read (Stream, Interfaces_Count);
   declare
      Interfaces : Interfaces_Count_Array (1 .. Interfaces_Count);
   begin
      ...
   end;
end;

HTH

--
Ludovic Brenta.



  parent reply	other threads:[~2009-04-03 13:37 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-04-03 12:01 Load an object from a file Olivier Scalbert
2009-04-03 13:07 ` Niklas Holsti
2009-04-03 13:37 ` Ludovic Brenta [this message]
2009-04-03 15:19   ` Olivier Scalbert
2009-04-03 16:08     ` Georg Bauhaus
2009-04-03 16:22       ` Ludovic Brenta
2009-04-03 16:41         ` Olivier Scalbert
2009-04-03 16:46       ` Adam Beneschan
2009-04-03 20:22         ` Ludovic Brenta
2009-04-09 20:32   ` Olivier Scalbert
2009-04-09 21:22     ` Ludovic Brenta
2009-04-09 22:22       ` Olivier Scalbert
2009-04-19 13:08   ` Olivier Scalbert
2009-04-19 19:52     ` Ludovic Brenta
2009-04-19 20:27     ` Gautier
2009-04-03 13:41 ` Thomas Løcke
replies disabled

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox