1 ------------------------------------------------------------------------------
3 -- GNAT RUN-TIME 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-2013, 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 3, or (at your option) any later ver- --
14 -- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
15 -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
16 -- or FITNESS FOR A PARTICULAR PURPOSE. --
18 -- As a special exception under Section 7 of GPL version 3, you are granted --
19 -- additional permissions described in the GCC Runtime Library Exception, --
20 -- version 3.1, as published by the Free Software Foundation. --
22 -- You should have received a copy of the GNU General Public License and --
23 -- a copy of the GCC Runtime Library Exception along with this program; --
24 -- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --
25 -- <http://www.gnu.org/licenses/>. --
27 -- GNAT was originally developed by the GNAT team at New York University. --
28 -- Extensive contributions were provided by Ada Core Technologies Inc. --
30 ------------------------------------------------------------------------------
32 -- This file is an alternate version of s-stratt.adb based on the XDR
33 -- standard. It is especially useful for exchanging streams between two
34 -- different systems with different basic type representations and endianness.
36 with Ada
.IO_Exceptions
;
37 with Ada
.Streams
; use Ada
.Streams
;
38 with Ada
.Unchecked_Conversion
;
40 package body System
.Stream_Attributes
is
42 pragma Suppress
(Range_Check
);
43 pragma Suppress
(Overflow_Check
);
47 Data_Error
: exception renames Ada
.IO_Exceptions
.End_Error
;
48 -- Exception raised if insufficient data read (End_Error is mandated by
51 SU
: constant := System
.Storage_Unit
;
52 -- The code in this body assumes that 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 completely used
76 F_Bytes
: SEO
; -- N. of fraction bytes completely 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 used for the double-precision
224 -- floating-point data type "double" (64 bits or 8 bytes). The encoding
225 -- used is the IEEE standard for normalized double-precision floating-point
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 -- Consider Wide_Wide_Character as an enumeration type
270 WWC_L
: constant := 8;
271 subtype XDR_S_WWC
is SEA
(1 .. WWC_L
);
272 type XDR_WWC
is mod BB
** WWC_L
;
274 -- Optimization: if we already have the correct Bit_Order, then some
275 -- computations can be avoided since the source and the target will be
276 -- identical anyway. They will be replaced by direct unchecked
279 Optimize_Integers
: constant Boolean :=
280 Default_Bit_Order
= High_Order_First
;
286 -- We must inhibit Block_IO, because in XDR mode, each element is output
287 -- according to XDR requirements, which is not at all the same as writing
288 -- the whole array in one block.
290 function Block_IO_OK
return Boolean is
299 function I_AD
(Stream
: not null access RST
) return Fat_Pointer
is
303 FP
.P1
:= I_AS
(Stream
).P1
;
304 FP
.P2
:= I_AS
(Stream
).P1
;
313 function I_AS
(Stream
: not null access RST
) return Thin_Pointer
is
319 Ada
.Streams
.Read
(Stream
.all, S
, L
);
325 for N
in S
'Range loop
326 U
:= U
* BB
+ XDR_TM
(S
(N
));
329 return (P1
=> To_XDR_SA
(XDR_SA
(U
)));
337 function I_B
(Stream
: not null access RST
) return Boolean is
339 case I_SSU
(Stream
) is
340 when 0 => return False;
341 when 1 => return True;
342 when others => raise Data_Error
;
350 function I_C
(Stream
: not null access RST
) return Character is
355 Ada
.Streams
.Read
(Stream
.all, S
, L
);
361 -- Use Ada requirements on Character representation clause
363 return Character'Val (S
(1));
371 function I_F
(Stream
: not null access RST
) return Float is
372 I
: constant Precision
:= Single
;
373 E_Size
: Integer renames Fields
(I
).E_Size
;
374 E_Bias
: Integer renames Fields
(I
).E_Bias
;
375 E_Last
: Integer renames Fields
(I
).E_Last
;
376 F_Mask
: SE
renames Fields
(I
).F_Mask
;
377 E_Bytes
: SEO
renames Fields
(I
).E_Bytes
;
378 F_Bytes
: SEO
renames Fields
(I
).F_Bytes
;
379 F_Size
: Integer renames Fields
(I
).F_Size
;
381 Is_Positive
: Boolean;
382 Exponent
: Long_Unsigned
;
383 Fraction
: Long_Unsigned
;
389 Ada
.Streams
.Read
(Stream
.all, S
, L
);
395 -- Extract Fraction, Sign and Exponent
397 Fraction
:= Long_Unsigned
(S
(F_L
+ 1 - F_Bytes
) and F_Mask
);
398 for N
in F_L
+ 2 - F_Bytes
.. F_L
loop
399 Fraction
:= Fraction
* BB
+ Long_Unsigned
(S
(N
));
401 Result
:= Float'Scaling (Float (Fraction
), -F_Size
);
404 Is_Positive
:= False;
405 Exponent
:= Long_Unsigned
(S
(1) - BS
);
408 Exponent
:= Long_Unsigned
(S
(1));
411 for N
in 2 .. E_Bytes
loop
412 Exponent
:= Exponent
* BB
+ Long_Unsigned
(S
(N
));
414 Exponent
:= Shift_Right
(Exponent
, Integer (E_Bytes
) * SU
- E_Size
- 1);
418 if Integer (Exponent
) = E_Last
then
419 raise Constraint_Error
;
421 elsif Exponent
= 0 then
428 -- Denormalized float
431 Result
:= Float'Scaling (Result
, 1 - E_Bias
);
437 Result
:= Float'Scaling
438 (1.0 + Result
, Integer (Exponent
) - E_Bias
);
441 if not Is_Positive
then
452 function I_I
(Stream
: not null access RST
) return Integer is
458 Ada
.Streams
.Read
(Stream
.all, S
, L
);
463 elsif Optimize_Integers
then
464 return XDR_S_I_To_Integer
(S
);
467 for N
in S
'Range loop
468 U
:= U
* BB
+ XDR_U
(S
(N
));
471 -- Test sign and apply two complement notation
477 return Integer (-((XDR_U
'Last xor U
) + 1));
486 function I_LF
(Stream
: not null access RST
) return Long_Float is
487 I
: constant Precision
:= Double
;
488 E_Size
: Integer renames Fields
(I
).E_Size
;
489 E_Bias
: Integer renames Fields
(I
).E_Bias
;
490 E_Last
: Integer renames Fields
(I
).E_Last
;
491 F_Mask
: SE
renames Fields
(I
).F_Mask
;
492 E_Bytes
: SEO
renames Fields
(I
).E_Bytes
;
493 F_Bytes
: SEO
renames Fields
(I
).F_Bytes
;
494 F_Size
: Integer renames Fields
(I
).F_Size
;
496 Is_Positive
: Boolean;
497 Exponent
: Long_Unsigned
;
498 Fraction
: Long_Long_Unsigned
;
504 Ada
.Streams
.Read
(Stream
.all, S
, L
);
510 -- Extract Fraction, Sign and Exponent
512 Fraction
:= Long_Long_Unsigned
(S
(LF_L
+ 1 - F_Bytes
) and F_Mask
);
513 for N
in LF_L
+ 2 - F_Bytes
.. LF_L
loop
514 Fraction
:= Fraction
* BB
+ Long_Long_Unsigned
(S
(N
));
517 Result
:= Long_Float'Scaling (Long_Float (Fraction
), -F_Size
);
520 Is_Positive
:= False;
521 Exponent
:= Long_Unsigned
(S
(1) - BS
);
524 Exponent
:= Long_Unsigned
(S
(1));
527 for N
in 2 .. E_Bytes
loop
528 Exponent
:= Exponent
* BB
+ Long_Unsigned
(S
(N
));
531 Exponent
:= Shift_Right
(Exponent
, Integer (E_Bytes
) * SU
- E_Size
- 1);
535 if Integer (Exponent
) = E_Last
then
536 raise Constraint_Error
;
538 elsif Exponent
= 0 then
545 -- Denormalized float
548 Result
:= Long_Float'Scaling (Result
, 1 - E_Bias
);
554 Result
:= Long_Float'Scaling
555 (1.0 + Result
, Integer (Exponent
) - E_Bias
);
558 if not Is_Positive
then
569 function I_LI
(Stream
: not null access RST
) return Long_Integer is
573 X
: Long_Unsigned
:= 0;
576 Ada
.Streams
.Read
(Stream
.all, S
, L
);
581 elsif Optimize_Integers
then
582 return Long_Integer (XDR_S_LI_To_Long_Long_Integer
(S
));
586 -- Compute using machine unsigned
587 -- rather than long_long_unsigned
589 for N
in S
'Range loop
590 U
:= U
* BB
+ Unsigned
(S
(N
));
592 -- We have filled an unsigned
595 X
:= Shift_Left
(X
, US
) + Long_Unsigned
(U
);
600 -- Test sign and apply two complement notation
603 return Long_Integer (X
);
605 return Long_Integer (-((Long_Unsigned
'Last xor X
) + 1));
615 function I_LLF
(Stream
: not null access RST
) return Long_Long_Float is
616 I
: constant Precision
:= Quadruple
;
617 E_Size
: Integer renames Fields
(I
).E_Size
;
618 E_Bias
: Integer renames Fields
(I
).E_Bias
;
619 E_Last
: Integer renames Fields
(I
).E_Last
;
620 E_Bytes
: SEO
renames Fields
(I
).E_Bytes
;
621 F_Bytes
: SEO
renames Fields
(I
).F_Bytes
;
622 F_Size
: Integer renames Fields
(I
).F_Size
;
624 Is_Positive
: Boolean;
625 Exponent
: Long_Unsigned
;
626 Fraction_1
: Long_Long_Unsigned
:= 0;
627 Fraction_2
: Long_Long_Unsigned
:= 0;
628 Result
: Long_Long_Float;
629 HF
: constant Natural := F_Size
/ 2;
630 S
: SEA
(1 .. LLF_L
);
634 Ada
.Streams
.Read
(Stream
.all, S
, L
);
640 -- Extract Fraction, Sign and Exponent
642 for I
in LLF_L
- F_Bytes
+ 1 .. LLF_L
- 7 loop
643 Fraction_1
:= Fraction_1
* BB
+ Long_Long_Unsigned
(S
(I
));
646 for I
in SEO
(LLF_L
- 6) .. SEO
(LLF_L
) loop
647 Fraction_2
:= Fraction_2
* BB
+ Long_Long_Unsigned
(S
(I
));
650 Result
:= Long_Long_Float'Scaling (Long_Long_Float (Fraction_2
), -HF
);
651 Result
:= Long_Long_Float (Fraction_1
) + Result
;
652 Result
:= Long_Long_Float'Scaling (Result
, HF
- F_Size
);
655 Is_Positive
:= False;
656 Exponent
:= Long_Unsigned
(S
(1) - BS
);
659 Exponent
:= Long_Unsigned
(S
(1));
662 for N
in 2 .. E_Bytes
loop
663 Exponent
:= Exponent
* BB
+ Long_Unsigned
(S
(N
));
666 Exponent
:= Shift_Right
(Exponent
, Integer (E_Bytes
) * SU
- E_Size
- 1);
670 if Integer (Exponent
) = E_Last
then
671 raise Constraint_Error
;
673 elsif Exponent
= 0 then
677 if Fraction_1
= 0 and then Fraction_2
= 0 then
680 -- Denormalized float
683 Result
:= Long_Long_Float'Scaling (Result
, 1 - E_Bias
);
689 Result
:= Long_Long_Float'Scaling
690 (1.0 + Result
, Integer (Exponent
) - E_Bias
);
693 if not Is_Positive
then
704 function I_LLI
(Stream
: not null access RST
) return Long_Long_Integer is
708 X
: Long_Long_Unsigned
:= 0;
711 Ada
.Streams
.Read
(Stream
.all, S
, L
);
716 elsif Optimize_Integers
then
717 return XDR_S_LLI_To_Long_Long_Integer
(S
);
720 -- Compute using machine unsigned for computing
721 -- rather than long_long_unsigned.
723 for N
in S
'Range loop
724 U
:= U
* BB
+ Unsigned
(S
(N
));
726 -- We have filled an unsigned
729 X
:= Shift_Left
(X
, US
) + Long_Long_Unsigned
(U
);
734 -- Test sign and apply two complement notation
737 return Long_Long_Integer (X
);
739 return Long_Long_Integer (-((Long_Long_Unsigned
'Last xor X
) + 1));
748 function I_LLU
(Stream
: not null access RST
) return Long_Long_Unsigned
is
752 X
: Long_Long_Unsigned
:= 0;
755 Ada
.Streams
.Read
(Stream
.all, S
, L
);
760 elsif Optimize_Integers
then
761 return XDR_S_LLU_To_Long_Long_Unsigned
(S
);
764 -- Compute using machine unsigned
765 -- rather than long_long_unsigned.
767 for N
in S
'Range loop
768 U
:= U
* BB
+ Unsigned
(S
(N
));
770 -- We have filled an unsigned
773 X
:= Shift_Left
(X
, US
) + Long_Long_Unsigned
(U
);
786 function I_LU
(Stream
: not null access RST
) return Long_Unsigned
is
790 X
: Long_Unsigned
:= 0;
793 Ada
.Streams
.Read
(Stream
.all, S
, L
);
798 elsif Optimize_Integers
then
799 return Long_Unsigned
(XDR_S_LU_To_Long_Long_Unsigned
(S
));
802 -- Compute using machine unsigned
803 -- rather than long_unsigned.
805 for N
in S
'Range loop
806 U
:= U
* BB
+ Unsigned
(S
(N
));
808 -- We have filled an unsigned
811 X
:= Shift_Left
(X
, US
) + Long_Unsigned
(U
);
824 function I_SF
(Stream
: not null access RST
) return Short_Float is
825 I
: constant Precision
:= Single
;
826 E_Size
: Integer renames Fields
(I
).E_Size
;
827 E_Bias
: Integer renames Fields
(I
).E_Bias
;
828 E_Last
: Integer renames Fields
(I
).E_Last
;
829 F_Mask
: SE
renames Fields
(I
).F_Mask
;
830 E_Bytes
: SEO
renames Fields
(I
).E_Bytes
;
831 F_Bytes
: SEO
renames Fields
(I
).F_Bytes
;
832 F_Size
: Integer renames Fields
(I
).F_Size
;
834 Exponent
: Long_Unsigned
;
835 Fraction
: Long_Unsigned
;
836 Is_Positive
: Boolean;
837 Result
: Short_Float;
842 Ada
.Streams
.Read
(Stream
.all, S
, L
);
848 -- Extract Fraction, Sign and Exponent
850 Fraction
:= Long_Unsigned
(S
(SF_L
+ 1 - F_Bytes
) and F_Mask
);
851 for N
in SF_L
+ 2 - F_Bytes
.. SF_L
loop
852 Fraction
:= Fraction
* BB
+ Long_Unsigned
(S
(N
));
854 Result
:= Short_Float'Scaling (Short_Float (Fraction
), -F_Size
);
857 Is_Positive
:= False;
858 Exponent
:= Long_Unsigned
(S
(1) - BS
);
861 Exponent
:= Long_Unsigned
(S
(1));
864 for N
in 2 .. E_Bytes
loop
865 Exponent
:= Exponent
* BB
+ Long_Unsigned
(S
(N
));
867 Exponent
:= Shift_Right
(Exponent
, Integer (E_Bytes
) * SU
- E_Size
- 1);
871 if Integer (Exponent
) = E_Last
then
872 raise Constraint_Error
;
874 elsif Exponent
= 0 then
881 -- Denormalized float
884 Result
:= Short_Float'Scaling (Result
, 1 - E_Bias
);
890 Result
:= Short_Float'Scaling
891 (1.0 + Result
, Integer (Exponent
) - E_Bias
);
894 if not Is_Positive
then
905 function I_SI
(Stream
: not null access RST
) return Short_Integer is
911 Ada
.Streams
.Read
(Stream
.all, S
, L
);
916 elsif Optimize_Integers
then
917 return XDR_S_SI_To_Short_Integer
(S
);
920 for N
in S
'Range loop
921 U
:= U
* BB
+ XDR_SU
(S
(N
));
924 -- Test sign and apply two complement notation
927 return Short_Integer (U
);
929 return Short_Integer (-((XDR_SU
'Last xor U
) + 1));
938 function I_SSI
(Stream
: not null access RST
) return Short_Short_Integer is
944 Ada
.Streams
.Read
(Stream
.all, S
, L
);
949 elsif Optimize_Integers
then
950 return XDR_S_SSI_To_Short_Short_Integer
(S
);
953 U
:= XDR_SSU
(S
(1));
955 -- Test sign and apply two complement notation
958 return Short_Short_Integer (U
);
960 return Short_Short_Integer (-((XDR_SSU
'Last xor U
) + 1));
969 function I_SSU
(Stream
: not null access RST
) return Short_Short_Unsigned
is
975 Ada
.Streams
.Read
(Stream
.all, S
, L
);
981 U
:= XDR_SSU
(S
(1));
982 return Short_Short_Unsigned
(U
);
990 function I_SU
(Stream
: not null access RST
) return Short_Unsigned
is
996 Ada
.Streams
.Read
(Stream
.all, S
, L
);
1001 elsif Optimize_Integers
then
1002 return XDR_S_SU_To_Short_Unsigned
(S
);
1005 for N
in S
'Range loop
1006 U
:= U
* BB
+ XDR_SU
(S
(N
));
1009 return Short_Unsigned
(U
);
1017 function I_U
(Stream
: not null access RST
) return Unsigned
is
1023 Ada
.Streams
.Read
(Stream
.all, S
, L
);
1028 elsif Optimize_Integers
then
1029 return XDR_S_U_To_Unsigned
(S
);
1032 for N
in S
'Range loop
1033 U
:= U
* BB
+ XDR_U
(S
(N
));
1036 return Unsigned
(U
);
1044 function I_WC
(Stream
: not null access RST
) return Wide_Character is
1050 Ada
.Streams
.Read
(Stream
.all, S
, L
);
1056 for N
in S
'Range loop
1057 U
:= U
* BB
+ XDR_WC
(S
(N
));
1060 -- Use Ada requirements on Wide_Character representation clause
1062 return Wide_Character'Val (U
);
1070 function I_WWC
(Stream
: not null access RST
) return Wide_Wide_Character
is
1076 Ada
.Streams
.Read
(Stream
.all, S
, L
);
1082 for N
in S
'Range loop
1083 U
:= U
* BB
+ XDR_WWC
(S
(N
));
1086 -- Use Ada requirements on Wide_Wide_Character representation clause
1088 return Wide_Wide_Character
'Val (U
);
1096 procedure W_AD
(Stream
: not null access RST
; Item
: Fat_Pointer
) is
1101 U
:= XDR_TM
(To_XDR_SA
(Item
.P1
));
1102 for N
in reverse S
'Range loop
1103 S
(N
) := SE
(U
mod BB
);
1107 Ada
.Streams
.Write
(Stream
.all, S
);
1109 U
:= XDR_TM
(To_XDR_SA
(Item
.P2
));
1110 for N
in reverse S
'Range loop
1111 S
(N
) := SE
(U
mod BB
);
1115 Ada
.Streams
.Write
(Stream
.all, S
);
1126 procedure W_AS
(Stream
: not null access RST
; Item
: Thin_Pointer
) is
1128 U
: XDR_TM
:= XDR_TM
(To_XDR_SA
(Item
.P1
));
1131 for N
in reverse S
'Range loop
1132 S
(N
) := SE
(U
mod BB
);
1136 Ada
.Streams
.Write
(Stream
.all, S
);
1147 procedure W_B
(Stream
: not null access RST
; Item
: Boolean) is
1160 procedure W_C
(Stream
: not null access RST
; Item
: Character) is
1163 pragma Assert
(C_L
= 1);
1166 -- Use Ada requirements on Character representation clause
1168 S
(1) := SE
(Character'Pos (Item
));
1170 Ada
.Streams
.Write
(Stream
.all, S
);
1177 procedure W_F
(Stream
: not null access RST
; Item
: Float) is
1178 I
: constant Precision
:= Single
;
1179 E_Size
: Integer renames Fields
(I
).E_Size
;
1180 E_Bias
: Integer renames Fields
(I
).E_Bias
;
1181 E_Bytes
: SEO
renames Fields
(I
).E_Bytes
;
1182 F_Bytes
: SEO
renames Fields
(I
).F_Bytes
;
1183 F_Size
: Integer renames Fields
(I
).F_Size
;
1184 F_Mask
: SE
renames Fields
(I
).F_Mask
;
1186 Exponent
: Long_Unsigned
;
1187 Fraction
: Long_Unsigned
;
1188 Is_Positive
: Boolean;
1191 S
: SEA
(1 .. F_L
) := (others => 0);
1194 if not Item
'Valid then
1195 raise Constraint_Error
;
1200 Is_Positive
:= (0.0 <= Item
);
1210 E
:= Float'Exponent (F
) - 1;
1212 -- Denormalized float
1214 if E
<= -E_Bias
then
1215 F
:= Float'Scaling (F
, F_Size
+ E_Bias
- 1);
1218 F
:= Float'Scaling (Float'Fraction (F
), F_Size
+ 1);
1221 -- Compute Exponent and Fraction
1223 Exponent
:= Long_Unsigned
(E
+ E_Bias
);
1224 Fraction
:= Long_Unsigned
(F
* 2.0) / 2;
1229 for I
in reverse F_L
- F_Bytes
+ 1 .. F_L
loop
1230 S
(I
) := SE
(Fraction
mod BB
);
1231 Fraction
:= Fraction
/ BB
;
1234 -- Remove implicit bit
1236 S
(F_L
- F_Bytes
+ 1) := S
(F_L
- F_Bytes
+ 1) and F_Mask
;
1238 -- Store Exponent (not always at the beginning of a byte)
1240 Exponent
:= Shift_Left
(Exponent
, Integer (E_Bytes
) * SU
- E_Size
- 1);
1241 for N
in reverse 1 .. E_Bytes
loop
1242 S
(N
) := SE
(Exponent
mod BB
) + S
(N
);
1243 Exponent
:= Exponent
/ BB
;
1248 if not Is_Positive
then
1249 S
(1) := S
(1) + BS
;
1252 Ada
.Streams
.Write
(Stream
.all, S
);
1259 procedure W_I
(Stream
: not null access RST
; Item
: Integer) is
1264 if Optimize_Integers
then
1265 S
:= Integer_To_XDR_S_I
(Item
);
1268 -- Test sign and apply two complement notation
1271 then XDR_U
'Last xor XDR_U
(-(Item
+ 1))
1274 for N
in reverse S
'Range loop
1275 S
(N
) := SE
(U
mod BB
);
1284 Ada
.Streams
.Write
(Stream
.all, S
);
1291 procedure W_LF
(Stream
: not null access RST
; Item
: Long_Float) is
1292 I
: constant Precision
:= Double
;
1293 E_Size
: Integer renames Fields
(I
).E_Size
;
1294 E_Bias
: Integer renames Fields
(I
).E_Bias
;
1295 E_Bytes
: SEO
renames Fields
(I
).E_Bytes
;
1296 F_Bytes
: SEO
renames Fields
(I
).F_Bytes
;
1297 F_Size
: Integer renames Fields
(I
).F_Size
;
1298 F_Mask
: SE
renames Fields
(I
).F_Mask
;
1300 Exponent
: Long_Unsigned
;
1301 Fraction
: Long_Long_Unsigned
;
1302 Is_Positive
: Boolean;
1305 S
: SEA
(1 .. LF_L
) := (others => 0);
1308 if not Item
'Valid then
1309 raise Constraint_Error
;
1314 Is_Positive
:= (0.0 <= Item
);
1324 E
:= Long_Float'Exponent (F
) - 1;
1326 -- Denormalized float
1328 if E
<= -E_Bias
then
1330 F
:= Long_Float'Scaling (F
, F_Size
+ E_Bias
- 1);
1332 F
:= Long_Float'Scaling (F
, F_Size
- E
);
1335 -- Compute Exponent and Fraction
1337 Exponent
:= Long_Unsigned
(E
+ E_Bias
);
1338 Fraction
:= Long_Long_Unsigned
(F
* 2.0) / 2;
1343 for I
in reverse LF_L
- F_Bytes
+ 1 .. LF_L
loop
1344 S
(I
) := SE
(Fraction
mod BB
);
1345 Fraction
:= Fraction
/ BB
;
1348 -- Remove implicit bit
1350 S
(LF_L
- F_Bytes
+ 1) := S
(LF_L
- F_Bytes
+ 1) and F_Mask
;
1352 -- Store Exponent (not always at the beginning of a byte)
1354 Exponent
:= Shift_Left
(Exponent
, Integer (E_Bytes
) * SU
- E_Size
- 1);
1355 for N
in reverse 1 .. E_Bytes
loop
1356 S
(N
) := SE
(Exponent
mod BB
) + S
(N
);
1357 Exponent
:= Exponent
/ BB
;
1362 if not Is_Positive
then
1363 S
(1) := S
(1) + BS
;
1366 Ada
.Streams
.Write
(Stream
.all, S
);
1373 procedure W_LI
(Stream
: not null access RST
; Item
: Long_Integer) is
1379 if Optimize_Integers
then
1380 S
:= Long_Long_Integer_To_XDR_S_LI
(Long_Long_Integer (Item
));
1383 -- Test sign and apply two complement notation
1386 X
:= Long_Unsigned
'Last xor Long_Unsigned
(-(Item
+ 1));
1388 X
:= Long_Unsigned
(Item
);
1391 -- Compute using machine unsigned rather than long_unsigned
1393 for N
in reverse S
'Range loop
1395 -- We have filled an unsigned
1397 if (LU_L
- N
) mod UB
= 0 then
1398 U
:= Unsigned
(X
and UL
);
1399 X
:= Shift_Right
(X
, US
);
1402 S
(N
) := SE
(U
mod BB
);
1411 Ada
.Streams
.Write
(Stream
.all, S
);
1418 procedure W_LLF
(Stream
: not null access RST
; Item
: Long_Long_Float) is
1419 I
: constant Precision
:= Quadruple
;
1420 E_Size
: Integer renames Fields
(I
).E_Size
;
1421 E_Bias
: Integer renames Fields
(I
).E_Bias
;
1422 E_Bytes
: SEO
renames Fields
(I
).E_Bytes
;
1423 F_Bytes
: SEO
renames Fields
(I
).F_Bytes
;
1424 F_Size
: Integer renames Fields
(I
).F_Size
;
1426 HFS
: constant Integer := F_Size
/ 2;
1428 Exponent
: Long_Unsigned
;
1429 Fraction_1
: Long_Long_Unsigned
;
1430 Fraction_2
: Long_Long_Unsigned
;
1431 Is_Positive
: Boolean;
1433 F
: Long_Long_Float := Item
;
1434 S
: SEA
(1 .. LLF_L
) := (others => 0);
1437 if not Item
'Valid then
1438 raise Constraint_Error
;
1443 Is_Positive
:= (0.0 <= Item
);
1457 E
:= Long_Long_Float'Exponent (F
) - 1;
1459 -- Denormalized float
1461 if E
<= -E_Bias
then
1462 F
:= Long_Long_Float'Scaling (F
, E_Bias
- 1);
1465 F
:= Long_Long_Float'Scaling
1466 (Long_Long_Float'Fraction (F
), 1);
1469 -- Compute Exponent and Fraction
1471 Exponent
:= Long_Unsigned
(E
+ E_Bias
);
1472 F
:= Long_Long_Float'Scaling (F
, F_Size
- HFS
);
1473 Fraction_1
:= Long_Long_Unsigned
(Long_Long_Float'Floor (F
));
1474 F
:= F
- Long_Long_Float (Fraction_1
);
1475 F
:= Long_Long_Float'Scaling (F
, HFS
);
1476 Fraction_2
:= Long_Long_Unsigned
(Long_Long_Float'Floor (F
));
1481 for I
in reverse LLF_L
- F_Bytes
+ 1 .. LLF_L
- 7 loop
1482 S
(I
) := SE
(Fraction_1
mod BB
);
1483 Fraction_1
:= Fraction_1
/ BB
;
1488 for I
in reverse LLF_L
- 6 .. LLF_L
loop
1489 S
(SEO
(I
)) := SE
(Fraction_2
mod BB
);
1490 Fraction_2
:= Fraction_2
/ BB
;
1493 -- Store Exponent (not always at the beginning of a byte)
1495 Exponent
:= Shift_Left
(Exponent
, Integer (E_Bytes
) * SU
- E_Size
- 1);
1496 for N
in reverse 1 .. E_Bytes
loop
1497 S
(N
) := SE
(Exponent
mod BB
) + S
(N
);
1498 Exponent
:= Exponent
/ BB
;
1503 if not Is_Positive
then
1504 S
(1) := S
(1) + BS
;
1507 Ada
.Streams
.Write
(Stream
.all, S
);
1515 (Stream
: not null access RST
;
1516 Item
: Long_Long_Integer)
1520 X
: Long_Long_Unsigned
;
1523 if Optimize_Integers
then
1524 S
:= Long_Long_Integer_To_XDR_S_LLI
(Item
);
1527 -- Test sign and apply two complement notation
1530 X
:= Long_Long_Unsigned
'Last xor Long_Long_Unsigned
(-(Item
+ 1));
1532 X
:= Long_Long_Unsigned
(Item
);
1535 -- Compute using machine unsigned rather than long_long_unsigned
1537 for N
in reverse S
'Range loop
1539 -- We have filled an unsigned
1541 if (LLU_L
- N
) mod UB
= 0 then
1542 U
:= Unsigned
(X
and UL
);
1543 X
:= Shift_Right
(X
, US
);
1546 S
(N
) := SE
(U
mod BB
);
1555 Ada
.Streams
.Write
(Stream
.all, S
);
1563 (Stream
: not null access RST
;
1564 Item
: Long_Long_Unsigned
)
1568 X
: Long_Long_Unsigned
:= Item
;
1571 if Optimize_Integers
then
1572 S
:= Long_Long_Unsigned_To_XDR_S_LLU
(Item
);
1575 -- Compute using machine unsigned rather than long_long_unsigned
1577 for N
in reverse S
'Range loop
1579 -- We have filled an unsigned
1581 if (LLU_L
- N
) mod UB
= 0 then
1582 U
:= Unsigned
(X
and UL
);
1583 X
:= Shift_Right
(X
, US
);
1586 S
(N
) := SE
(U
mod BB
);
1595 Ada
.Streams
.Write
(Stream
.all, S
);
1602 procedure W_LU
(Stream
: not null access RST
; Item
: Long_Unsigned
) is
1605 X
: Long_Unsigned
:= Item
;
1608 if Optimize_Integers
then
1609 S
:= Long_Long_Unsigned_To_XDR_S_LU
(Long_Long_Unsigned
(Item
));
1612 -- Compute using machine unsigned rather than long_unsigned
1614 for N
in reverse S
'Range loop
1616 -- We have filled an unsigned
1618 if (LU_L
- N
) mod UB
= 0 then
1619 U
:= Unsigned
(X
and UL
);
1620 X
:= Shift_Right
(X
, US
);
1622 S
(N
) := SE
(U
mod BB
);
1631 Ada
.Streams
.Write
(Stream
.all, S
);
1638 procedure W_SF
(Stream
: not null access RST
; Item
: Short_Float) is
1639 I
: constant Precision
:= Single
;
1640 E_Size
: Integer renames Fields
(I
).E_Size
;
1641 E_Bias
: Integer renames Fields
(I
).E_Bias
;
1642 E_Bytes
: SEO
renames Fields
(I
).E_Bytes
;
1643 F_Bytes
: SEO
renames Fields
(I
).F_Bytes
;
1644 F_Size
: Integer renames Fields
(I
).F_Size
;
1645 F_Mask
: SE
renames Fields
(I
).F_Mask
;
1647 Exponent
: Long_Unsigned
;
1648 Fraction
: Long_Unsigned
;
1649 Is_Positive
: Boolean;
1652 S
: SEA
(1 .. SF_L
) := (others => 0);
1655 if not Item
'Valid then
1656 raise Constraint_Error
;
1661 Is_Positive
:= (0.0 <= Item
);
1671 E
:= Short_Float'Exponent (F
) - 1;
1673 -- Denormalized float
1675 if E
<= -E_Bias
then
1677 F
:= Short_Float'Scaling (F
, F_Size
+ E_Bias
- 1);
1679 F
:= Short_Float'Scaling (F
, F_Size
- E
);
1682 -- Compute Exponent and Fraction
1684 Exponent
:= Long_Unsigned
(E
+ E_Bias
);
1685 Fraction
:= Long_Unsigned
(F
* 2.0) / 2;
1690 for I
in reverse SF_L
- F_Bytes
+ 1 .. SF_L
loop
1691 S
(I
) := SE
(Fraction
mod BB
);
1692 Fraction
:= Fraction
/ BB
;
1695 -- Remove implicit bit
1697 S
(SF_L
- F_Bytes
+ 1) := S
(SF_L
- F_Bytes
+ 1) and F_Mask
;
1699 -- Store Exponent (not always at the beginning of a byte)
1701 Exponent
:= Shift_Left
(Exponent
, Integer (E_Bytes
) * SU
- E_Size
- 1);
1702 for N
in reverse 1 .. E_Bytes
loop
1703 S
(N
) := SE
(Exponent
mod BB
) + S
(N
);
1704 Exponent
:= Exponent
/ BB
;
1709 if not Is_Positive
then
1710 S
(1) := S
(1) + BS
;
1713 Ada
.Streams
.Write
(Stream
.all, S
);
1720 procedure W_SI
(Stream
: not null access RST
; Item
: Short_Integer) is
1725 if Optimize_Integers
then
1726 S
:= Short_Integer_To_XDR_S_SI
(Item
);
1729 -- Test sign and apply two complement's notation
1732 then XDR_SU
'Last xor XDR_SU
(-(Item
+ 1))
1733 else XDR_SU
(Item
));
1735 for N
in reverse S
'Range loop
1736 S
(N
) := SE
(U
mod BB
);
1745 Ada
.Streams
.Write
(Stream
.all, S
);
1753 (Stream
: not null access RST
;
1754 Item
: Short_Short_Integer)
1760 if Optimize_Integers
then
1761 S
:= Short_Short_Integer_To_XDR_S_SSI
(Item
);
1764 -- Test sign and apply two complement's notation
1767 then XDR_SSU
'Last xor XDR_SSU
(-(Item
+ 1))
1768 else XDR_SSU
(Item
));
1773 Ada
.Streams
.Write
(Stream
.all, S
);
1781 (Stream
: not null access RST
;
1782 Item
: Short_Short_Unsigned
)
1784 U
: constant XDR_SSU
:= XDR_SSU
(Item
);
1789 Ada
.Streams
.Write
(Stream
.all, S
);
1796 procedure W_SU
(Stream
: not null access RST
; Item
: Short_Unsigned
) is
1798 U
: XDR_SU
:= XDR_SU
(Item
);
1801 if Optimize_Integers
then
1802 S
:= Short_Unsigned_To_XDR_S_SU
(Item
);
1805 for N
in reverse S
'Range loop
1806 S
(N
) := SE
(U
mod BB
);
1815 Ada
.Streams
.Write
(Stream
.all, S
);
1822 procedure W_U
(Stream
: not null access RST
; Item
: Unsigned
) is
1824 U
: XDR_U
:= XDR_U
(Item
);
1827 if Optimize_Integers
then
1828 S
:= Unsigned_To_XDR_S_U
(Item
);
1831 for N
in reverse S
'Range loop
1832 S
(N
) := SE
(U
mod BB
);
1841 Ada
.Streams
.Write
(Stream
.all, S
);
1848 procedure W_WC
(Stream
: not null access RST
; Item
: Wide_Character) is
1853 -- Use Ada requirements on Wide_Character representation clause
1855 U
:= XDR_WC
(Wide_Character'Pos (Item
));
1857 for N
in reverse S
'Range loop
1858 S
(N
) := SE
(U
mod BB
);
1862 Ada
.Streams
.Write
(Stream
.all, S
);
1874 (Stream
: not null access RST
; Item
: Wide_Wide_Character
)
1880 -- Use Ada requirements on Wide_Wide_Character representation clause
1882 U
:= XDR_WWC
(Wide_Wide_Character
'Pos (Item
));
1884 for N
in reverse S
'Range loop
1885 S
(N
) := SE
(U
mod BB
);
1889 Ada
.Streams
.Write
(Stream
.all, S
);
1896 end System
.Stream_Attributes
;