* Re: Load an object from a file
2009-04-03 13:37 ` Ludovic Brenta
@ 2009-04-03 15:19 ` Olivier Scalbert
2009-04-03 16:08 ` Georg Bauhaus
2009-04-09 20:32 ` Olivier Scalbert
2009-04-19 13:08 ` Olivier Scalbert
2 siblings, 1 reply; 16+ messages in thread
From: Olivier Scalbert @ 2009-04-03 15:19 UTC (permalink / raw)
Thanks Ludovic,
One more question:
with:
type u2 is new Integer;
type cp_info is new Integer;
type Constant_Pool_Array is array (Positive range <>) of cp_info;
type Interfaces_Array is array (Positive range <>) of u2;
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);
end record;
I have an error: expected type "Standard.Integer", in the 2 last lines.
If I replace the line:
"attributes_count : u2" by
"attributes_count : Integer"
then compile is Ok !
Don't know how to cleanly solve ...
Olivier
Ludovic Brenta wrote:
> 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.
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: Load an object from a file
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:46 ` Adam Beneschan
0 siblings, 2 replies; 16+ messages in thread
From: Georg Bauhaus @ 2009-04-03 16:08 UTC (permalink / raw)
Olivier Scalbert schrieb:
> Thanks Ludovic,
>
> One more question:
>
> with:
> type u2 is new Integer;
> type cp_info is new Integer;
>
> type Constant_Pool_Array is array (Positive range <>) of cp_info;
> type Interfaces_Array is array (Positive range <>) of u2;
Make the index type the same as the type in the disciminant,
that is, u2.
type Constant_Pool_Array is array (u2 range <>) of cp_info;
type Interfaces_Array is array (u2 range <>) of u2;
since U2 is the type of the discriminants used in providing
the array bounds.
In fact, very likely the type U2 is range 0 .. Something, with
Java's integer type semantics regarding overflow and wrap
around. Perhaps it is a good idea to express this in Ada
for U2 as well.
> 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);
> end record;
>
> I have an error: expected type "Standard.Integer", in the 2 last lines.
> If I replace the line:
> "attributes_count : u2" by
> "attributes_count : Integer"
> then compile is Ok !
> Don't know how to cleanly solve ...
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: Load an object from a file
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
1 sibling, 1 reply; 16+ messages in thread
From: Ludovic Brenta @ 2009-04-03 16:22 UTC (permalink / raw)
Georg Bauhaus wrote on comp.lang.ada:
> Olivier Scalbert schrieb:
>
> > Thanks Ludovic,
>
> > One more question:
>
> > with:
> > type u2 is new Integer;
> > type cp_info is new Integer;
>
> > type Constant_Pool_Array is array (Positive range <>) of cp_info;
> > type Interfaces_Array is array (Positive range <>) of u2;
>
> Make the index type the same as the type in the disciminant,
> that is, u2.
>
> type Constant_Pool_Array is array (u2 range <>) of cp_info;
> type Interfaces_Array is array (u2 range <>) of u2;
>
> since U2 is the type of the discriminants used in providing
> the array bounds.
>
> In fact, very likely the type U2 is range 0 .. Something, with
> Java's integer type semantics regarding overflow and wrap
> around. Perhaps it is a good idea to express this in Ada
> for U2 as well.
Right; in fact, Java's u2 probably corresponds to
type u2 is mod 2 ** 32; -- or perhaps 64?
--
Ludovic Brenta.
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: Load an object from a file
2009-04-03 16:22 ` Ludovic Brenta
@ 2009-04-03 16:41 ` Olivier Scalbert
0 siblings, 0 replies; 16+ messages in thread
From: Olivier Scalbert @ 2009-04-03 16:41 UTC (permalink / raw)
Ludovic Brenta wrote:
> Georg Bauhaus wrote on comp.lang.ada:
>> Olivier Scalbert schrieb:
>>
>>> Thanks Ludovic,
>>> One more question:
>>> with:
>>> type u2 is new Integer;
>>> type cp_info is new Integer;
>>> type Constant_Pool_Array is array (Positive range <>) of cp_info;
>>> type Interfaces_Array is array (Positive range <>) of u2;
>> Make the index type the same as the type in the disciminant,
>> that is, u2.
>>
>> type Constant_Pool_Array is array (u2 range <>) of cp_info;
>> type Interfaces_Array is array (u2 range <>) of u2;
>>
>> since U2 is the type of the discriminants used in providing
>> the array bounds.
>>
>> In fact, very likely the type U2 is range 0 .. Something, with
>> Java's integer type semantics regarding overflow and wrap
>> around. Perhaps it is a good idea to express this in Ada
>> for U2 as well.
>
> Right; in fact, Java's u2 probably corresponds to
>
> type u2 is mod 2 ** 32; -- or perhaps 64?
>
> --
> Ludovic Brenta.A class file consists of a stream of 8-bit bytes. All 16-bit, 32-bit, and 64-bit quantities are constructed by reading in two, four, and eight consecutive 8-bit bytes, respectively. Multibyte data items are always stored in big-endian order, where the high bytes come first. In the Java and Java 2 platforms, this format is supported by interfaces java.io.DataInput and java.io.DataOutput and classes such as java.io.DataInputStream and java.io.DataOutputStream.
Yes it works !
I should focus on the domain problem.
I should focus on the domain problem.
I should focus on the domain problem.
I should focus on the domain problem.
I should focus on the domain problem.
For your info:
...
A class file consists of a stream of 8-bit bytes. All 16-bit, 32-bit,
and 64-bit quantities are constructed by reading in two, four, and eight
consecutive 8-bit bytes, respectively. Multibyte data items are always
stored in big-endian order, where the high bytes come first.
...
This chapter defines its own set of data types representing class file
data: The types u1, u2, and u4 represent an unsigned one-, two-, or
four-byte quantity, respectively.
...
The firt 4 bytes that composed the magic field are:
0xCAFEBABE
;-)
Olivier
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: Load an object from a file
2009-04-03 16:08 ` Georg Bauhaus
2009-04-03 16:22 ` Ludovic Brenta
@ 2009-04-03 16:46 ` Adam Beneschan
2009-04-03 20:22 ` Ludovic Brenta
1 sibling, 1 reply; 16+ messages in thread
From: Adam Beneschan @ 2009-04-03 16:46 UTC (permalink / raw)
On Apr 3, 9:08 am, Georg Bauhaus <rm.dash-bauh...@futureapps.de>
wrote:
> Olivier Scalbert schrieb:
>
> > Thanks Ludovic,
>
> > One more question:
>
> > with:
> > type u2 is new Integer;
> > type cp_info is new Integer;
>
> > type Constant_Pool_Array is array (Positive range <>) of cp_info;
> > type Interfaces_Array is array (Positive range <>) of u2;
>
> Make the index type the same as the type in the disciminant,
> that is, u2.
>
> type Constant_Pool_Array is array (u2 range <>) of cp_info;
> type Interfaces_Array is array (u2 range <>) of u2;
>
> since U2 is the type of the discriminants used in providing
> the array bounds.
Or, if you want to keep the "Positive" aspect:
subtype Positive_U2 is U2 range 1 .. U2'Last;
type Constant_Pool_Array is array (Positive_U2 range <>) of
cp_info;
type Interfaces_Array is array (Positive_U2 range <>) of U2;
P.S. You may need to be a bit cautious if you define U2 as a modular
type, as Ludovic suggested, and then use it as the base type of an
unconstrained array. If you define
type Some_Array is array (u2 range <>) of u2;
you might be tempted to write code like this:
procedure Do_Some_Operation (Count : U2) is
Result : Some_Array (0 .. Count - 1);
...
If you call Do_Some_Operation(0), Result is not going to be an empty
array like you expect, but rather an array too large to fit in your
computer, because 0-1 doesn't return a negative number for modular
types but rather a very large positive number.
-- Adam
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: Load an object from a file
2009-04-03 16:46 ` Adam Beneschan
@ 2009-04-03 20:22 ` Ludovic Brenta
0 siblings, 0 replies; 16+ messages in thread
From: Ludovic Brenta @ 2009-04-03 20:22 UTC (permalink / raw)
Adam Beneschan wrote on comp.lang.ada:
> P.S. You may need to be a bit cautious if you define U2 as a modular
> type, as Ludovic suggested, and then use it as the base type of an
> unconstrained array. If you define
>
> type Some_Array is array (u2 range <>) of u2;
>
> you might be tempted to write code like this:
>
> procedure Do_Some_Operation (Count : U2) is
> Result : Some_Array (0 .. Count - 1);
> ...
>
> If you call Do_Some_Operation(0), Result is not going to be an empty
> array like you expect, but rather an array too large to fit in your
> computer, because 0-1 doesn't return a negative number for modular
> types but rather a very large positive number.
In the light of Adam's remark,
type u2 is mod 2 ** 16;
is the exact equivalent of Java's u2, but we now see that Java's u2
does _not_ represent the problem domain accurately; therefore defining
u2 in Ada as
type u2 is range 0 .. 2 ** 16 - 1;
does reflect the problem domain accurately (i.e. in the problem
domain, there is no wrap-around semantics) at the expense, perhaps, of
exposing bugs in the Java code :)
--
Ludovic Brenta.
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: Load an object from a file
2009-04-03 13:37 ` Ludovic Brenta
2009-04-03 15:19 ` Olivier Scalbert
@ 2009-04-09 20:32 ` Olivier Scalbert
2009-04-09 21:22 ` Ludovic Brenta
2009-04-19 13:08 ` Olivier Scalbert
2 siblings, 1 reply; 16+ messages in thread
From: Olivier Scalbert @ 2009-04-09 20:32 UTC (permalink / raw)
Hi,
I still have one question ...
How can I implement the Load_Class procedure that will use the Input
function?
I do not know how to get the needed stream from a given file name.
And I do not know how to define the Class_File_Structure result (I get
an unconstrained subtype (need initialization)).
Thanks,
Olivier
Here is my spec:
--------------------------
package jvm is
type Byte_T is range 0..255;
for Byte_T'Size use 8;
type U2_T is range 0 .. 2 ** 16 - 1;
type U4_T is range 0 .. 2 ** 32 - 1;
type cp_info_T is new Integer; -- Just for test !
type Constant_Pool_Array_T is array (U2_T range <>) of cp_info_T;
type Class_File_Structure_T(
constant_pool_count,
interfaces_count,
fields_count,
methods_count,
attributes_count : U2_T) is record
Magic : U4_T;
Minor_Version : U2_T;
Major_Version : U2_T;
Constant_Pool : Constant_Pool_Array_T (2 .. constant_pool_count);
--interfaces : Interfaces_Array_T (1 .. interfaces_count);
end record;
procedure Run;
procedure Load_Class(File_Name: String);
function Input(Stream : not null access
Ada.Streams.Root_Stream_Type'Class)
return Class_File_Structure_T; -- see RM 13.13(22)
and following
for Class_File_Structure_T'Input use Input; -- as per RM 13.13(38/2)
end jvm;
Here is the body:
--------------------------
with Ada.Text_IO; use Ada.Text_IO;
with Ada.Sequential_IO;
with Ada.Unchecked_Deallocation;
package body jvm is
procedure run is
begin
Load_Class("Main.class");
end run;
procedure Load_Class(File_Name: String) is
Class_File_Structure: Class_File_Structure_T; -- (unconstrained
subtype (need initialization)
begin
Put_Line(File_Name);
Class_file_Structure := Input(Stream ???);
end Load_Class;
function Input(Stream : not null access
Ada.Streams.Root_Stream_Type'Class)
return Class_File_Structure_T is
Magic : U4_T;
Minor_Version : U2_T;
Major_Version : U2_T;
Constant_Pool_Count : U2_T;
type Constant_Pool_Array_Access is access Constant_Pool_Array_T;
procedure Free is new Ada.Unchecked_Deallocation
(Constant_Pool_Array_T, Constant_Pool_Array_Access);
Constant_Pool : Constant_Pool_Array_Access;
begin
-- Read
U4_T'Read(Stream, Magic);
U2_T'Read(Stream, Minor_Version);
U2_T'Read(Stream, Major_Version);
U2_T'Read (Stream, Constant_Pool_Count);
Constant_Pool := new Constant_Pool_Array_T (1 ..
Constant_Pool_Count - 1);
Constant_Pool_Array_T'Read (Stream, Constant_Pool.all);
-- Fill in to the result
declare
Result : Class_File_Structure_T
(constant_pool_count => Constant_Pool_Count,
interfaces_count => 0, --Interfaces_Count,
fields_count => 0, --Fields_Count,
methods_count => 0, --Methods_Count,
attributes_count => 0); --Attricutes_Count);
begin
Result.Magic := Magic;
Result.Minor_Version := Minor_Version;
Result.Major_Version := Major_Version;
Result.Constant_Pool := Constant_Pool.all;
Free(Constant_Pool);
return Result;
end;
end;
end jvm;
Ludovic Brenta wrote:
> 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.
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: Load an object from a file
2009-04-09 20:32 ` Olivier Scalbert
@ 2009-04-09 21:22 ` Ludovic Brenta
2009-04-09 22:22 ` Olivier Scalbert
0 siblings, 1 reply; 16+ messages in thread
From: Ludovic Brenta @ 2009-04-09 21:22 UTC (permalink / raw)
On Apr 9, 10:32 pm, Olivier Scalbert <olivier.scalb...@algosyn.com>
wrote:
> Hi,
>
> I still have one question ...
> How can I implement the Load_Class procedure that will use the Input
> function?
> I do not know how to get the needed stream from a given file name.
> And I do not know how to define the Class_File_Structure result (I get
> an unconstrained subtype (need initialization)).
[...]
> package body jvm is
[...]
> procedure Load_Class(File_Name: String) is
>
> Class_File_Structure: Class_File_Structure_T; -- (unconstrained
> subtype (need initialization)
> begin
> Put_Line(File_Name);
>
> Class_file_Structure := Input(Stream ???);
>
> end Load_Class;
[...]
> end jvm;
Because Class_File_Structure_T is unconstrained and needs
initialization, you cannot use a procedure to load one: out parameters
don't work, and the procedure cannot write into a variable because you
can't declare a variable without initializing it. So, here is a
possible solution replacing your procedure with a function:
with Ada.Streams.Stream_IO;
...
function From_File (File_Name : String) return Class_File_Structure_T
is
File : Ada.Streams.Stream_IO.File_Type;
begin
Ada.Streams.Stream_IO.Open (File,
File_Mode =>
Ada.Streams.Stream_IO.In_File,
Name => File_Name);
declare
Result : constant Class_File_Structure_T :=
Class_File_Structure_T'Input (Ada.Streams.Stream_IO.Stream
(File));
begin
Ada.Streams.Stream_IO.Close (File);
return Result;
end;
end From_File;
HTH
--
Ludovic Brenta.
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: Load an object from a file
2009-04-03 13:37 ` Ludovic Brenta
2009-04-03 15:19 ` Olivier Scalbert
2009-04-09 20:32 ` Olivier Scalbert
@ 2009-04-19 13:08 ` Olivier Scalbert
2009-04-19 19:52 ` Ludovic Brenta
2009-04-19 20:27 ` Gautier
2 siblings, 2 replies; 16+ messages in thread
From: Olivier Scalbert @ 2009-04-19 13:08 UTC (permalink / raw)
Hello,
I have an endianness problem. In the file, The u2 data are stored in
big-endian order. As I am working on a Pentium, the reading is done in
little-endian order. Is it possible to fix it with the representation
stuff ?
Thanks,
Olivier
Ludovic Brenta wrote:
>
> 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.
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: Load an object from a file
2009-04-19 13:08 ` Olivier Scalbert
@ 2009-04-19 19:52 ` Ludovic Brenta
2009-04-19 20:27 ` Gautier
1 sibling, 0 replies; 16+ messages in thread
From: Ludovic Brenta @ 2009-04-19 19:52 UTC (permalink / raw)
Olivier Scalbert wrote on comp.lang.ada:
> I have an endianness problem. In the file, The u2 data are stored in
> big-endian order. As I am working on a Pentium, the reading is done in
> little-endian order. Is it possible to fix it with the representation
> stuff ?
No; Ada's representation clauses only allow you to control bit order,
not
byte order. On little-endian architectures, you'll have to resort to
something like
procedure Read (Stream : access Ada.Streams.Root_Stream_Type'Class;
Item : out u2) is
type Byte is mod 2**8;
for Byte'Size use 8;
High_Order, Low_Order : Byte;
begin
Byte'Read (Stream, High_Order); -- call the predefined Read for
type Byte
Byte'Read (Stream, Low_Order);
Item := High_Order * 2**8 + Low_Order;
end Read;
for u2'Read use Read;
HTH
--
Ludovic Brenta.
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: Load an object from a file
2009-04-19 13:08 ` Olivier Scalbert
2009-04-19 19:52 ` Ludovic Brenta
@ 2009-04-19 20:27 ` Gautier
1 sibling, 0 replies; 16+ messages in thread
From: Gautier @ 2009-04-19 20:27 UTC (permalink / raw)
In the GLOBE_3D and Zip-Ada projects (from link below) you'll
find the generic Intel_nb functions that do the I/O by merging/splitting
integers of various sizes from/to bytes (the way Ludovic described).
It is in the packages GLOBE_3D.IO and Zip.Headers respectively.
On the other hand, I kind of remember having read about a GNAT-only way
to replace some run-time package to obtain the same with less efforts:
T'Read could be doable with a specific endianess, no need to load in
small pieces. Maybe I'm dreaming ?...
_________________________________________________________
Gautier's Ada programming -- http://sf.net/users/gdemont/
NB: For a direct answer, e-mail address on the Web site!
^ permalink raw reply [flat|nested] 16+ messages in thread