1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131
|
with Ada.Streams.Stream_Io; use Ada.Streams.Stream_Io;
with Text_Io;
-- Remplir un buffer a la sauvage.
-- C'est brut de fonderie, il faut y aller sur des oeufs,
-- Ca ne gere absolument pas les endians, donc gaffe.
-- C'est très crade, mieux vaut implementer des Stream (ma solution préférée), mais c'est plus ... direct.
-- Par contre, le buffer meriterait un package pour lui tout seul avec ses petites fonctions
-- pour rendre le biniou plus propre.
procedure Ugly is
-- definition des types utilises dans l'exemple.
type Index_T is range 1 .. 100;
type Octet_T is mod 2**8;
for Octet_T'Size use 8;
type A is mod 2**16;
for A'Size use 16;
type B is mod 2**32;
for B'Size use 32;
type Buffer_T is array(Index_T range <>) of Octet_T;
type R1 is
record
R1_1 : A;
R1_2 : A;
end record;
for R1 use
record
R1_1 at 0 range 0 .. 15;
R1_2 at 2 range 0 .. 15;
end record;
for R1'Size use 32;
type R2 is
record
R2_1 : A;
R2_2 : B;
end record;
for R2 use
record
R2_1 at 0 range 0 .. 15;
R2_2 at 2 range 0 .. 31;
end record;
for R2'Size use 48;
type Desc_T is (First, Last);
for Desc_T use (First => 0, Last => 1);
for Desc_T'Size use 8;
-- notre type variant.
type V(Desc : Desc_T := First) is
record
case Desc is
when First =>
V_1 : R1;
when Last =>
V_2 : R2;
end case;
end record;
for V use
record
Desc at 0 range 0 .. 7;
V_1 at 1 range 0 .. 31;
V_2 at 1 range 0 .. 47;
end record;
Buffer : Buffer_T(1 .. 12);
Read_Index : Index_T := 1; -- index a gerer pour savoir ou lire
Write_Index : Index_T := 1; -- index a gerer pour savoir ou ecrire.
V_First_Size : constant Index_T := 5;
V_Last_Size : constant Index_T := 7;
File : File_Type;
Output : Stream_Access;
begin
Create(File => File, Name => "toto.dat");
Output := Stream(File);
declare
X : V := (First, (2,3));
for X'Address use Buffer(Write_Index)'Address;
-- on se positionne dans le buffer.
begin
Write_Index := Write_Index + V_First_Size;
-- et on oublie pas de mettre à jour
-- la position de la prochaine ecriture, sinon, c'est la cata!
end;
declare
Y : V := (Last, (4,5));
for Y'Address use Buffer(Write_Index)'Address;
begin
Write_Index := Write_Index + V_Last_Size;
end;
for Index in Buffer'Range loop
Octet_T'Write(Output, Buffer(Index));
end loop;
Close(File);
declare
X : V;
pragma Import(Ada,X); -- cet import sert a eviter qu'Ada rale a cause de l'initialisation du variant.
for X'Address use Buffer(Read_Index)'Address;
begin
Text_Io.Put_Line(Desc_T'Image(X.Desc) & " " &
A'Image(X.V_1.R1_1) & " " &
A'Image(X.V_1.R1_2));
Read_Index := Read_Index + V_First_Size;
end;
declare
X : V;
pragma Import(Ada,X); -- comme le precedent
for X'Address use Buffer(Read_Index)'Address;
begin
Text_Io.Put_Line(Desc_T'Image(X.Desc) & " " &
A'Image(X.V_2.R2_1) & " " &
B'Image(X.V_2.R2_2));
end;
end Ugly; |
Partager