1 ------------------------------------------------------------------------------
3 -- GNAT RUNTIME COMPONENTS --
5 -- S Y S T E M . S T R E A M _ A T T R I B U T E S --
9 -- Copyright (C) 1996-2003 Free Software Foundation, Inc. --
11 -- GARLIC is free software; you can redistribute it and/or modify it under --
12 -- terms of the GNU General Public License as published by the Free Soft- --
13 -- ware Foundation; either version 2, or (at your option) any later ver- --
14 -- sion. GARLIC is distributed in the hope that it will be useful, but --
15 -- WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABI- --
16 -- LITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public --
17 -- License for more details. You should have received a copy of the GNU --
18 -- General Public License distributed with GARLIC; see file COPYING. If --
19 -- not, write to the Free Software Foundation, 59 Temple Place - Suite 330, --
20 -- Boston, MA 02111-1307, USA. --
22 -- As a special exception, if other files instantiate generics from this --
23 -- unit, or you link this unit with other files to produce an executable, --
24 -- this unit does not by itself cause the resulting executable to be --
25 -- covered by the GNU General Public License. This exception does not --
26 -- however invalidate any other reasons why the executable file might be --
27 -- covered by the GNU Public License. --
29 -- GNAT was originally developed by the GNAT team at New York University. --
30 -- Extensive contributions were provided by Ada Core Technologies Inc. --
32 ------------------------------------------------------------------------------
34 -- This file is an alternate version of s-stratt.adb based on the XDR
35 -- standard. It is especially useful for exchanging streams between two
36 -- different systems with different basic type representations and endianess.
38 with Ada
.Streams
; use Ada
.Streams
;
39 with Ada
.Unchecked_Conversion
;
41 package body System
.Stream_Attributes
is
43 pragma Suppress
(Range_Check
);
44 pragma Suppress
(Overflow_Check
);
48 Data_Error
: exception;
49 -- Exception raised if insufficient data read.
51 SU
: constant := System
.Storage_Unit
;
52 -- XXXXX pragma Assert (SU = 8);
54 BB
: constant := 2 ** SU
; -- Byte base
55 BL
: constant := 2 ** SU
- 1; -- Byte last
56 BS
: constant := 2 ** (SU
- 1); -- Byte sign
58 US
: constant := Unsigned
'Size; -- Unsigned size
59 UB
: constant := (US
- 1) / SU
+ 1; -- Unsigned byte
60 UL
: constant := 2 ** US
- 1; -- Unsigned last
62 subtype SE
is Ada
.Streams
.Stream_Element
;
63 subtype SEA
is Ada
.Streams
.Stream_Element_Array
;
64 subtype SEO
is Ada
.Streams
.Stream_Element_Offset
;
66 generic function UC
renames Ada
.Unchecked_Conversion
;
70 E_Size
: Integer; -- Exponent bit size
71 E_Bias
: Integer; -- Exponent bias
72 F_Size
: Integer; -- Fraction bit size
73 E_Last
: Integer; -- Max exponent value
74 F_Mask
: SE
; -- Mask to apply on first fraction byte
75 E_Bytes
: SEO
; -- N. of exponent bytes completly used
76 F_Bytes
: SEO
; -- N. of fraction bytes completly used
77 F_Bits
: Integer; -- N. of bits used on first fraction word
80 type Precision
is (Single
, Double
, Quadruple
);
82 Fields
: constant array (Precision
) of Field_Type
:= (
90 F_Mask
=> 16#
7F#
, -- 2 ** 7 - 1,
100 E_Last
=> 2 ** 11 - 1,
101 F_Mask
=> 16#
0F#
, -- 2 ** 4 - 1,
104 F_Bits
=> 52 mod US
),
106 -- Quadruple precision
111 E_Last
=> 2 ** 8 - 1,
112 F_Mask
=> 16#FF#
, -- 2 ** 8 - 1,
115 F_Bits
=> 112 mod US
));
117 -- The representation of all items requires a multiple of four bytes
118 -- (or 32 bits) of data. The bytes are numbered 0 through n-1. The bytes
119 -- are read or written to some byte stream such that byte m always
120 -- precedes byte m+1. If the n bytes needed to contain the data are not
121 -- a multiple of four, then the n bytes are followed by enough (0 to 3)
122 -- residual zero bytes, r, to make the total byte count a multiple of 4.
124 -- An XDR signed integer is a 32-bit datum that encodes an integer
125 -- in the range [-2147483648,2147483647]. The integer is represented
126 -- in two's complement notation. The most and least significant bytes
127 -- are 0 and 3, respectively. Integers are declared as follows:
130 -- +-------+-------+-------+-------+
131 -- |byte 0 |byte 1 |byte 2 |byte 3 |
132 -- +-------+-------+-------+-------+
133 -- <------------32 bits------------>
135 SSI_L
: constant := 1;
136 SI_L
: constant := 2;
138 LI_L
: constant := 8;
139 LLI_L
: constant := 8;
141 subtype XDR_S_SSI
is SEA
(1 .. SSI_L
);
142 subtype XDR_S_SI
is SEA
(1 .. SI_L
);
143 subtype XDR_S_I
is SEA
(1 .. I_L
);
144 subtype XDR_S_LI
is SEA
(1 .. LI_L
);
145 subtype XDR_S_LLI
is SEA
(1 .. LLI_L
);
147 function Short_Short_Integer_To_XDR_S_SSI
is
148 new Ada
.Unchecked_Conversion
(Short_Short_Integer, XDR_S_SSI
);
149 function XDR_S_SSI_To_Short_Short_Integer
is
150 new Ada
.Unchecked_Conversion
(XDR_S_SSI
, Short_Short_Integer);
152 function Short_Integer_To_XDR_S_SI
is
153 new Ada
.Unchecked_Conversion
(Short_Integer, XDR_S_SI
);
154 function XDR_S_SI_To_Short_Integer
is
155 new Ada
.Unchecked_Conversion
(XDR_S_SI
, Short_Integer);
157 function Integer_To_XDR_S_I
is
158 new Ada
.Unchecked_Conversion
(Integer, XDR_S_I
);
159 function XDR_S_I_To_Integer
is
160 new Ada
.Unchecked_Conversion
(XDR_S_I
, Integer);
162 function Long_Long_Integer_To_XDR_S_LI
is
163 new Ada
.Unchecked_Conversion
(Long_Long_Integer, XDR_S_LI
);
164 function XDR_S_LI_To_Long_Long_Integer
is
165 new Ada
.Unchecked_Conversion
(XDR_S_LI
, Long_Long_Integer);
167 function Long_Long_Integer_To_XDR_S_LLI
is
168 new Ada
.Unchecked_Conversion
(Long_Long_Integer, XDR_S_LLI
);
169 function XDR_S_LLI_To_Long_Long_Integer
is
170 new Ada
.Unchecked_Conversion
(XDR_S_LLI
, Long_Long_Integer);
172 -- An XDR unsigned integer is a 32-bit datum that encodes a nonnegative
173 -- integer in the range [0,4294967295]. It is represented by an unsigned
174 -- binary number whose most and least significant bytes are 0 and 3,
175 -- respectively. An unsigned integer is declared as follows:
178 -- +-------+-------+-------+-------+
179 -- |byte 0 |byte 1 |byte 2 |byte 3 |
180 -- +-------+-------+-------+-------+
181 -- <------------32 bits------------>
183 SSU_L
: constant := 1;
184 SU_L
: constant := 2;
186 LU_L
: constant := 8;
187 LLU_L
: constant := 8;
189 subtype XDR_S_SSU
is SEA
(1 .. SSU_L
);
190 subtype XDR_S_SU
is SEA
(1 .. SU_L
);
191 subtype XDR_S_U
is SEA
(1 .. U_L
);
192 subtype XDR_S_LU
is SEA
(1 .. LU_L
);
193 subtype XDR_S_LLU
is SEA
(1 .. LLU_L
);
195 type XDR_SSU
is mod BB
** SSU_L
;
196 type XDR_SU
is mod BB
** SU_L
;
197 type XDR_U
is mod BB
** U_L
;
199 function Short_Unsigned_To_XDR_S_SU
is
200 new Ada
.Unchecked_Conversion
(Short_Unsigned
, XDR_S_SU
);
201 function XDR_S_SU_To_Short_Unsigned
is
202 new Ada
.Unchecked_Conversion
(XDR_S_SU
, Short_Unsigned
);
204 function Unsigned_To_XDR_S_U
is
205 new Ada
.Unchecked_Conversion
(Unsigned
, XDR_S_U
);
206 function XDR_S_U_To_Unsigned
is
207 new Ada
.Unchecked_Conversion
(XDR_S_U
, Unsigned
);
209 function Long_Long_Unsigned_To_XDR_S_LU
is
210 new Ada
.Unchecked_Conversion
(Long_Long_Unsigned
, XDR_S_LU
);
211 function XDR_S_LU_To_Long_Long_Unsigned
is
212 new Ada
.Unchecked_Conversion
(XDR_S_LU
, Long_Long_Unsigned
);
214 function Long_Long_Unsigned_To_XDR_S_LLU
is
215 new Ada
.Unchecked_Conversion
(Long_Long_Unsigned
, XDR_S_LLU
);
216 function XDR_S_LLU_To_Long_Long_Unsigned
is
217 new Ada
.Unchecked_Conversion
(XDR_S_LLU
, Long_Long_Unsigned
);
219 -- The standard defines the floating-point data type "float" (32 bits
220 -- or 4 bytes). The encoding used is the IEEE standard for normalized
221 -- single-precision floating-point numbers.
223 -- The standard defines the encoding for the double-precision
224 -- floating-point data type "double" (64 bits or 8 bytes). The
225 -- encoding used is the IEEE standard for normalized double-precision
226 -- floating-point numbers.
228 SF_L
: constant := 4; -- Single precision
229 F_L
: constant := 4; -- Single precision
230 LF_L
: constant := 8; -- Double precision
231 LLF_L
: constant := 16; -- Quadruple precision
233 TM_L
: constant := 8;
234 subtype XDR_S_TM
is SEA
(1 .. TM_L
);
235 type XDR_TM
is mod BB
** TM_L
;
237 type XDR_SA
is mod 2 ** Standard
'Address_Size;
238 function To_XDR_SA
is new UC
(System
.Address
, XDR_SA
);
239 function To_XDR_SA
is new UC
(XDR_SA
, System
.Address
);
241 -- Enumerations have the same representation as signed integers.
242 -- Enumerations are handy for describing subsets of the integers.
244 -- Booleans are important enough and occur frequently enough to warrant
245 -- their own explicit type in the standard. Booleans are declared as
246 -- an enumeration, with FALSE = 0 and TRUE = 1.
248 -- The standard defines a string of n (numbered 0 through n-1) ASCII
249 -- bytes to be the number n encoded as an unsigned integer (as described
250 -- above), and followed by the n bytes of the string. Byte m of the string
251 -- always precedes byte m+1 of the string, and byte 0 of the string always
252 -- follows the string's length. If n is not a multiple of four, then the
253 -- n bytes are followed by enough (0 to 3) residual zero bytes, r, to make
254 -- the total byte count a multiple of four.
256 -- To fit with XDR string, do not consider character as an enumeration
260 subtype XDR_S_C
is SEA
(1 .. C_L
);
262 -- Consider Wide_Character as an enumeration type
264 WC_L
: constant := 4;
265 subtype XDR_S_WC
is SEA
(1 .. WC_L
);
266 type XDR_WC
is mod BB
** WC_L
;
268 -- Optimization: if we already have the correct Bit_Order, then some
269 -- computations can be avoided since the source and the target will be
270 -- identical anyway. They will be replaced by direct unchecked
273 Optimize_Integers
: constant Boolean :=
274 Default_Bit_Order
= High_Order_First
;
280 function I_AD
(Stream
: access RST
) return Fat_Pointer
is
284 FP
.P1
:= I_AS
(Stream
).P1
;
285 FP
.P2
:= I_AS
(Stream
).P1
;
294 function I_AS
(Stream
: access RST
) return Thin_Pointer
is
300 Ada
.Streams
.Read
(Stream
.all, S
, L
);
305 for N
in S
'Range loop
306 U
:= U
* BB
+ XDR_TM
(S
(N
));
309 return (P1
=> To_XDR_SA
(XDR_SA
(U
)));
317 function I_B
(Stream
: access RST
) return Boolean is
319 case I_SSU
(Stream
) is
320 when 0 => return False;
321 when 1 => return True;
322 when others => raise Data_Error
;
330 function I_C
(Stream
: access RST
) return Character is
335 Ada
.Streams
.Read
(Stream
.all, S
, L
);
341 -- Use Ada requirements on Character representation clause
343 return Character'Val (S
(1));
351 function I_F
(Stream
: access RST
) return Float is
352 I
: constant Precision
:= Single
;
353 E_Size
: Integer renames Fields
(I
).E_Size
;
354 E_Bias
: Integer renames Fields
(I
).E_Bias
;
355 E_Last
: Integer renames Fields
(I
).E_Last
;
356 F_Mask
: SE
renames Fields
(I
).F_Mask
;
357 E_Bytes
: SEO
renames Fields
(I
).E_Bytes
;
358 F_Bytes
: SEO
renames Fields
(I
).F_Bytes
;
359 F_Size
: Integer renames Fields
(I
).F_Size
;
362 Exponent
: Long_Unsigned
;
363 Fraction
: Long_Unsigned
;
369 Ada
.Streams
.Read
(Stream
.all, S
, L
);
375 -- Extract Fraction, Sign and Exponent
377 Fraction
:= Long_Unsigned
(S
(F_L
+ 1 - F_Bytes
) and F_Mask
);
378 for N
in F_L
+ 2 - F_Bytes
.. F_L
loop
379 Fraction
:= Fraction
* BB
+ Long_Unsigned
(S
(N
));
381 Result
:= Float'Scaling (Float (Fraction
), -F_Size
);
385 Exponent
:= Long_Unsigned
(S
(1) - BS
);
388 Exponent
:= Long_Unsigned
(S
(1));
391 for N
in 2 .. E_Bytes
loop
392 Exponent
:= Exponent
* BB
+ Long_Unsigned
(S
(N
));
394 Exponent
:= Shift_Right
(Exponent
, Integer (E_Bytes
) * SU
- E_Size
- 1);
398 if Integer (Exponent
) = E_Last
then
399 raise Constraint_Error
;
401 elsif Exponent
= 0 then
408 -- Denormalized float
411 Result
:= Float'Scaling (Result
, 1 - E_Bias
);
417 Result
:= Float'Scaling
418 (1.0 + Result
, Integer (Exponent
) - E_Bias
);
432 function I_I
(Stream
: access RST
) return Integer is
438 Ada
.Streams
.Read
(Stream
.all, S
, L
);
443 elsif Optimize_Integers
then
444 return XDR_S_I_To_Integer
(S
);
447 for N
in S
'Range loop
448 U
:= U
* BB
+ XDR_U
(S
(N
));
451 -- Test sign and apply two complement notation
457 return Integer (-((XDR_U
'Last xor U
) + 1));
466 function I_LF
(Stream
: access RST
) return Long_Float is
467 I
: constant Precision
:= Double
;
468 E_Size
: Integer renames Fields
(I
).E_Size
;
469 E_Bias
: Integer renames Fields
(I
).E_Bias
;
470 E_Last
: Integer renames Fields
(I
).E_Last
;
471 F_Mask
: SE
renames Fields
(I
).F_Mask
;
472 E_Bytes
: SEO
renames Fields
(I
).E_Bytes
;
473 F_Bytes
: SEO
renames Fields
(I
).F_Bytes
;
474 F_Size
: Integer renames Fields
(I
).F_Size
;
477 Exponent
: Long_Unsigned
;
478 Fraction
: Long_Long_Unsigned
;
484 Ada
.Streams
.Read
(Stream
.all, S
, L
);
490 -- Extract Fraction, Sign and Exponent
492 Fraction
:= Long_Long_Unsigned
(S
(LF_L
+ 1 - F_Bytes
) and F_Mask
);
493 for N
in LF_L
+ 2 - F_Bytes
.. LF_L
loop
494 Fraction
:= Fraction
* BB
+ Long_Long_Unsigned
(S
(N
));
497 Result
:= Long_Float'Scaling (Long_Float (Fraction
), -F_Size
);
501 Exponent
:= Long_Unsigned
(S
(1) - BS
);
504 Exponent
:= Long_Unsigned
(S
(1));
507 for N
in 2 .. E_Bytes
loop
508 Exponent
:= Exponent
* BB
+ Long_Unsigned
(S
(N
));
511 Exponent
:= Shift_Right
(Exponent
, Integer (E_Bytes
) * SU
- E_Size
- 1);
515 if Integer (Exponent
) = E_Last
then
516 raise Constraint_Error
;
518 elsif Exponent
= 0 then
525 -- Denormalized float
528 Result
:= Long_Float'Scaling (Result
, 1 - E_Bias
);
534 Result
:= Long_Float'Scaling
535 (1.0 + Result
, Integer (Exponent
) - E_Bias
);
549 function I_LI
(Stream
: access RST
) return Long_Integer is
553 X
: Long_Unsigned
:= 0;
556 Ada
.Streams
.Read
(Stream
.all, S
, L
);
561 elsif Optimize_Integers
then
562 return Long_Integer (XDR_S_LI_To_Long_Long_Integer
(S
));
566 -- Compute using machine unsigned
567 -- rather than long_long_unsigned
569 for N
in S
'Range loop
570 U
:= U
* BB
+ Unsigned
(S
(N
));
572 -- We have filled an unsigned
575 X
:= Shift_Left
(X
, US
) + Long_Unsigned
(U
);
580 -- Test sign and apply two complement notation
583 return Long_Integer (X
);
585 return Long_Integer (-((Long_Unsigned
'Last xor X
) + 1));
595 function I_LLF
(Stream
: access RST
) return Long_Long_Float is
596 I
: constant Precision
:= Quadruple
;
597 E_Size
: Integer renames Fields
(I
).E_Size
;
598 E_Bias
: Integer renames Fields
(I
).E_Bias
;
599 E_Last
: Integer renames Fields
(I
).E_Last
;
600 E_Bytes
: SEO
renames Fields
(I
).E_Bytes
;
601 F_Bytes
: SEO
renames Fields
(I
).F_Bytes
;
602 F_Size
: Integer renames Fields
(I
).F_Size
;
605 Exponent
: Long_Unsigned
;
606 Fraction_1
: Long_Long_Unsigned
:= 0;
607 Fraction_2
: Long_Long_Unsigned
:= 0;
608 Result
: Long_Long_Float;
609 HF
: constant Natural := F_Size
/ 2;
610 S
: SEA
(1 .. LLF_L
);
614 Ada
.Streams
.Read
(Stream
.all, S
, L
);
620 -- Extract Fraction, Sign and Exponent
622 for I
in LLF_L
- F_Bytes
+ 1 .. LLF_L
- 7 loop
623 Fraction_1
:= Fraction_1
* BB
+ Long_Long_Unsigned
(S
(I
));
626 for I
in SEO
(LLF_L
- 6) .. SEO
(LLF_L
) loop
627 Fraction_2
:= Fraction_2
* BB
+ Long_Long_Unsigned
(S
(I
));
630 Result
:= Long_Long_Float'Scaling (Long_Long_Float (Fraction_2
), -HF
);
631 Result
:= Long_Long_Float (Fraction_1
) + Result
;
632 Result
:= Long_Long_Float'Scaling (Result
, HF
- F_Size
);
636 Exponent
:= Long_Unsigned
(S
(1) - BS
);
639 Exponent
:= Long_Unsigned
(S
(1));
642 for N
in 2 .. E_Bytes
loop
643 Exponent
:= Exponent
* BB
+ Long_Unsigned
(S
(N
));
646 Exponent
:= Shift_Right
(Exponent
, Integer (E_Bytes
) * SU
- E_Size
- 1);
650 if Integer (Exponent
) = E_Last
then
651 raise Constraint_Error
;
653 elsif Exponent
= 0 then
657 if Fraction_1
= 0 and then Fraction_2
= 0 then
660 -- Denormalized float
663 Result
:= Long_Long_Float'Scaling (Result
, 1 - E_Bias
);
669 Result
:= Long_Long_Float'Scaling
670 (1.0 + Result
, Integer (Exponent
) - E_Bias
);
684 function I_LLI
(Stream
: access RST
) return Long_Long_Integer is
688 X
: Long_Long_Unsigned
:= 0;
691 Ada
.Streams
.Read
(Stream
.all, S
, L
);
695 elsif Optimize_Integers
then
696 return XDR_S_LLI_To_Long_Long_Integer
(S
);
699 -- Compute using machine unsigned for computing
700 -- rather than long_long_unsigned.
702 for N
in S
'Range loop
703 U
:= U
* BB
+ Unsigned
(S
(N
));
705 -- We have filled an unsigned
708 X
:= Shift_Left
(X
, US
) + Long_Long_Unsigned
(U
);
713 -- Test sign and apply two complement notation
716 return Long_Long_Integer (X
);
718 return Long_Long_Integer (-((Long_Long_Unsigned
'Last xor X
) + 1));
727 function I_LLU
(Stream
: access RST
) return Long_Long_Unsigned
is
731 X
: Long_Long_Unsigned
:= 0;
734 Ada
.Streams
.Read
(Stream
.all, S
, L
);
738 elsif Optimize_Integers
then
739 return XDR_S_LLU_To_Long_Long_Unsigned
(S
);
742 -- Compute using machine unsigned
743 -- rather than long_long_unsigned.
745 for N
in S
'Range loop
746 U
:= U
* BB
+ Unsigned
(S
(N
));
748 -- We have filled an unsigned
751 X
:= Shift_Left
(X
, US
) + Long_Long_Unsigned
(U
);
764 function I_LU
(Stream
: access RST
) return Long_Unsigned
is
768 X
: Long_Unsigned
:= 0;
771 Ada
.Streams
.Read
(Stream
.all, S
, L
);
775 elsif Optimize_Integers
then
776 return Long_Unsigned
(XDR_S_LU_To_Long_Long_Unsigned
(S
));
779 -- Compute using machine unsigned
780 -- rather than long_unsigned.
782 for N
in S
'Range loop
783 U
:= U
* BB
+ Unsigned
(S
(N
));
785 -- We have filled an unsigned
788 X
:= Shift_Left
(X
, US
) + Long_Unsigned
(U
);
801 function I_SF
(Stream
: access RST
) return Short_Float is
802 I
: constant Precision
:= Single
;
803 E_Size
: Integer renames Fields
(I
).E_Size
;
804 E_Bias
: Integer renames Fields
(I
).E_Bias
;
805 E_Last
: Integer renames Fields
(I
).E_Last
;
806 F_Mask
: SE
renames Fields
(I
).F_Mask
;
807 E_Bytes
: SEO
renames Fields
(I
).E_Bytes
;
808 F_Bytes
: SEO
renames Fields
(I
).F_Bytes
;
809 F_Size
: Integer renames Fields
(I
).F_Size
;
811 Exponent
: Long_Unsigned
;
812 Fraction
: Long_Unsigned
;
814 Result
: Short_Float;
819 Ada
.Streams
.Read
(Stream
.all, S
, L
);
825 -- Extract Fraction, Sign and Exponent
827 Fraction
:= Long_Unsigned
(S
(SF_L
+ 1 - F_Bytes
) and F_Mask
);
828 for N
in SF_L
+ 2 - F_Bytes
.. SF_L
loop
829 Fraction
:= Fraction
* BB
+ Long_Unsigned
(S
(N
));
831 Result
:= Short_Float'Scaling (Short_Float (Fraction
), -F_Size
);
835 Exponent
:= Long_Unsigned
(S
(1) - BS
);
838 Exponent
:= Long_Unsigned
(S
(1));
841 for N
in 2 .. E_Bytes
loop
842 Exponent
:= Exponent
* BB
+ Long_Unsigned
(S
(N
));
844 Exponent
:= Shift_Right
(Exponent
, Integer (E_Bytes
) * SU
- E_Size
- 1);
848 if Integer (Exponent
) = E_Last
then
849 raise Constraint_Error
;
851 elsif Exponent
= 0 then
858 -- Denormalized float
861 Result
:= Short_Float'Scaling (Result
, 1 - E_Bias
);
867 Result
:= Short_Float'Scaling
868 (1.0 + Result
, Integer (Exponent
) - E_Bias
);
882 function I_SI
(Stream
: access RST
) return Short_Integer is
888 Ada
.Streams
.Read
(Stream
.all, S
, L
);
893 elsif Optimize_Integers
then
894 return XDR_S_SI_To_Short_Integer
(S
);
897 for N
in S
'Range loop
898 U
:= U
* BB
+ XDR_SU
(S
(N
));
901 -- Test sign and apply two complement notation
904 return Short_Integer (U
);
906 return Short_Integer (-((XDR_SU
'Last xor U
) + 1));
915 function I_SSI
(Stream
: access RST
) return Short_Short_Integer is
921 Ada
.Streams
.Read
(Stream
.all, S
, L
);
925 elsif Optimize_Integers
then
926 return XDR_S_SSI_To_Short_Short_Integer
(S
);
928 U
:= XDR_SSU
(S
(1));
930 -- Test sign and apply two complement notation
933 return Short_Short_Integer (U
);
935 return Short_Short_Integer (-((XDR_SSU
'Last xor U
) + 1));
944 function I_SSU
(Stream
: access RST
) return Short_Short_Unsigned
is
950 Ada
.Streams
.Read
(Stream
.all, S
, L
);
955 U
:= XDR_SSU
(S
(1));
957 return Short_Short_Unsigned
(U
);
965 function I_SU
(Stream
: access RST
) return Short_Unsigned
is
971 Ada
.Streams
.Read
(Stream
.all, S
, L
);
975 elsif Optimize_Integers
then
976 return XDR_S_SU_To_Short_Unsigned
(S
);
978 for N
in S
'Range loop
979 U
:= U
* BB
+ XDR_SU
(S
(N
));
982 return Short_Unsigned
(U
);
990 function I_U
(Stream
: access RST
) return Unsigned
is
996 Ada
.Streams
.Read
(Stream
.all, S
, L
);
1001 elsif Optimize_Integers
then
1002 return XDR_S_U_To_Unsigned
(S
);
1005 for N
in S
'Range loop
1006 U
:= U
* BB
+ XDR_U
(S
(N
));
1009 return Unsigned
(U
);
1017 function I_WC
(Stream
: access RST
) return Wide_Character is
1023 Ada
.Streams
.Read
(Stream
.all, S
, L
);
1028 for N
in S
'Range loop
1029 U
:= U
* BB
+ XDR_WC
(S
(N
));
1032 -- Use Ada requirements on Wide_Character representation clause
1034 return Wide_Character'Val (U
);
1042 procedure W_AD
(Stream
: access RST
; Item
: in Fat_Pointer
) is
1047 U
:= XDR_TM
(To_XDR_SA
(Item
.P1
));
1048 for N
in reverse S
'Range loop
1049 S
(N
) := SE
(U
mod BB
);
1053 Ada
.Streams
.Write
(Stream
.all, S
);
1055 U
:= XDR_TM
(To_XDR_SA
(Item
.P2
));
1056 for N
in reverse S
'Range loop
1057 S
(N
) := SE
(U
mod BB
);
1061 Ada
.Streams
.Write
(Stream
.all, S
);
1072 procedure W_AS
(Stream
: access RST
; Item
: in Thin_Pointer
) is
1074 U
: XDR_TM
:= XDR_TM
(To_XDR_SA
(Item
.P1
));
1077 for N
in reverse S
'Range loop
1078 S
(N
) := SE
(U
mod BB
);
1082 Ada
.Streams
.Write
(Stream
.all, S
);
1093 procedure W_B
(Stream
: access RST
; Item
: in Boolean) is
1106 procedure W_C
(Stream
: access RST
; Item
: in Character) is
1109 pragma Assert
(C_L
= 1);
1113 -- Use Ada requirements on Character representation clause
1115 S
(1) := SE
(Character'Pos (Item
));
1117 Ada
.Streams
.Write
(Stream
.all, S
);
1124 procedure W_F
(Stream
: access RST
; Item
: in Float) is
1125 I
: constant Precision
:= Single
;
1126 E_Size
: Integer renames Fields
(I
).E_Size
;
1127 E_Bias
: Integer renames Fields
(I
).E_Bias
;
1128 E_Bytes
: SEO
renames Fields
(I
).E_Bytes
;
1129 F_Bytes
: SEO
renames Fields
(I
).F_Bytes
;
1130 F_Size
: Integer renames Fields
(I
).F_Size
;
1131 F_Mask
: SE
renames Fields
(I
).F_Mask
;
1133 Exponent
: Long_Unsigned
;
1134 Fraction
: Long_Unsigned
;
1138 S
: SEA
(1 .. F_L
) := (others => 0);
1141 if not Item
'Valid then
1142 raise Constraint_Error
;
1147 Positive := (0.0 <= Item
);
1157 E
:= Float'Exponent (F
) - 1;
1159 -- Denormalized float
1161 if E
<= -E_Bias
then
1162 F
:= Float'Scaling (F
, F_Size
+ E_Bias
- 1);
1165 F
:= Float'Scaling (Float'Fraction (F
), F_Size
+ 1);
1168 -- Compute Exponent and Fraction
1170 Exponent
:= Long_Unsigned
(E
+ E_Bias
);
1171 Fraction
:= Long_Unsigned
(F
* 2.0) / 2;
1176 for I
in reverse F_L
- F_Bytes
+ 1 .. F_L
loop
1177 S
(I
) := SE
(Fraction
mod BB
);
1178 Fraction
:= Fraction
/ BB
;
1181 -- Remove implicit bit
1183 S
(F_L
- F_Bytes
+ 1) := S
(F_L
- F_Bytes
+ 1) and F_Mask
;
1185 -- Store Exponent (not always at the beginning of a byte)
1187 Exponent
:= Shift_Left
(Exponent
, Integer (E_Bytes
) * SU
- E_Size
- 1);
1188 for N
in reverse 1 .. E_Bytes
loop
1189 S
(N
) := SE
(Exponent
mod BB
) + S
(N
);
1190 Exponent
:= Exponent
/ BB
;
1195 if not Positive then
1196 S
(1) := S
(1) + BS
;
1199 Ada
.Streams
.Write
(Stream
.all, S
);
1206 procedure W_I
(Stream
: access RST
; Item
: in Integer) is
1211 if Optimize_Integers
then
1212 S
:= Integer_To_XDR_S_I
(Item
);
1215 -- Test sign and apply two complement notation
1218 U
:= XDR_U
'Last xor XDR_U
(-(Item
+ 1));
1223 for N
in reverse S
'Range loop
1224 S
(N
) := SE
(U
mod BB
);
1233 Ada
.Streams
.Write
(Stream
.all, S
);
1240 procedure W_LF
(Stream
: access RST
; Item
: in Long_Float) is
1241 I
: constant Precision
:= Double
;
1242 E_Size
: Integer renames Fields
(I
).E_Size
;
1243 E_Bias
: Integer renames Fields
(I
).E_Bias
;
1244 E_Bytes
: SEO
renames Fields
(I
).E_Bytes
;
1245 F_Bytes
: SEO
renames Fields
(I
).F_Bytes
;
1246 F_Size
: Integer renames Fields
(I
).F_Size
;
1247 F_Mask
: SE
renames Fields
(I
).F_Mask
;
1249 Exponent
: Long_Unsigned
;
1250 Fraction
: Long_Long_Unsigned
;
1254 S
: SEA
(1 .. LF_L
) := (others => 0);
1257 if not Item
'Valid then
1258 raise Constraint_Error
;
1263 Positive := (0.0 <= Item
);
1273 E
:= Long_Float'Exponent (F
) - 1;
1275 -- Denormalized float
1277 if E
<= -E_Bias
then
1279 F
:= Long_Float'Scaling (F
, F_Size
+ E_Bias
- 1);
1281 F
:= Long_Float'Scaling (F
, F_Size
- E
);
1284 -- Compute Exponent and Fraction
1286 Exponent
:= Long_Unsigned
(E
+ E_Bias
);
1287 Fraction
:= Long_Long_Unsigned
(F
* 2.0) / 2;
1292 for I
in reverse LF_L
- F_Bytes
+ 1 .. LF_L
loop
1293 S
(I
) := SE
(Fraction
mod BB
);
1294 Fraction
:= Fraction
/ BB
;
1297 -- Remove implicit bit
1299 S
(LF_L
- F_Bytes
+ 1) := S
(LF_L
- F_Bytes
+ 1) and F_Mask
;
1301 -- Store Exponent (not always at the beginning of a byte)
1303 Exponent
:= Shift_Left
(Exponent
, Integer (E_Bytes
) * SU
- E_Size
- 1);
1304 for N
in reverse 1 .. E_Bytes
loop
1305 S
(N
) := SE
(Exponent
mod BB
) + S
(N
);
1306 Exponent
:= Exponent
/ BB
;
1311 if not Positive then
1312 S
(1) := S
(1) + BS
;
1315 Ada
.Streams
.Write
(Stream
.all, S
);
1322 procedure W_LI
(Stream
: access RST
; Item
: in Long_Integer) is
1328 if Optimize_Integers
then
1329 S
:= Long_Long_Integer_To_XDR_S_LI
(Long_Long_Integer (Item
));
1332 -- Test sign and apply two complement notation
1335 X
:= Long_Unsigned
'Last xor Long_Unsigned
(-(Item
+ 1));
1337 X
:= Long_Unsigned
(Item
);
1340 -- Compute using machine unsigned
1341 -- rather than long_unsigned.
1343 for N
in reverse S
'Range loop
1345 -- We have filled an unsigned
1347 if (LU_L
- N
) mod UB
= 0 then
1348 U
:= Unsigned
(X
and UL
);
1349 X
:= Shift_Right
(X
, US
);
1352 S
(N
) := SE
(U
mod BB
);
1361 Ada
.Streams
.Write
(Stream
.all, S
);
1368 procedure W_LLF
(Stream
: access RST
; Item
: in Long_Long_Float) is
1369 I
: constant Precision
:= Quadruple
;
1370 E_Size
: Integer renames Fields
(I
).E_Size
;
1371 E_Bias
: Integer renames Fields
(I
).E_Bias
;
1372 E_Bytes
: SEO
renames Fields
(I
).E_Bytes
;
1373 F_Bytes
: SEO
renames Fields
(I
).F_Bytes
;
1374 F_Size
: Integer renames Fields
(I
).F_Size
;
1376 HFS
: constant Integer := F_Size
/ 2;
1378 Exponent
: Long_Unsigned
;
1379 Fraction_1
: Long_Long_Unsigned
;
1380 Fraction_2
: Long_Long_Unsigned
;
1383 F
: Long_Long_Float := Item
;
1384 S
: SEA
(1 .. LLF_L
) := (others => 0);
1387 if not Item
'Valid then
1388 raise Constraint_Error
;
1393 Positive := (0.0 <= Item
);
1406 E
:= Long_Long_Float'Exponent (F
) - 1;
1408 -- Denormalized float
1410 if E
<= -E_Bias
then
1411 F
:= Long_Long_Float'Scaling (F
, E_Bias
- 1);
1414 F
:= Long_Long_Float'Scaling
1415 (Long_Long_Float'Fraction (F
), 1);
1418 -- Compute Exponent and Fraction
1420 Exponent
:= Long_Unsigned
(E
+ E_Bias
);
1421 F
:= Long_Long_Float'Scaling (F
, F_Size
- HFS
);
1422 Fraction_1
:= Long_Long_Unsigned
(Long_Long_Float'Floor (F
));
1423 F
:= Long_Long_Float (F
- Long_Long_Float (Fraction_1
));
1424 F
:= Long_Long_Float'Scaling (F
, HFS
);
1425 Fraction_2
:= Long_Long_Unsigned
(Long_Long_Float'Floor (F
));
1430 for I
in reverse LLF_L
- F_Bytes
+ 1 .. LLF_L
- 7 loop
1431 S
(I
) := SE
(Fraction_1
mod BB
);
1432 Fraction_1
:= Fraction_1
/ BB
;
1437 for I
in reverse LLF_L
- 6 .. LLF_L
loop
1438 S
(SEO
(I
)) := SE
(Fraction_2
mod BB
);
1439 Fraction_2
:= Fraction_2
/ BB
;
1442 -- Store Exponent (not always at the beginning of a byte)
1444 Exponent
:= Shift_Left
(Exponent
, Integer (E_Bytes
) * SU
- E_Size
- 1);
1445 for N
in reverse 1 .. E_Bytes
loop
1446 S
(N
) := SE
(Exponent
mod BB
) + S
(N
);
1447 Exponent
:= Exponent
/ BB
;
1452 if not Positive then
1453 S
(1) := S
(1) + BS
;
1456 Ada
.Streams
.Write
(Stream
.all, S
);
1463 procedure W_LLI
(Stream
: access RST
; Item
: in Long_Long_Integer) is
1466 X
: Long_Long_Unsigned
;
1469 if Optimize_Integers
then
1470 S
:= Long_Long_Integer_To_XDR_S_LLI
(Item
);
1473 -- Test sign and apply two complement notation
1476 X
:= Long_Long_Unsigned
'Last xor Long_Long_Unsigned
(-(Item
+ 1));
1478 X
:= Long_Long_Unsigned
(Item
);
1481 -- Compute using machine unsigned
1482 -- rather than long_long_unsigned.
1484 for N
in reverse S
'Range loop
1486 -- We have filled an unsigned
1488 if (LLU_L
- N
) mod UB
= 0 then
1489 U
:= Unsigned
(X
and UL
);
1490 X
:= Shift_Right
(X
, US
);
1493 S
(N
) := SE
(U
mod BB
);
1502 Ada
.Streams
.Write
(Stream
.all, S
);
1509 procedure W_LLU
(Stream
: access RST
; Item
: in Long_Long_Unsigned
) is
1512 X
: Long_Long_Unsigned
:= Item
;
1515 if Optimize_Integers
then
1516 S
:= Long_Long_Unsigned_To_XDR_S_LLU
(Item
);
1518 -- Compute using machine unsigned
1519 -- rather than long_long_unsigned.
1521 for N
in reverse S
'Range loop
1523 -- We have filled an unsigned
1525 if (LLU_L
- N
) mod UB
= 0 then
1526 U
:= Unsigned
(X
and UL
);
1527 X
:= Shift_Right
(X
, US
);
1530 S
(N
) := SE
(U
mod BB
);
1539 Ada
.Streams
.Write
(Stream
.all, S
);
1546 procedure W_LU
(Stream
: access RST
; Item
: in Long_Unsigned
) is
1549 X
: Long_Unsigned
:= Item
;
1552 if Optimize_Integers
then
1553 S
:= Long_Long_Unsigned_To_XDR_S_LU
(Long_Long_Unsigned
(Item
));
1555 -- Compute using machine unsigned
1556 -- rather than long_unsigned.
1558 for N
in reverse S
'Range loop
1560 -- We have filled an unsigned
1562 if (LU_L
- N
) mod UB
= 0 then
1563 U
:= Unsigned
(X
and UL
);
1564 X
:= Shift_Right
(X
, US
);
1566 S
(N
) := SE
(U
mod BB
);
1575 Ada
.Streams
.Write
(Stream
.all, S
);
1582 procedure W_SF
(Stream
: access RST
; Item
: in Short_Float) is
1583 I
: constant Precision
:= Single
;
1584 E_Size
: Integer renames Fields
(I
).E_Size
;
1585 E_Bias
: Integer renames Fields
(I
).E_Bias
;
1586 E_Bytes
: SEO
renames Fields
(I
).E_Bytes
;
1587 F_Bytes
: SEO
renames Fields
(I
).F_Bytes
;
1588 F_Size
: Integer renames Fields
(I
).F_Size
;
1589 F_Mask
: SE
renames Fields
(I
).F_Mask
;
1591 Exponent
: Long_Unsigned
;
1592 Fraction
: Long_Unsigned
;
1596 S
: SEA
(1 .. SF_L
) := (others => 0);
1599 if not Item
'Valid then
1600 raise Constraint_Error
;
1605 Positive := (0.0 <= Item
);
1615 E
:= Short_Float'Exponent (F
) - 1;
1617 -- Denormalized float
1619 if E
<= -E_Bias
then
1621 F
:= Short_Float'Scaling (F
, F_Size
+ E_Bias
- 1);
1623 F
:= Short_Float'Scaling (F
, F_Size
- E
);
1626 -- Compute Exponent and Fraction
1628 Exponent
:= Long_Unsigned
(E
+ E_Bias
);
1629 Fraction
:= Long_Unsigned
(F
* 2.0) / 2;
1634 for I
in reverse SF_L
- F_Bytes
+ 1 .. SF_L
loop
1635 S
(I
) := SE
(Fraction
mod BB
);
1636 Fraction
:= Fraction
/ BB
;
1639 -- Remove implicit bit
1641 S
(SF_L
- F_Bytes
+ 1) := S
(SF_L
- F_Bytes
+ 1) and F_Mask
;
1643 -- Store Exponent (not always at the beginning of a byte)
1645 Exponent
:= Shift_Left
(Exponent
, Integer (E_Bytes
) * SU
- E_Size
- 1);
1646 for N
in reverse 1 .. E_Bytes
loop
1647 S
(N
) := SE
(Exponent
mod BB
) + S
(N
);
1648 Exponent
:= Exponent
/ BB
;
1653 if not Positive then
1654 S
(1) := S
(1) + BS
;
1657 Ada
.Streams
.Write
(Stream
.all, S
);
1664 procedure W_SI
(Stream
: access RST
; Item
: in Short_Integer) is
1669 if Optimize_Integers
then
1670 S
:= Short_Integer_To_XDR_S_SI
(Item
);
1673 -- Test sign and apply two complement's notation
1676 U
:= XDR_SU
'Last xor XDR_SU
(-(Item
+ 1));
1681 for N
in reverse S
'Range loop
1682 S
(N
) := SE
(U
mod BB
);
1691 Ada
.Streams
.Write
(Stream
.all, S
);
1698 procedure W_SSI
(Stream
: access RST
; Item
: in Short_Short_Integer) is
1703 if Optimize_Integers
then
1704 S
:= Short_Short_Integer_To_XDR_S_SSI
(Item
);
1707 -- Test sign and apply two complement's notation
1710 U
:= XDR_SSU
'Last xor XDR_SSU
(-(Item
+ 1));
1712 U
:= XDR_SSU
(Item
);
1718 Ada
.Streams
.Write
(Stream
.all, S
);
1725 procedure W_SSU
(Stream
: access RST
; Item
: in Short_Short_Unsigned
) is
1727 U
: XDR_SSU
:= XDR_SSU
(Item
);
1732 Ada
.Streams
.Write
(Stream
.all, S
);
1739 procedure W_SU
(Stream
: access RST
; Item
: in Short_Unsigned
) is
1741 U
: XDR_SU
:= XDR_SU
(Item
);
1744 if Optimize_Integers
then
1745 S
:= Short_Unsigned_To_XDR_S_SU
(Item
);
1747 for N
in reverse S
'Range loop
1748 S
(N
) := SE
(U
mod BB
);
1757 Ada
.Streams
.Write
(Stream
.all, S
);
1764 procedure W_U
(Stream
: access RST
; Item
: in Unsigned
) is
1766 U
: XDR_U
:= XDR_U
(Item
);
1769 if Optimize_Integers
then
1770 S
:= Unsigned_To_XDR_S_U
(Item
);
1772 for N
in reverse S
'Range loop
1773 S
(N
) := SE
(U
mod BB
);
1782 Ada
.Streams
.Write
(Stream
.all, S
);
1789 procedure W_WC
(Stream
: access RST
; Item
: in Wide_Character) is
1795 -- Use Ada requirements on Wide_Character representation clause
1797 U
:= XDR_WC
(Wide_Character'Pos (Item
));
1799 for N
in reverse S
'Range loop
1800 S
(N
) := SE
(U
mod BB
);
1804 Ada
.Streams
.Write
(Stream
.all, S
);
1811 end System
.Stream_Attributes
;