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-2016, 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 pragma Warnings
(Off
, "*not allowed in compiler unit");
37 -- This body is used only when rebuilding the runtime library, not when
38 -- building the compiler, so it's OK to depend on features that would
39 -- otherwise break bootstrap (e.g. IF-expressions).
41 with Ada
.IO_Exceptions
;
42 with Ada
.Streams
; use Ada
.Streams
;
43 with Ada
.Unchecked_Conversion
;
45 package body System
.Stream_Attributes
is
47 pragma Suppress
(Range_Check
);
48 pragma Suppress
(Overflow_Check
);
52 Data_Error
: exception renames Ada
.IO_Exceptions
.End_Error
;
53 -- Exception raised if insufficient data read (End_Error is mandated by
56 SU
: constant := System
.Storage_Unit
;
57 -- The code in this body assumes that SU = 8
59 BB
: constant := 2 ** SU
; -- Byte base
60 BL
: constant := 2 ** SU
- 1; -- Byte last
61 BS
: constant := 2 ** (SU
- 1); -- Byte sign
63 US
: constant := Unsigned
'Size; -- Unsigned size
64 UB
: constant := (US
- 1) / SU
+ 1; -- Unsigned byte
65 UL
: constant := 2 ** US
- 1; -- Unsigned last
67 subtype SE
is Ada
.Streams
.Stream_Element
;
68 subtype SEA
is Ada
.Streams
.Stream_Element_Array
;
69 subtype SEO
is Ada
.Streams
.Stream_Element_Offset
;
71 generic function UC
renames Ada
.Unchecked_Conversion
;
75 E_Size
: Integer; -- Exponent bit size
76 E_Bias
: Integer; -- Exponent bias
77 F_Size
: Integer; -- Fraction bit size
78 E_Last
: Integer; -- Max exponent value
79 F_Mask
: SE
; -- Mask to apply on first fraction byte
80 E_Bytes
: SEO
; -- N. of exponent bytes completely used
81 F_Bytes
: SEO
; -- N. of fraction bytes completely used
82 F_Bits
: Integer; -- N. of bits used on first fraction word
85 type Precision
is (Single
, Double
, Quadruple
);
87 Fields
: constant array (Precision
) of Field_Type
:= (
95 F_Mask
=> 16#
7F#
, -- 2 ** 7 - 1,
105 E_Last
=> 2 ** 11 - 1,
106 F_Mask
=> 16#
0F#
, -- 2 ** 4 - 1,
109 F_Bits
=> 52 mod US
),
111 -- Quadruple precision
116 E_Last
=> 2 ** 8 - 1,
117 F_Mask
=> 16#FF#
, -- 2 ** 8 - 1,
120 F_Bits
=> 112 mod US
));
122 -- The representation of all items requires a multiple of four bytes
123 -- (or 32 bits) of data. The bytes are numbered 0 through n-1. The bytes
124 -- are read or written to some byte stream such that byte m always
125 -- precedes byte m+1. If the n bytes needed to contain the data are not
126 -- a multiple of four, then the n bytes are followed by enough (0 to 3)
127 -- residual zero bytes, r, to make the total byte count a multiple of 4.
129 -- An XDR signed integer is a 32-bit datum that encodes an integer
130 -- in the range [-2147483648,2147483647]. The integer is represented
131 -- in two's complement notation. The most and least significant bytes
132 -- are 0 and 3, respectively. Integers are declared as follows:
135 -- +-------+-------+-------+-------+
136 -- |byte 0 |byte 1 |byte 2 |byte 3 |
137 -- +-------+-------+-------+-------+
138 -- <------------32 bits------------>
140 SSI_L
: constant := 1;
141 SI_L
: constant := 2;
143 LI_L
: constant := 8;
144 LLI_L
: constant := 8;
146 subtype XDR_S_SSI
is SEA
(1 .. SSI_L
);
147 subtype XDR_S_SI
is SEA
(1 .. SI_L
);
148 subtype XDR_S_I
is SEA
(1 .. I_L
);
149 subtype XDR_S_LI
is SEA
(1 .. LI_L
);
150 subtype XDR_S_LLI
is SEA
(1 .. LLI_L
);
152 function Short_Short_Integer_To_XDR_S_SSI
is
153 new Ada
.Unchecked_Conversion
(Short_Short_Integer, XDR_S_SSI
);
154 function XDR_S_SSI_To_Short_Short_Integer
is
155 new Ada
.Unchecked_Conversion
(XDR_S_SSI
, Short_Short_Integer);
157 function Short_Integer_To_XDR_S_SI
is
158 new Ada
.Unchecked_Conversion
(Short_Integer, XDR_S_SI
);
159 function XDR_S_SI_To_Short_Integer
is
160 new Ada
.Unchecked_Conversion
(XDR_S_SI
, Short_Integer);
162 function Integer_To_XDR_S_I
is
163 new Ada
.Unchecked_Conversion
(Integer, XDR_S_I
);
164 function XDR_S_I_To_Integer
is
165 new Ada
.Unchecked_Conversion
(XDR_S_I
, Integer);
167 function Long_Long_Integer_To_XDR_S_LI
is
168 new Ada
.Unchecked_Conversion
(Long_Long_Integer, XDR_S_LI
);
169 function XDR_S_LI_To_Long_Long_Integer
is
170 new Ada
.Unchecked_Conversion
(XDR_S_LI
, Long_Long_Integer);
172 function Long_Long_Integer_To_XDR_S_LLI
is
173 new Ada
.Unchecked_Conversion
(Long_Long_Integer, XDR_S_LLI
);
174 function XDR_S_LLI_To_Long_Long_Integer
is
175 new Ada
.Unchecked_Conversion
(XDR_S_LLI
, Long_Long_Integer);
177 -- An XDR unsigned integer is a 32-bit datum that encodes a nonnegative
178 -- integer in the range [0,4294967295]. It is represented by an unsigned
179 -- binary number whose most and least significant bytes are 0 and 3,
180 -- respectively. An unsigned integer is declared as follows:
183 -- +-------+-------+-------+-------+
184 -- |byte 0 |byte 1 |byte 2 |byte 3 |
185 -- +-------+-------+-------+-------+
186 -- <------------32 bits------------>
188 SSU_L
: constant := 1;
189 SU_L
: constant := 2;
191 LU_L
: constant := 8;
192 LLU_L
: constant := 8;
194 subtype XDR_S_SSU
is SEA
(1 .. SSU_L
);
195 subtype XDR_S_SU
is SEA
(1 .. SU_L
);
196 subtype XDR_S_U
is SEA
(1 .. U_L
);
197 subtype XDR_S_LU
is SEA
(1 .. LU_L
);
198 subtype XDR_S_LLU
is SEA
(1 .. LLU_L
);
200 type XDR_SSU
is mod BB
** SSU_L
;
201 type XDR_SU
is mod BB
** SU_L
;
202 type XDR_U
is mod BB
** U_L
;
204 function Short_Unsigned_To_XDR_S_SU
is
205 new Ada
.Unchecked_Conversion
(Short_Unsigned
, XDR_S_SU
);
206 function XDR_S_SU_To_Short_Unsigned
is
207 new Ada
.Unchecked_Conversion
(XDR_S_SU
, Short_Unsigned
);
209 function Unsigned_To_XDR_S_U
is
210 new Ada
.Unchecked_Conversion
(Unsigned
, XDR_S_U
);
211 function XDR_S_U_To_Unsigned
is
212 new Ada
.Unchecked_Conversion
(XDR_S_U
, Unsigned
);
214 function Long_Long_Unsigned_To_XDR_S_LU
is
215 new Ada
.Unchecked_Conversion
(Long_Long_Unsigned
, XDR_S_LU
);
216 function XDR_S_LU_To_Long_Long_Unsigned
is
217 new Ada
.Unchecked_Conversion
(XDR_S_LU
, Long_Long_Unsigned
);
219 function Long_Long_Unsigned_To_XDR_S_LLU
is
220 new Ada
.Unchecked_Conversion
(Long_Long_Unsigned
, XDR_S_LLU
);
221 function XDR_S_LLU_To_Long_Long_Unsigned
is
222 new Ada
.Unchecked_Conversion
(XDR_S_LLU
, Long_Long_Unsigned
);
224 -- The standard defines the floating-point data type "float" (32 bits
225 -- or 4 bytes). The encoding used is the IEEE standard for normalized
226 -- single-precision floating-point numbers.
228 -- The standard defines the encoding used for the double-precision
229 -- floating-point data type "double" (64 bits or 8 bytes). The encoding
230 -- used is the IEEE standard for normalized double-precision floating-point
233 SF_L
: constant := 4; -- Single precision
234 F_L
: constant := 4; -- Single precision
235 LF_L
: constant := 8; -- Double precision
236 LLF_L
: constant := 16; -- Quadruple precision
238 TM_L
: constant := 8;
239 subtype XDR_S_TM
is SEA
(1 .. TM_L
);
240 type XDR_TM
is mod BB
** TM_L
;
242 type XDR_SA
is mod 2 ** Standard
'Address_Size;
243 function To_XDR_SA
is new UC
(System
.Address
, XDR_SA
);
244 function To_XDR_SA
is new UC
(XDR_SA
, System
.Address
);
246 -- Enumerations have the same representation as signed integers.
247 -- Enumerations are handy for describing subsets of the integers.
249 -- Booleans are important enough and occur frequently enough to warrant
250 -- their own explicit type in the standard. Booleans are declared as
251 -- an enumeration, with FALSE = 0 and TRUE = 1.
253 -- The standard defines a string of n (numbered 0 through n-1) ASCII
254 -- bytes to be the number n encoded as an unsigned integer (as described
255 -- above), and followed by the n bytes of the string. Byte m of the string
256 -- always precedes byte m+1 of the string, and byte 0 of the string always
257 -- follows the string's length. If n is not a multiple of four, then the
258 -- n bytes are followed by enough (0 to 3) residual zero bytes, r, to make
259 -- the total byte count a multiple of four.
261 -- To fit with XDR string, do not consider character as an enumeration
265 subtype XDR_S_C
is SEA
(1 .. C_L
);
267 -- Consider Wide_Character as an enumeration type
269 WC_L
: constant := 4;
270 subtype XDR_S_WC
is SEA
(1 .. WC_L
);
271 type XDR_WC
is mod BB
** WC_L
;
273 -- Consider Wide_Wide_Character as an enumeration type
275 WWC_L
: constant := 8;
276 subtype XDR_S_WWC
is SEA
(1 .. WWC_L
);
277 type XDR_WWC
is mod BB
** WWC_L
;
279 -- Optimization: if we already have the correct Bit_Order, then some
280 -- computations can be avoided since the source and the target will be
281 -- identical anyway. They will be replaced by direct unchecked
284 Optimize_Integers
: constant Boolean :=
285 Default_Bit_Order
= High_Order_First
;
291 -- We must inhibit Block_IO, because in XDR mode, each element is output
292 -- according to XDR requirements, which is not at all the same as writing
293 -- the whole array in one block.
295 function Block_IO_OK
return Boolean is
304 function I_AD
(Stream
: not null access RST
) return Fat_Pointer
is
308 FP
.P1
:= I_AS
(Stream
).P1
;
309 FP
.P2
:= I_AS
(Stream
).P1
;
318 function I_AS
(Stream
: not null access RST
) return Thin_Pointer
is
324 Ada
.Streams
.Read
(Stream
.all, S
, L
);
330 for N
in S
'Range loop
331 U
:= U
* BB
+ XDR_TM
(S
(N
));
334 return (P1
=> To_XDR_SA
(XDR_SA
(U
)));
342 function I_B
(Stream
: not null access RST
) return Boolean is
344 case I_SSU
(Stream
) is
345 when 0 => return False;
346 when 1 => return True;
347 when others => raise Data_Error
;
355 function I_C
(Stream
: not null access RST
) return Character is
360 Ada
.Streams
.Read
(Stream
.all, S
, L
);
366 -- Use Ada requirements on Character representation clause
368 return Character'Val (S
(1));
376 function I_F
(Stream
: not null access RST
) return Float is
377 I
: constant Precision
:= Single
;
378 E_Size
: Integer renames Fields
(I
).E_Size
;
379 E_Bias
: Integer renames Fields
(I
).E_Bias
;
380 E_Last
: Integer renames Fields
(I
).E_Last
;
381 F_Mask
: SE
renames Fields
(I
).F_Mask
;
382 E_Bytes
: SEO
renames Fields
(I
).E_Bytes
;
383 F_Bytes
: SEO
renames Fields
(I
).F_Bytes
;
384 F_Size
: Integer renames Fields
(I
).F_Size
;
386 Is_Positive
: Boolean;
387 Exponent
: Long_Unsigned
;
388 Fraction
: Long_Unsigned
;
394 Ada
.Streams
.Read
(Stream
.all, S
, L
);
400 -- Extract Fraction, Sign and Exponent
402 Fraction
:= Long_Unsigned
(S
(F_L
+ 1 - F_Bytes
) and F_Mask
);
403 for N
in F_L
+ 2 - F_Bytes
.. F_L
loop
404 Fraction
:= Fraction
* BB
+ Long_Unsigned
(S
(N
));
406 Result
:= Float'Scaling (Float (Fraction
), -F_Size
);
409 Is_Positive
:= False;
410 Exponent
:= Long_Unsigned
(S
(1) - BS
);
413 Exponent
:= Long_Unsigned
(S
(1));
416 for N
in 2 .. E_Bytes
loop
417 Exponent
:= Exponent
* BB
+ Long_Unsigned
(S
(N
));
419 Exponent
:= Shift_Right
(Exponent
, Integer (E_Bytes
) * SU
- E_Size
- 1);
423 if Integer (Exponent
) = E_Last
then
424 raise Constraint_Error
;
426 elsif Exponent
= 0 then
433 -- Denormalized float
436 Result
:= Float'Scaling (Result
, 1 - E_Bias
);
442 Result
:= Float'Scaling
443 (1.0 + Result
, Integer (Exponent
) - E_Bias
);
446 if not Is_Positive
then
457 function I_I
(Stream
: not null access RST
) return Integer is
463 Ada
.Streams
.Read
(Stream
.all, S
, L
);
468 elsif Optimize_Integers
then
469 return XDR_S_I_To_Integer
(S
);
472 for N
in S
'Range loop
473 U
:= U
* BB
+ XDR_U
(S
(N
));
476 -- Test sign and apply two complement notation
482 return Integer (-((XDR_U
'Last xor U
) + 1));
491 function I_LF
(Stream
: not null access RST
) return Long_Float is
492 I
: constant Precision
:= Double
;
493 E_Size
: Integer renames Fields
(I
).E_Size
;
494 E_Bias
: Integer renames Fields
(I
).E_Bias
;
495 E_Last
: Integer renames Fields
(I
).E_Last
;
496 F_Mask
: SE
renames Fields
(I
).F_Mask
;
497 E_Bytes
: SEO
renames Fields
(I
).E_Bytes
;
498 F_Bytes
: SEO
renames Fields
(I
).F_Bytes
;
499 F_Size
: Integer renames Fields
(I
).F_Size
;
501 Is_Positive
: Boolean;
502 Exponent
: Long_Unsigned
;
503 Fraction
: Long_Long_Unsigned
;
509 Ada
.Streams
.Read
(Stream
.all, S
, L
);
515 -- Extract Fraction, Sign and Exponent
517 Fraction
:= Long_Long_Unsigned
(S
(LF_L
+ 1 - F_Bytes
) and F_Mask
);
518 for N
in LF_L
+ 2 - F_Bytes
.. LF_L
loop
519 Fraction
:= Fraction
* BB
+ Long_Long_Unsigned
(S
(N
));
522 Result
:= Long_Float'Scaling (Long_Float (Fraction
), -F_Size
);
525 Is_Positive
:= False;
526 Exponent
:= Long_Unsigned
(S
(1) - BS
);
529 Exponent
:= Long_Unsigned
(S
(1));
532 for N
in 2 .. E_Bytes
loop
533 Exponent
:= Exponent
* BB
+ Long_Unsigned
(S
(N
));
536 Exponent
:= Shift_Right
(Exponent
, Integer (E_Bytes
) * SU
- E_Size
- 1);
540 if Integer (Exponent
) = E_Last
then
541 raise Constraint_Error
;
543 elsif Exponent
= 0 then
550 -- Denormalized float
553 Result
:= Long_Float'Scaling (Result
, 1 - E_Bias
);
559 Result
:= Long_Float'Scaling
560 (1.0 + Result
, Integer (Exponent
) - E_Bias
);
563 if not Is_Positive
then
574 function I_LI
(Stream
: not null access RST
) return Long_Integer is
578 X
: Long_Unsigned
:= 0;
581 Ada
.Streams
.Read
(Stream
.all, S
, L
);
586 elsif Optimize_Integers
then
587 return Long_Integer (XDR_S_LI_To_Long_Long_Integer
(S
));
591 -- Compute using machine unsigned
592 -- rather than long_long_unsigned
594 for N
in S
'Range loop
595 U
:= U
* BB
+ Unsigned
(S
(N
));
597 -- We have filled an unsigned
600 X
:= Shift_Left
(X
, US
) + Long_Unsigned
(U
);
605 -- Test sign and apply two complement notation
608 return Long_Integer (X
);
610 return Long_Integer (-((Long_Unsigned
'Last xor X
) + 1));
620 function I_LLF
(Stream
: not null access RST
) return Long_Long_Float is
621 I
: constant Precision
:= Quadruple
;
622 E_Size
: Integer renames Fields
(I
).E_Size
;
623 E_Bias
: Integer renames Fields
(I
).E_Bias
;
624 E_Last
: Integer renames Fields
(I
).E_Last
;
625 E_Bytes
: SEO
renames Fields
(I
).E_Bytes
;
626 F_Bytes
: SEO
renames Fields
(I
).F_Bytes
;
627 F_Size
: Integer renames Fields
(I
).F_Size
;
629 Is_Positive
: Boolean;
630 Exponent
: Long_Unsigned
;
631 Fraction_1
: Long_Long_Unsigned
:= 0;
632 Fraction_2
: Long_Long_Unsigned
:= 0;
633 Result
: Long_Long_Float;
634 HF
: constant Natural := F_Size
/ 2;
635 S
: SEA
(1 .. LLF_L
);
639 Ada
.Streams
.Read
(Stream
.all, S
, L
);
645 -- Extract Fraction, Sign and Exponent
647 for I
in LLF_L
- F_Bytes
+ 1 .. LLF_L
- 7 loop
648 Fraction_1
:= Fraction_1
* BB
+ Long_Long_Unsigned
(S
(I
));
651 for I
in SEO
(LLF_L
- 6) .. SEO
(LLF_L
) loop
652 Fraction_2
:= Fraction_2
* BB
+ Long_Long_Unsigned
(S
(I
));
655 Result
:= Long_Long_Float'Scaling (Long_Long_Float (Fraction_2
), -HF
);
656 Result
:= Long_Long_Float (Fraction_1
) + Result
;
657 Result
:= Long_Long_Float'Scaling (Result
, HF
- F_Size
);
660 Is_Positive
:= False;
661 Exponent
:= Long_Unsigned
(S
(1) - BS
);
664 Exponent
:= Long_Unsigned
(S
(1));
667 for N
in 2 .. E_Bytes
loop
668 Exponent
:= Exponent
* BB
+ Long_Unsigned
(S
(N
));
671 Exponent
:= Shift_Right
(Exponent
, Integer (E_Bytes
) * SU
- E_Size
- 1);
675 if Integer (Exponent
) = E_Last
then
676 raise Constraint_Error
;
678 elsif Exponent
= 0 then
682 if Fraction_1
= 0 and then Fraction_2
= 0 then
685 -- Denormalized float
688 Result
:= Long_Long_Float'Scaling (Result
, 1 - E_Bias
);
694 Result
:= Long_Long_Float'Scaling
695 (1.0 + Result
, Integer (Exponent
) - E_Bias
);
698 if not Is_Positive
then
709 function I_LLI
(Stream
: not null access RST
) return Long_Long_Integer is
713 X
: Long_Long_Unsigned
:= 0;
716 Ada
.Streams
.Read
(Stream
.all, S
, L
);
721 elsif Optimize_Integers
then
722 return XDR_S_LLI_To_Long_Long_Integer
(S
);
725 -- Compute using machine unsigned for computing
726 -- rather than long_long_unsigned.
728 for N
in S
'Range loop
729 U
:= U
* BB
+ Unsigned
(S
(N
));
731 -- We have filled an unsigned
734 X
:= Shift_Left
(X
, US
) + Long_Long_Unsigned
(U
);
739 -- Test sign and apply two complement notation
742 return Long_Long_Integer (X
);
744 return Long_Long_Integer (-((Long_Long_Unsigned
'Last xor X
) + 1));
753 function I_LLU
(Stream
: not null access RST
) return Long_Long_Unsigned
is
757 X
: Long_Long_Unsigned
:= 0;
760 Ada
.Streams
.Read
(Stream
.all, S
, L
);
765 elsif Optimize_Integers
then
766 return XDR_S_LLU_To_Long_Long_Unsigned
(S
);
769 -- Compute using machine unsigned
770 -- rather than long_long_unsigned.
772 for N
in S
'Range loop
773 U
:= U
* BB
+ Unsigned
(S
(N
));
775 -- We have filled an unsigned
778 X
:= Shift_Left
(X
, US
) + Long_Long_Unsigned
(U
);
791 function I_LU
(Stream
: not null access RST
) return Long_Unsigned
is
795 X
: Long_Unsigned
:= 0;
798 Ada
.Streams
.Read
(Stream
.all, S
, L
);
803 elsif Optimize_Integers
then
804 return Long_Unsigned
(XDR_S_LU_To_Long_Long_Unsigned
(S
));
807 -- Compute using machine unsigned
808 -- rather than long_unsigned.
810 for N
in S
'Range loop
811 U
:= U
* BB
+ Unsigned
(S
(N
));
813 -- We have filled an unsigned
816 X
:= Shift_Left
(X
, US
) + Long_Unsigned
(U
);
829 function I_SF
(Stream
: not null access RST
) return Short_Float is
830 I
: constant Precision
:= Single
;
831 E_Size
: Integer renames Fields
(I
).E_Size
;
832 E_Bias
: Integer renames Fields
(I
).E_Bias
;
833 E_Last
: Integer renames Fields
(I
).E_Last
;
834 F_Mask
: SE
renames Fields
(I
).F_Mask
;
835 E_Bytes
: SEO
renames Fields
(I
).E_Bytes
;
836 F_Bytes
: SEO
renames Fields
(I
).F_Bytes
;
837 F_Size
: Integer renames Fields
(I
).F_Size
;
839 Exponent
: Long_Unsigned
;
840 Fraction
: Long_Unsigned
;
841 Is_Positive
: Boolean;
842 Result
: Short_Float;
847 Ada
.Streams
.Read
(Stream
.all, S
, L
);
853 -- Extract Fraction, Sign and Exponent
855 Fraction
:= Long_Unsigned
(S
(SF_L
+ 1 - F_Bytes
) and F_Mask
);
856 for N
in SF_L
+ 2 - F_Bytes
.. SF_L
loop
857 Fraction
:= Fraction
* BB
+ Long_Unsigned
(S
(N
));
859 Result
:= Short_Float'Scaling (Short_Float (Fraction
), -F_Size
);
862 Is_Positive
:= False;
863 Exponent
:= Long_Unsigned
(S
(1) - BS
);
866 Exponent
:= Long_Unsigned
(S
(1));
869 for N
in 2 .. E_Bytes
loop
870 Exponent
:= Exponent
* BB
+ Long_Unsigned
(S
(N
));
872 Exponent
:= Shift_Right
(Exponent
, Integer (E_Bytes
) * SU
- E_Size
- 1);
876 if Integer (Exponent
) = E_Last
then
877 raise Constraint_Error
;
879 elsif Exponent
= 0 then
886 -- Denormalized float
889 Result
:= Short_Float'Scaling (Result
, 1 - E_Bias
);
895 Result
:= Short_Float'Scaling
896 (1.0 + Result
, Integer (Exponent
) - E_Bias
);
899 if not Is_Positive
then
910 function I_SI
(Stream
: not null access RST
) return Short_Integer is
916 Ada
.Streams
.Read
(Stream
.all, S
, L
);
921 elsif Optimize_Integers
then
922 return XDR_S_SI_To_Short_Integer
(S
);
925 for N
in S
'Range loop
926 U
:= U
* BB
+ XDR_SU
(S
(N
));
929 -- Test sign and apply two complement notation
932 return Short_Integer (U
);
934 return Short_Integer (-((XDR_SU
'Last xor U
) + 1));
943 function I_SSI
(Stream
: not null access RST
) return Short_Short_Integer is
949 Ada
.Streams
.Read
(Stream
.all, S
, L
);
954 elsif Optimize_Integers
then
955 return XDR_S_SSI_To_Short_Short_Integer
(S
);
958 U
:= XDR_SSU
(S
(1));
960 -- Test sign and apply two complement notation
963 return Short_Short_Integer (U
);
965 return Short_Short_Integer (-((XDR_SSU
'Last xor U
) + 1));
974 function I_SSU
(Stream
: not null access RST
) return Short_Short_Unsigned
is
980 Ada
.Streams
.Read
(Stream
.all, S
, L
);
986 U
:= XDR_SSU
(S
(1));
987 return Short_Short_Unsigned
(U
);
995 function I_SU
(Stream
: not null access RST
) return Short_Unsigned
is
1001 Ada
.Streams
.Read
(Stream
.all, S
, L
);
1006 elsif Optimize_Integers
then
1007 return XDR_S_SU_To_Short_Unsigned
(S
);
1010 for N
in S
'Range loop
1011 U
:= U
* BB
+ XDR_SU
(S
(N
));
1014 return Short_Unsigned
(U
);
1022 function I_U
(Stream
: not null access RST
) return Unsigned
is
1028 Ada
.Streams
.Read
(Stream
.all, S
, L
);
1033 elsif Optimize_Integers
then
1034 return XDR_S_U_To_Unsigned
(S
);
1037 for N
in S
'Range loop
1038 U
:= U
* BB
+ XDR_U
(S
(N
));
1041 return Unsigned
(U
);
1049 function I_WC
(Stream
: not null access RST
) return Wide_Character is
1055 Ada
.Streams
.Read
(Stream
.all, S
, L
);
1061 for N
in S
'Range loop
1062 U
:= U
* BB
+ XDR_WC
(S
(N
));
1065 -- Use Ada requirements on Wide_Character representation clause
1067 return Wide_Character'Val (U
);
1075 function I_WWC
(Stream
: not null access RST
) return Wide_Wide_Character
is
1081 Ada
.Streams
.Read
(Stream
.all, S
, L
);
1087 for N
in S
'Range loop
1088 U
:= U
* BB
+ XDR_WWC
(S
(N
));
1091 -- Use Ada requirements on Wide_Wide_Character representation clause
1093 return Wide_Wide_Character
'Val (U
);
1101 procedure W_AD
(Stream
: not null access RST
; Item
: Fat_Pointer
) is
1106 U
:= XDR_TM
(To_XDR_SA
(Item
.P1
));
1107 for N
in reverse S
'Range loop
1108 S
(N
) := SE
(U
mod BB
);
1112 Ada
.Streams
.Write
(Stream
.all, S
);
1114 U
:= XDR_TM
(To_XDR_SA
(Item
.P2
));
1115 for N
in reverse S
'Range loop
1116 S
(N
) := SE
(U
mod BB
);
1120 Ada
.Streams
.Write
(Stream
.all, S
);
1131 procedure W_AS
(Stream
: not null access RST
; Item
: Thin_Pointer
) is
1133 U
: XDR_TM
:= XDR_TM
(To_XDR_SA
(Item
.P1
));
1136 for N
in reverse S
'Range loop
1137 S
(N
) := SE
(U
mod BB
);
1141 Ada
.Streams
.Write
(Stream
.all, S
);
1152 procedure W_B
(Stream
: not null access RST
; Item
: Boolean) is
1165 procedure W_C
(Stream
: not null access RST
; Item
: Character) is
1168 pragma Assert
(C_L
= 1);
1171 -- Use Ada requirements on Character representation clause
1173 S
(1) := SE
(Character'Pos (Item
));
1175 Ada
.Streams
.Write
(Stream
.all, S
);
1182 procedure W_F
(Stream
: not null access RST
; Item
: Float) is
1183 I
: constant Precision
:= Single
;
1184 E_Size
: Integer renames Fields
(I
).E_Size
;
1185 E_Bias
: Integer renames Fields
(I
).E_Bias
;
1186 E_Bytes
: SEO
renames Fields
(I
).E_Bytes
;
1187 F_Bytes
: SEO
renames Fields
(I
).F_Bytes
;
1188 F_Size
: Integer renames Fields
(I
).F_Size
;
1189 F_Mask
: SE
renames Fields
(I
).F_Mask
;
1191 Exponent
: Long_Unsigned
;
1192 Fraction
: Long_Unsigned
;
1193 Is_Positive
: Boolean;
1196 S
: SEA
(1 .. F_L
) := (others => 0);
1199 if not Item
'Valid then
1200 raise Constraint_Error
;
1205 Is_Positive
:= (0.0 <= Item
);
1215 E
:= Float'Exponent (F
) - 1;
1217 -- Denormalized float
1219 if E
<= -E_Bias
then
1220 F
:= Float'Scaling (F
, F_Size
+ E_Bias
- 1);
1223 F
:= Float'Scaling (Float'Fraction (F
), F_Size
+ 1);
1226 -- Compute Exponent and Fraction
1228 Exponent
:= Long_Unsigned
(E
+ E_Bias
);
1229 Fraction
:= Long_Unsigned
(F
* 2.0) / 2;
1234 for I
in reverse F_L
- F_Bytes
+ 1 .. F_L
loop
1235 S
(I
) := SE
(Fraction
mod BB
);
1236 Fraction
:= Fraction
/ BB
;
1239 -- Remove implicit bit
1241 S
(F_L
- F_Bytes
+ 1) := S
(F_L
- F_Bytes
+ 1) and F_Mask
;
1243 -- Store Exponent (not always at the beginning of a byte)
1245 Exponent
:= Shift_Left
(Exponent
, Integer (E_Bytes
) * SU
- E_Size
- 1);
1246 for N
in reverse 1 .. E_Bytes
loop
1247 S
(N
) := SE
(Exponent
mod BB
) + S
(N
);
1248 Exponent
:= Exponent
/ BB
;
1253 if not Is_Positive
then
1254 S
(1) := S
(1) + BS
;
1257 Ada
.Streams
.Write
(Stream
.all, S
);
1264 procedure W_I
(Stream
: not null access RST
; Item
: Integer) is
1269 if Optimize_Integers
then
1270 S
:= Integer_To_XDR_S_I
(Item
);
1273 -- Test sign and apply two complement notation
1276 then XDR_U
'Last xor XDR_U
(-(Item
+ 1))
1279 for N
in reverse S
'Range loop
1280 S
(N
) := SE
(U
mod BB
);
1289 Ada
.Streams
.Write
(Stream
.all, S
);
1296 procedure W_LF
(Stream
: not null access RST
; Item
: Long_Float) is
1297 I
: constant Precision
:= Double
;
1298 E_Size
: Integer renames Fields
(I
).E_Size
;
1299 E_Bias
: Integer renames Fields
(I
).E_Bias
;
1300 E_Bytes
: SEO
renames Fields
(I
).E_Bytes
;
1301 F_Bytes
: SEO
renames Fields
(I
).F_Bytes
;
1302 F_Size
: Integer renames Fields
(I
).F_Size
;
1303 F_Mask
: SE
renames Fields
(I
).F_Mask
;
1305 Exponent
: Long_Unsigned
;
1306 Fraction
: Long_Long_Unsigned
;
1307 Is_Positive
: Boolean;
1310 S
: SEA
(1 .. LF_L
) := (others => 0);
1313 if not Item
'Valid then
1314 raise Constraint_Error
;
1319 Is_Positive
:= (0.0 <= Item
);
1329 E
:= Long_Float'Exponent (F
) - 1;
1331 -- Denormalized float
1333 if E
<= -E_Bias
then
1335 F
:= Long_Float'Scaling (F
, F_Size
+ E_Bias
- 1);
1337 F
:= Long_Float'Scaling (F
, F_Size
- E
);
1340 -- Compute Exponent and Fraction
1342 Exponent
:= Long_Unsigned
(E
+ E_Bias
);
1343 Fraction
:= Long_Long_Unsigned
(F
* 2.0) / 2;
1348 for I
in reverse LF_L
- F_Bytes
+ 1 .. LF_L
loop
1349 S
(I
) := SE
(Fraction
mod BB
);
1350 Fraction
:= Fraction
/ BB
;
1353 -- Remove implicit bit
1355 S
(LF_L
- F_Bytes
+ 1) := S
(LF_L
- F_Bytes
+ 1) and F_Mask
;
1357 -- Store Exponent (not always at the beginning of a byte)
1359 Exponent
:= Shift_Left
(Exponent
, Integer (E_Bytes
) * SU
- E_Size
- 1);
1360 for N
in reverse 1 .. E_Bytes
loop
1361 S
(N
) := SE
(Exponent
mod BB
) + S
(N
);
1362 Exponent
:= Exponent
/ BB
;
1367 if not Is_Positive
then
1368 S
(1) := S
(1) + BS
;
1371 Ada
.Streams
.Write
(Stream
.all, S
);
1378 procedure W_LI
(Stream
: not null access RST
; Item
: Long_Integer) is
1384 if Optimize_Integers
then
1385 S
:= Long_Long_Integer_To_XDR_S_LI
(Long_Long_Integer (Item
));
1388 -- Test sign and apply two complement notation
1391 X
:= Long_Unsigned
'Last xor Long_Unsigned
(-(Item
+ 1));
1393 X
:= Long_Unsigned
(Item
);
1396 -- Compute using machine unsigned rather than long_unsigned
1398 for N
in reverse S
'Range loop
1400 -- We have filled an unsigned
1402 if (LU_L
- N
) mod UB
= 0 then
1403 U
:= Unsigned
(X
and UL
);
1404 X
:= Shift_Right
(X
, US
);
1407 S
(N
) := SE
(U
mod BB
);
1416 Ada
.Streams
.Write
(Stream
.all, S
);
1423 procedure W_LLF
(Stream
: not null access RST
; Item
: Long_Long_Float) is
1424 I
: constant Precision
:= Quadruple
;
1425 E_Size
: Integer renames Fields
(I
).E_Size
;
1426 E_Bias
: Integer renames Fields
(I
).E_Bias
;
1427 E_Bytes
: SEO
renames Fields
(I
).E_Bytes
;
1428 F_Bytes
: SEO
renames Fields
(I
).F_Bytes
;
1429 F_Size
: Integer renames Fields
(I
).F_Size
;
1431 HFS
: constant Integer := F_Size
/ 2;
1433 Exponent
: Long_Unsigned
;
1434 Fraction_1
: Long_Long_Unsigned
;
1435 Fraction_2
: Long_Long_Unsigned
;
1436 Is_Positive
: Boolean;
1438 F
: Long_Long_Float := Item
;
1439 S
: SEA
(1 .. LLF_L
) := (others => 0);
1442 if not Item
'Valid then
1443 raise Constraint_Error
;
1448 Is_Positive
:= (0.0 <= Item
);
1462 E
:= Long_Long_Float'Exponent (F
) - 1;
1464 -- Denormalized float
1466 if E
<= -E_Bias
then
1467 F
:= Long_Long_Float'Scaling (F
, E_Bias
- 1);
1470 F
:= Long_Long_Float'Scaling
1471 (Long_Long_Float'Fraction (F
), 1);
1474 -- Compute Exponent and Fraction
1476 Exponent
:= Long_Unsigned
(E
+ E_Bias
);
1477 F
:= Long_Long_Float'Scaling (F
, F_Size
- HFS
);
1478 Fraction_1
:= Long_Long_Unsigned
(Long_Long_Float'Floor (F
));
1479 F
:= F
- Long_Long_Float (Fraction_1
);
1480 F
:= Long_Long_Float'Scaling (F
, HFS
);
1481 Fraction_2
:= Long_Long_Unsigned
(Long_Long_Float'Floor (F
));
1486 for I
in reverse LLF_L
- F_Bytes
+ 1 .. LLF_L
- 7 loop
1487 S
(I
) := SE
(Fraction_1
mod BB
);
1488 Fraction_1
:= Fraction_1
/ BB
;
1493 for I
in reverse LLF_L
- 6 .. LLF_L
loop
1494 S
(SEO
(I
)) := SE
(Fraction_2
mod BB
);
1495 Fraction_2
:= Fraction_2
/ BB
;
1498 -- Store Exponent (not always at the beginning of a byte)
1500 Exponent
:= Shift_Left
(Exponent
, Integer (E_Bytes
) * SU
- E_Size
- 1);
1501 for N
in reverse 1 .. E_Bytes
loop
1502 S
(N
) := SE
(Exponent
mod BB
) + S
(N
);
1503 Exponent
:= Exponent
/ BB
;
1508 if not Is_Positive
then
1509 S
(1) := S
(1) + BS
;
1512 Ada
.Streams
.Write
(Stream
.all, S
);
1520 (Stream
: not null access RST
;
1521 Item
: Long_Long_Integer)
1525 X
: Long_Long_Unsigned
;
1528 if Optimize_Integers
then
1529 S
:= Long_Long_Integer_To_XDR_S_LLI
(Item
);
1532 -- Test sign and apply two complement notation
1535 X
:= Long_Long_Unsigned
'Last xor Long_Long_Unsigned
(-(Item
+ 1));
1537 X
:= Long_Long_Unsigned
(Item
);
1540 -- Compute using machine unsigned rather than long_long_unsigned
1542 for N
in reverse S
'Range loop
1544 -- We have filled an unsigned
1546 if (LLU_L
- N
) mod UB
= 0 then
1547 U
:= Unsigned
(X
and UL
);
1548 X
:= Shift_Right
(X
, US
);
1551 S
(N
) := SE
(U
mod BB
);
1560 Ada
.Streams
.Write
(Stream
.all, S
);
1568 (Stream
: not null access RST
;
1569 Item
: Long_Long_Unsigned
)
1573 X
: Long_Long_Unsigned
:= Item
;
1576 if Optimize_Integers
then
1577 S
:= Long_Long_Unsigned_To_XDR_S_LLU
(Item
);
1580 -- Compute using machine unsigned rather than long_long_unsigned
1582 for N
in reverse S
'Range loop
1584 -- We have filled an unsigned
1586 if (LLU_L
- N
) mod UB
= 0 then
1587 U
:= Unsigned
(X
and UL
);
1588 X
:= Shift_Right
(X
, US
);
1591 S
(N
) := SE
(U
mod BB
);
1600 Ada
.Streams
.Write
(Stream
.all, S
);
1607 procedure W_LU
(Stream
: not null access RST
; Item
: Long_Unsigned
) is
1610 X
: Long_Unsigned
:= Item
;
1613 if Optimize_Integers
then
1614 S
:= Long_Long_Unsigned_To_XDR_S_LU
(Long_Long_Unsigned
(Item
));
1617 -- Compute using machine unsigned rather than long_unsigned
1619 for N
in reverse S
'Range loop
1621 -- We have filled an unsigned
1623 if (LU_L
- N
) mod UB
= 0 then
1624 U
:= Unsigned
(X
and UL
);
1625 X
:= Shift_Right
(X
, US
);
1627 S
(N
) := SE
(U
mod BB
);
1636 Ada
.Streams
.Write
(Stream
.all, S
);
1643 procedure W_SF
(Stream
: not null access RST
; Item
: Short_Float) is
1644 I
: constant Precision
:= Single
;
1645 E_Size
: Integer renames Fields
(I
).E_Size
;
1646 E_Bias
: Integer renames Fields
(I
).E_Bias
;
1647 E_Bytes
: SEO
renames Fields
(I
).E_Bytes
;
1648 F_Bytes
: SEO
renames Fields
(I
).F_Bytes
;
1649 F_Size
: Integer renames Fields
(I
).F_Size
;
1650 F_Mask
: SE
renames Fields
(I
).F_Mask
;
1652 Exponent
: Long_Unsigned
;
1653 Fraction
: Long_Unsigned
;
1654 Is_Positive
: Boolean;
1657 S
: SEA
(1 .. SF_L
) := (others => 0);
1660 if not Item
'Valid then
1661 raise Constraint_Error
;
1666 Is_Positive
:= (0.0 <= Item
);
1676 E
:= Short_Float'Exponent (F
) - 1;
1678 -- Denormalized float
1680 if E
<= -E_Bias
then
1682 F
:= Short_Float'Scaling (F
, F_Size
+ E_Bias
- 1);
1684 F
:= Short_Float'Scaling (F
, F_Size
- E
);
1687 -- Compute Exponent and Fraction
1689 Exponent
:= Long_Unsigned
(E
+ E_Bias
);
1690 Fraction
:= Long_Unsigned
(F
* 2.0) / 2;
1695 for I
in reverse SF_L
- F_Bytes
+ 1 .. SF_L
loop
1696 S
(I
) := SE
(Fraction
mod BB
);
1697 Fraction
:= Fraction
/ BB
;
1700 -- Remove implicit bit
1702 S
(SF_L
- F_Bytes
+ 1) := S
(SF_L
- F_Bytes
+ 1) and F_Mask
;
1704 -- Store Exponent (not always at the beginning of a byte)
1706 Exponent
:= Shift_Left
(Exponent
, Integer (E_Bytes
) * SU
- E_Size
- 1);
1707 for N
in reverse 1 .. E_Bytes
loop
1708 S
(N
) := SE
(Exponent
mod BB
) + S
(N
);
1709 Exponent
:= Exponent
/ BB
;
1714 if not Is_Positive
then
1715 S
(1) := S
(1) + BS
;
1718 Ada
.Streams
.Write
(Stream
.all, S
);
1725 procedure W_SI
(Stream
: not null access RST
; Item
: Short_Integer) is
1730 if Optimize_Integers
then
1731 S
:= Short_Integer_To_XDR_S_SI
(Item
);
1734 -- Test sign and apply two complement's notation
1737 then XDR_SU
'Last xor XDR_SU
(-(Item
+ 1))
1738 else XDR_SU
(Item
));
1740 for N
in reverse S
'Range loop
1741 S
(N
) := SE
(U
mod BB
);
1750 Ada
.Streams
.Write
(Stream
.all, S
);
1758 (Stream
: not null access RST
;
1759 Item
: Short_Short_Integer)
1765 if Optimize_Integers
then
1766 S
:= Short_Short_Integer_To_XDR_S_SSI
(Item
);
1769 -- Test sign and apply two complement's notation
1772 then XDR_SSU
'Last xor XDR_SSU
(-(Item
+ 1))
1773 else XDR_SSU
(Item
));
1778 Ada
.Streams
.Write
(Stream
.all, S
);
1786 (Stream
: not null access RST
;
1787 Item
: Short_Short_Unsigned
)
1789 U
: constant XDR_SSU
:= XDR_SSU
(Item
);
1794 Ada
.Streams
.Write
(Stream
.all, S
);
1801 procedure W_SU
(Stream
: not null access RST
; Item
: Short_Unsigned
) is
1803 U
: XDR_SU
:= XDR_SU
(Item
);
1806 if Optimize_Integers
then
1807 S
:= Short_Unsigned_To_XDR_S_SU
(Item
);
1810 for N
in reverse S
'Range loop
1811 S
(N
) := SE
(U
mod BB
);
1820 Ada
.Streams
.Write
(Stream
.all, S
);
1827 procedure W_U
(Stream
: not null access RST
; Item
: Unsigned
) is
1829 U
: XDR_U
:= XDR_U
(Item
);
1832 if Optimize_Integers
then
1833 S
:= Unsigned_To_XDR_S_U
(Item
);
1836 for N
in reverse S
'Range loop
1837 S
(N
) := SE
(U
mod BB
);
1846 Ada
.Streams
.Write
(Stream
.all, S
);
1853 procedure W_WC
(Stream
: not null access RST
; Item
: Wide_Character) is
1858 -- Use Ada requirements on Wide_Character representation clause
1860 U
:= XDR_WC
(Wide_Character'Pos (Item
));
1862 for N
in reverse S
'Range loop
1863 S
(N
) := SE
(U
mod BB
);
1867 Ada
.Streams
.Write
(Stream
.all, S
);
1879 (Stream
: not null access RST
; Item
: Wide_Wide_Character
)
1885 -- Use Ada requirements on Wide_Wide_Character representation clause
1887 U
:= XDR_WWC
(Wide_Wide_Character
'Pos (Item
));
1889 for N
in reverse S
'Range loop
1890 S
(N
) := SE
(U
mod BB
);
1894 Ada
.Streams
.Write
(Stream
.all, S
);
1901 end System
.Stream_Attributes
;