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-2008, 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, 51 Franklin Street, Fifth --
20 -- Floor, Boston, MA 02110-1301, 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 endianness.
38 with Ada
.IO_Exceptions
;
39 with Ada
.Streams
; use Ada
.Streams
;
40 with Ada
.Unchecked_Conversion
;
42 package body System
.Stream_Attributes
is
44 pragma Suppress
(Range_Check
);
45 pragma Suppress
(Overflow_Check
);
49 Data_Error
: exception renames Ada
.IO_Exceptions
.End_Error
;
50 -- Exception raised if insufficient data read (End_Error is
51 -- mandated by AI95-00132).
53 SU
: constant := System
.Storage_Unit
;
54 -- XXXXX pragma Assert (SU = 8);
56 BB
: constant := 2 ** SU
; -- Byte base
57 BL
: constant := 2 ** SU
- 1; -- Byte last
58 BS
: constant := 2 ** (SU
- 1); -- Byte sign
60 US
: constant := Unsigned
'Size; -- Unsigned size
61 UB
: constant := (US
- 1) / SU
+ 1; -- Unsigned byte
62 UL
: constant := 2 ** US
- 1; -- Unsigned last
64 subtype SE
is Ada
.Streams
.Stream_Element
;
65 subtype SEA
is Ada
.Streams
.Stream_Element_Array
;
66 subtype SEO
is Ada
.Streams
.Stream_Element_Offset
;
68 generic function UC
renames Ada
.Unchecked_Conversion
;
72 E_Size
: Integer; -- Exponent bit size
73 E_Bias
: Integer; -- Exponent bias
74 F_Size
: Integer; -- Fraction bit size
75 E_Last
: Integer; -- Max exponent value
76 F_Mask
: SE
; -- Mask to apply on first fraction byte
77 E_Bytes
: SEO
; -- N. of exponent bytes completely used
78 F_Bytes
: SEO
; -- N. of fraction bytes completely used
79 F_Bits
: Integer; -- N. of bits used on first fraction word
82 type Precision
is (Single
, Double
, Quadruple
);
84 Fields
: constant array (Precision
) of Field_Type
:= (
92 F_Mask
=> 16#
7F#
, -- 2 ** 7 - 1,
102 E_Last
=> 2 ** 11 - 1,
103 F_Mask
=> 16#
0F#
, -- 2 ** 4 - 1,
106 F_Bits
=> 52 mod US
),
108 -- Quadruple precision
113 E_Last
=> 2 ** 8 - 1,
114 F_Mask
=> 16#FF#
, -- 2 ** 8 - 1,
117 F_Bits
=> 112 mod US
));
119 -- The representation of all items requires a multiple of four bytes
120 -- (or 32 bits) of data. The bytes are numbered 0 through n-1. The bytes
121 -- are read or written to some byte stream such that byte m always
122 -- precedes byte m+1. If the n bytes needed to contain the data are not
123 -- a multiple of four, then the n bytes are followed by enough (0 to 3)
124 -- residual zero bytes, r, to make the total byte count a multiple of 4.
126 -- An XDR signed integer is a 32-bit datum that encodes an integer
127 -- in the range [-2147483648,2147483647]. The integer is represented
128 -- in two's complement notation. The most and least significant bytes
129 -- are 0 and 3, respectively. Integers are declared as follows:
132 -- +-------+-------+-------+-------+
133 -- |byte 0 |byte 1 |byte 2 |byte 3 |
134 -- +-------+-------+-------+-------+
135 -- <------------32 bits------------>
137 SSI_L
: constant := 1;
138 SI_L
: constant := 2;
140 LI_L
: constant := 8;
141 LLI_L
: constant := 8;
143 subtype XDR_S_SSI
is SEA
(1 .. SSI_L
);
144 subtype XDR_S_SI
is SEA
(1 .. SI_L
);
145 subtype XDR_S_I
is SEA
(1 .. I_L
);
146 subtype XDR_S_LI
is SEA
(1 .. LI_L
);
147 subtype XDR_S_LLI
is SEA
(1 .. LLI_L
);
149 function Short_Short_Integer_To_XDR_S_SSI
is
150 new Ada
.Unchecked_Conversion
(Short_Short_Integer, XDR_S_SSI
);
151 function XDR_S_SSI_To_Short_Short_Integer
is
152 new Ada
.Unchecked_Conversion
(XDR_S_SSI
, Short_Short_Integer);
154 function Short_Integer_To_XDR_S_SI
is
155 new Ada
.Unchecked_Conversion
(Short_Integer, XDR_S_SI
);
156 function XDR_S_SI_To_Short_Integer
is
157 new Ada
.Unchecked_Conversion
(XDR_S_SI
, Short_Integer);
159 function Integer_To_XDR_S_I
is
160 new Ada
.Unchecked_Conversion
(Integer, XDR_S_I
);
161 function XDR_S_I_To_Integer
is
162 new Ada
.Unchecked_Conversion
(XDR_S_I
, Integer);
164 function Long_Long_Integer_To_XDR_S_LI
is
165 new Ada
.Unchecked_Conversion
(Long_Long_Integer, XDR_S_LI
);
166 function XDR_S_LI_To_Long_Long_Integer
is
167 new Ada
.Unchecked_Conversion
(XDR_S_LI
, Long_Long_Integer);
169 function Long_Long_Integer_To_XDR_S_LLI
is
170 new Ada
.Unchecked_Conversion
(Long_Long_Integer, XDR_S_LLI
);
171 function XDR_S_LLI_To_Long_Long_Integer
is
172 new Ada
.Unchecked_Conversion
(XDR_S_LLI
, Long_Long_Integer);
174 -- An XDR unsigned integer is a 32-bit datum that encodes a nonnegative
175 -- integer in the range [0,4294967295]. It is represented by an unsigned
176 -- binary number whose most and least significant bytes are 0 and 3,
177 -- respectively. An unsigned integer is declared as follows:
180 -- +-------+-------+-------+-------+
181 -- |byte 0 |byte 1 |byte 2 |byte 3 |
182 -- +-------+-------+-------+-------+
183 -- <------------32 bits------------>
185 SSU_L
: constant := 1;
186 SU_L
: constant := 2;
188 LU_L
: constant := 8;
189 LLU_L
: constant := 8;
191 subtype XDR_S_SSU
is SEA
(1 .. SSU_L
);
192 subtype XDR_S_SU
is SEA
(1 .. SU_L
);
193 subtype XDR_S_U
is SEA
(1 .. U_L
);
194 subtype XDR_S_LU
is SEA
(1 .. LU_L
);
195 subtype XDR_S_LLU
is SEA
(1 .. LLU_L
);
197 type XDR_SSU
is mod BB
** SSU_L
;
198 type XDR_SU
is mod BB
** SU_L
;
199 type XDR_U
is mod BB
** U_L
;
201 function Short_Unsigned_To_XDR_S_SU
is
202 new Ada
.Unchecked_Conversion
(Short_Unsigned
, XDR_S_SU
);
203 function XDR_S_SU_To_Short_Unsigned
is
204 new Ada
.Unchecked_Conversion
(XDR_S_SU
, Short_Unsigned
);
206 function Unsigned_To_XDR_S_U
is
207 new Ada
.Unchecked_Conversion
(Unsigned
, XDR_S_U
);
208 function XDR_S_U_To_Unsigned
is
209 new Ada
.Unchecked_Conversion
(XDR_S_U
, Unsigned
);
211 function Long_Long_Unsigned_To_XDR_S_LU
is
212 new Ada
.Unchecked_Conversion
(Long_Long_Unsigned
, XDR_S_LU
);
213 function XDR_S_LU_To_Long_Long_Unsigned
is
214 new Ada
.Unchecked_Conversion
(XDR_S_LU
, Long_Long_Unsigned
);
216 function Long_Long_Unsigned_To_XDR_S_LLU
is
217 new Ada
.Unchecked_Conversion
(Long_Long_Unsigned
, XDR_S_LLU
);
218 function XDR_S_LLU_To_Long_Long_Unsigned
is
219 new Ada
.Unchecked_Conversion
(XDR_S_LLU
, Long_Long_Unsigned
);
221 -- The standard defines the floating-point data type "float" (32 bits
222 -- or 4 bytes). The encoding used is the IEEE standard for normalized
223 -- single-precision floating-point numbers.
225 -- The standard defines the encoding for the double-precision
226 -- floating-point data type "double" (64 bits or 8 bytes). The
227 -- encoding used is the IEEE standard for normalized double-precision
228 -- floating-point numbers.
230 SF_L
: constant := 4; -- Single precision
231 F_L
: constant := 4; -- Single precision
232 LF_L
: constant := 8; -- Double precision
233 LLF_L
: constant := 16; -- Quadruple precision
235 TM_L
: constant := 8;
236 subtype XDR_S_TM
is SEA
(1 .. TM_L
);
237 type XDR_TM
is mod BB
** TM_L
;
239 type XDR_SA
is mod 2 ** Standard
'Address_Size;
240 function To_XDR_SA
is new UC
(System
.Address
, XDR_SA
);
241 function To_XDR_SA
is new UC
(XDR_SA
, System
.Address
);
243 -- Enumerations have the same representation as signed integers.
244 -- Enumerations are handy for describing subsets of the integers.
246 -- Booleans are important enough and occur frequently enough to warrant
247 -- their own explicit type in the standard. Booleans are declared as
248 -- an enumeration, with FALSE = 0 and TRUE = 1.
250 -- The standard defines a string of n (numbered 0 through n-1) ASCII
251 -- bytes to be the number n encoded as an unsigned integer (as described
252 -- above), and followed by the n bytes of the string. Byte m of the string
253 -- always precedes byte m+1 of the string, and byte 0 of the string always
254 -- follows the string's length. If n is not a multiple of four, then the
255 -- n bytes are followed by enough (0 to 3) residual zero bytes, r, to make
256 -- the total byte count a multiple of four.
258 -- To fit with XDR string, do not consider character as an enumeration
262 subtype XDR_S_C
is SEA
(1 .. C_L
);
264 -- Consider Wide_Character as an enumeration type
266 WC_L
: constant := 4;
267 subtype XDR_S_WC
is SEA
(1 .. WC_L
);
268 type XDR_WC
is mod BB
** WC_L
;
270 -- Consider Wide_Wide_Character as an enumeration type
272 WWC_L
: constant := 8;
273 subtype XDR_S_WWC
is SEA
(1 .. WWC_L
);
274 type XDR_WWC
is mod BB
** WWC_L
;
276 -- Optimization: if we already have the correct Bit_Order, then some
277 -- computations can be avoided since the source and the target will be
278 -- identical anyway. They will be replaced by direct unchecked
281 Optimize_Integers
: constant Boolean :=
282 Default_Bit_Order
= High_Order_First
;
288 function Block_IO_OK
return Boolean is
297 function I_AD
(Stream
: not null access RST
) return Fat_Pointer
is
301 FP
.P1
:= I_AS
(Stream
).P1
;
302 FP
.P2
:= I_AS
(Stream
).P1
;
311 function I_AS
(Stream
: not null access RST
) return Thin_Pointer
is
317 Ada
.Streams
.Read
(Stream
.all, S
, L
);
323 for N
in S
'Range loop
324 U
:= U
* BB
+ XDR_TM
(S
(N
));
327 return (P1
=> To_XDR_SA
(XDR_SA
(U
)));
335 function I_B
(Stream
: not null access RST
) return Boolean is
337 case I_SSU
(Stream
) is
338 when 0 => return False;
339 when 1 => return True;
340 when others => raise Data_Error
;
348 function I_C
(Stream
: not null access RST
) return Character is
353 Ada
.Streams
.Read
(Stream
.all, S
, L
);
359 -- Use Ada requirements on Character representation clause
361 return Character'Val (S
(1));
369 function I_F
(Stream
: not null access RST
) return Float is
370 I
: constant Precision
:= Single
;
371 E_Size
: Integer renames Fields
(I
).E_Size
;
372 E_Bias
: Integer renames Fields
(I
).E_Bias
;
373 E_Last
: Integer renames Fields
(I
).E_Last
;
374 F_Mask
: SE
renames Fields
(I
).F_Mask
;
375 E_Bytes
: SEO
renames Fields
(I
).E_Bytes
;
376 F_Bytes
: SEO
renames Fields
(I
).F_Bytes
;
377 F_Size
: Integer renames Fields
(I
).F_Size
;
380 Exponent
: Long_Unsigned
;
381 Fraction
: Long_Unsigned
;
387 Ada
.Streams
.Read
(Stream
.all, S
, L
);
393 -- Extract Fraction, Sign and Exponent
395 Fraction
:= Long_Unsigned
(S
(F_L
+ 1 - F_Bytes
) and F_Mask
);
396 for N
in F_L
+ 2 - F_Bytes
.. F_L
loop
397 Fraction
:= Fraction
* BB
+ Long_Unsigned
(S
(N
));
399 Result
:= Float'Scaling (Float (Fraction
), -F_Size
);
403 Exponent
:= Long_Unsigned
(S
(1) - BS
);
406 Exponent
:= Long_Unsigned
(S
(1));
409 for N
in 2 .. E_Bytes
loop
410 Exponent
:= Exponent
* BB
+ Long_Unsigned
(S
(N
));
412 Exponent
:= Shift_Right
(Exponent
, Integer (E_Bytes
) * SU
- E_Size
- 1);
416 if Integer (Exponent
) = E_Last
then
417 raise Constraint_Error
;
419 elsif Exponent
= 0 then
426 -- Denormalized float
429 Result
:= Float'Scaling (Result
, 1 - E_Bias
);
435 Result
:= Float'Scaling
436 (1.0 + Result
, Integer (Exponent
) - E_Bias
);
450 function I_I
(Stream
: not null access RST
) return Integer is
456 Ada
.Streams
.Read
(Stream
.all, S
, L
);
461 elsif Optimize_Integers
then
462 return XDR_S_I_To_Integer
(S
);
465 for N
in S
'Range loop
466 U
:= U
* BB
+ XDR_U
(S
(N
));
469 -- Test sign and apply two complement notation
475 return Integer (-((XDR_U
'Last xor U
) + 1));
484 function I_LF
(Stream
: not null access RST
) return Long_Float is
485 I
: constant Precision
:= Double
;
486 E_Size
: Integer renames Fields
(I
).E_Size
;
487 E_Bias
: Integer renames Fields
(I
).E_Bias
;
488 E_Last
: Integer renames Fields
(I
).E_Last
;
489 F_Mask
: SE
renames Fields
(I
).F_Mask
;
490 E_Bytes
: SEO
renames Fields
(I
).E_Bytes
;
491 F_Bytes
: SEO
renames Fields
(I
).F_Bytes
;
492 F_Size
: Integer renames Fields
(I
).F_Size
;
495 Exponent
: Long_Unsigned
;
496 Fraction
: Long_Long_Unsigned
;
502 Ada
.Streams
.Read
(Stream
.all, S
, L
);
508 -- Extract Fraction, Sign and Exponent
510 Fraction
:= Long_Long_Unsigned
(S
(LF_L
+ 1 - F_Bytes
) and F_Mask
);
511 for N
in LF_L
+ 2 - F_Bytes
.. LF_L
loop
512 Fraction
:= Fraction
* BB
+ Long_Long_Unsigned
(S
(N
));
515 Result
:= Long_Float'Scaling (Long_Float (Fraction
), -F_Size
);
519 Exponent
:= Long_Unsigned
(S
(1) - BS
);
522 Exponent
:= Long_Unsigned
(S
(1));
525 for N
in 2 .. E_Bytes
loop
526 Exponent
:= Exponent
* BB
+ Long_Unsigned
(S
(N
));
529 Exponent
:= Shift_Right
(Exponent
, Integer (E_Bytes
) * SU
- E_Size
- 1);
533 if Integer (Exponent
) = E_Last
then
534 raise Constraint_Error
;
536 elsif Exponent
= 0 then
543 -- Denormalized float
546 Result
:= Long_Float'Scaling (Result
, 1 - E_Bias
);
552 Result
:= Long_Float'Scaling
553 (1.0 + Result
, Integer (Exponent
) - E_Bias
);
567 function I_LI
(Stream
: not null access RST
) return Long_Integer is
571 X
: Long_Unsigned
:= 0;
574 Ada
.Streams
.Read
(Stream
.all, S
, L
);
579 elsif Optimize_Integers
then
580 return Long_Integer (XDR_S_LI_To_Long_Long_Integer
(S
));
584 -- Compute using machine unsigned
585 -- rather than long_long_unsigned
587 for N
in S
'Range loop
588 U
:= U
* BB
+ Unsigned
(S
(N
));
590 -- We have filled an unsigned
593 X
:= Shift_Left
(X
, US
) + Long_Unsigned
(U
);
598 -- Test sign and apply two complement notation
601 return Long_Integer (X
);
603 return Long_Integer (-((Long_Unsigned
'Last xor X
) + 1));
613 function I_LLF
(Stream
: not null access RST
) return Long_Long_Float is
614 I
: constant Precision
:= Quadruple
;
615 E_Size
: Integer renames Fields
(I
).E_Size
;
616 E_Bias
: Integer renames Fields
(I
).E_Bias
;
617 E_Last
: Integer renames Fields
(I
).E_Last
;
618 E_Bytes
: SEO
renames Fields
(I
).E_Bytes
;
619 F_Bytes
: SEO
renames Fields
(I
).F_Bytes
;
620 F_Size
: Integer renames Fields
(I
).F_Size
;
623 Exponent
: Long_Unsigned
;
624 Fraction_1
: Long_Long_Unsigned
:= 0;
625 Fraction_2
: Long_Long_Unsigned
:= 0;
626 Result
: Long_Long_Float;
627 HF
: constant Natural := F_Size
/ 2;
628 S
: SEA
(1 .. LLF_L
);
632 Ada
.Streams
.Read
(Stream
.all, S
, L
);
638 -- Extract Fraction, Sign and Exponent
640 for I
in LLF_L
- F_Bytes
+ 1 .. LLF_L
- 7 loop
641 Fraction_1
:= Fraction_1
* BB
+ Long_Long_Unsigned
(S
(I
));
644 for I
in SEO
(LLF_L
- 6) .. SEO
(LLF_L
) loop
645 Fraction_2
:= Fraction_2
* BB
+ Long_Long_Unsigned
(S
(I
));
648 Result
:= Long_Long_Float'Scaling (Long_Long_Float (Fraction_2
), -HF
);
649 Result
:= Long_Long_Float (Fraction_1
) + Result
;
650 Result
:= Long_Long_Float'Scaling (Result
, HF
- F_Size
);
654 Exponent
:= Long_Unsigned
(S
(1) - BS
);
657 Exponent
:= Long_Unsigned
(S
(1));
660 for N
in 2 .. E_Bytes
loop
661 Exponent
:= Exponent
* BB
+ Long_Unsigned
(S
(N
));
664 Exponent
:= Shift_Right
(Exponent
, Integer (E_Bytes
) * SU
- E_Size
- 1);
668 if Integer (Exponent
) = E_Last
then
669 raise Constraint_Error
;
671 elsif Exponent
= 0 then
675 if Fraction_1
= 0 and then Fraction_2
= 0 then
678 -- Denormalized float
681 Result
:= Long_Long_Float'Scaling (Result
, 1 - E_Bias
);
687 Result
:= Long_Long_Float'Scaling
688 (1.0 + Result
, Integer (Exponent
) - E_Bias
);
702 function I_LLI
(Stream
: not null access RST
) return Long_Long_Integer is
706 X
: Long_Long_Unsigned
:= 0;
709 Ada
.Streams
.Read
(Stream
.all, S
, L
);
714 elsif Optimize_Integers
then
715 return XDR_S_LLI_To_Long_Long_Integer
(S
);
718 -- Compute using machine unsigned for computing
719 -- rather than long_long_unsigned.
721 for N
in S
'Range loop
722 U
:= U
* BB
+ Unsigned
(S
(N
));
724 -- We have filled an unsigned
727 X
:= Shift_Left
(X
, US
) + Long_Long_Unsigned
(U
);
732 -- Test sign and apply two complement notation
735 return Long_Long_Integer (X
);
737 return Long_Long_Integer (-((Long_Long_Unsigned
'Last xor X
) + 1));
746 function I_LLU
(Stream
: not null access RST
) return Long_Long_Unsigned
is
750 X
: Long_Long_Unsigned
:= 0;
753 Ada
.Streams
.Read
(Stream
.all, S
, L
);
758 elsif Optimize_Integers
then
759 return XDR_S_LLU_To_Long_Long_Unsigned
(S
);
762 -- Compute using machine unsigned
763 -- rather than long_long_unsigned.
765 for N
in S
'Range loop
766 U
:= U
* BB
+ Unsigned
(S
(N
));
768 -- We have filled an unsigned
771 X
:= Shift_Left
(X
, US
) + Long_Long_Unsigned
(U
);
784 function I_LU
(Stream
: not null access RST
) return Long_Unsigned
is
788 X
: Long_Unsigned
:= 0;
791 Ada
.Streams
.Read
(Stream
.all, S
, L
);
796 elsif Optimize_Integers
then
797 return Long_Unsigned
(XDR_S_LU_To_Long_Long_Unsigned
(S
));
800 -- Compute using machine unsigned
801 -- rather than long_unsigned.
803 for N
in S
'Range loop
804 U
:= U
* BB
+ Unsigned
(S
(N
));
806 -- We have filled an unsigned
809 X
:= Shift_Left
(X
, US
) + Long_Unsigned
(U
);
822 function I_SF
(Stream
: not null access RST
) return Short_Float is
823 I
: constant Precision
:= Single
;
824 E_Size
: Integer renames Fields
(I
).E_Size
;
825 E_Bias
: Integer renames Fields
(I
).E_Bias
;
826 E_Last
: Integer renames Fields
(I
).E_Last
;
827 F_Mask
: SE
renames Fields
(I
).F_Mask
;
828 E_Bytes
: SEO
renames Fields
(I
).E_Bytes
;
829 F_Bytes
: SEO
renames Fields
(I
).F_Bytes
;
830 F_Size
: Integer renames Fields
(I
).F_Size
;
832 Exponent
: Long_Unsigned
;
833 Fraction
: Long_Unsigned
;
835 Result
: Short_Float;
840 Ada
.Streams
.Read
(Stream
.all, S
, L
);
846 -- Extract Fraction, Sign and Exponent
848 Fraction
:= Long_Unsigned
(S
(SF_L
+ 1 - F_Bytes
) and F_Mask
);
849 for N
in SF_L
+ 2 - F_Bytes
.. SF_L
loop
850 Fraction
:= Fraction
* BB
+ Long_Unsigned
(S
(N
));
852 Result
:= Short_Float'Scaling (Short_Float (Fraction
), -F_Size
);
856 Exponent
:= Long_Unsigned
(S
(1) - BS
);
859 Exponent
:= Long_Unsigned
(S
(1));
862 for N
in 2 .. E_Bytes
loop
863 Exponent
:= Exponent
* BB
+ Long_Unsigned
(S
(N
));
865 Exponent
:= Shift_Right
(Exponent
, Integer (E_Bytes
) * SU
- E_Size
- 1);
869 if Integer (Exponent
) = E_Last
then
870 raise Constraint_Error
;
872 elsif Exponent
= 0 then
879 -- Denormalized float
882 Result
:= Short_Float'Scaling (Result
, 1 - E_Bias
);
888 Result
:= Short_Float'Scaling
889 (1.0 + Result
, Integer (Exponent
) - E_Bias
);
903 function I_SI
(Stream
: not null access RST
) return Short_Integer is
909 Ada
.Streams
.Read
(Stream
.all, S
, L
);
914 elsif Optimize_Integers
then
915 return XDR_S_SI_To_Short_Integer
(S
);
918 for N
in S
'Range loop
919 U
:= U
* BB
+ XDR_SU
(S
(N
));
922 -- Test sign and apply two complement notation
925 return Short_Integer (U
);
927 return Short_Integer (-((XDR_SU
'Last xor U
) + 1));
936 function I_SSI
(Stream
: not null access RST
) return Short_Short_Integer is
942 Ada
.Streams
.Read
(Stream
.all, S
, L
);
947 elsif Optimize_Integers
then
948 return XDR_S_SSI_To_Short_Short_Integer
(S
);
951 U
:= XDR_SSU
(S
(1));
953 -- Test sign and apply two complement notation
956 return Short_Short_Integer (U
);
958 return Short_Short_Integer (-((XDR_SSU
'Last xor U
) + 1));
967 function I_SSU
(Stream
: not null access RST
) return Short_Short_Unsigned
is
973 Ada
.Streams
.Read
(Stream
.all, S
, L
);
979 U
:= XDR_SSU
(S
(1));
980 return Short_Short_Unsigned
(U
);
988 function I_SU
(Stream
: not null access RST
) return Short_Unsigned
is
994 Ada
.Streams
.Read
(Stream
.all, S
, L
);
999 elsif Optimize_Integers
then
1000 return XDR_S_SU_To_Short_Unsigned
(S
);
1003 for N
in S
'Range loop
1004 U
:= U
* BB
+ XDR_SU
(S
(N
));
1007 return Short_Unsigned
(U
);
1015 function I_U
(Stream
: not null access RST
) return Unsigned
is
1021 Ada
.Streams
.Read
(Stream
.all, S
, L
);
1026 elsif Optimize_Integers
then
1027 return XDR_S_U_To_Unsigned
(S
);
1030 for N
in S
'Range loop
1031 U
:= U
* BB
+ XDR_U
(S
(N
));
1034 return Unsigned
(U
);
1042 function I_WC
(Stream
: not null access RST
) return Wide_Character is
1048 Ada
.Streams
.Read
(Stream
.all, S
, L
);
1054 for N
in S
'Range loop
1055 U
:= U
* BB
+ XDR_WC
(S
(N
));
1058 -- Use Ada requirements on Wide_Character representation clause
1060 return Wide_Character'Val (U
);
1068 function I_WWC
(Stream
: not null access RST
) return Wide_Wide_Character
is
1074 Ada
.Streams
.Read
(Stream
.all, S
, L
);
1080 for N
in S
'Range loop
1081 U
:= U
* BB
+ XDR_WWC
(S
(N
));
1084 -- Use Ada requirements on Wide_Wide_Character representation clause
1086 return Wide_Wide_Character
'Val (U
);
1094 procedure W_AD
(Stream
: not null access RST
; Item
: Fat_Pointer
) is
1099 U
:= XDR_TM
(To_XDR_SA
(Item
.P1
));
1100 for N
in reverse S
'Range loop
1101 S
(N
) := SE
(U
mod BB
);
1105 Ada
.Streams
.Write
(Stream
.all, S
);
1107 U
:= XDR_TM
(To_XDR_SA
(Item
.P2
));
1108 for N
in reverse S
'Range loop
1109 S
(N
) := SE
(U
mod BB
);
1113 Ada
.Streams
.Write
(Stream
.all, S
);
1124 procedure W_AS
(Stream
: not null access RST
; Item
: Thin_Pointer
) is
1126 U
: XDR_TM
:= XDR_TM
(To_XDR_SA
(Item
.P1
));
1129 for N
in reverse S
'Range loop
1130 S
(N
) := SE
(U
mod BB
);
1134 Ada
.Streams
.Write
(Stream
.all, S
);
1145 procedure W_B
(Stream
: not null access RST
; Item
: Boolean) is
1158 procedure W_C
(Stream
: not null access RST
; Item
: Character) is
1161 pragma Assert
(C_L
= 1);
1164 -- Use Ada requirements on Character representation clause
1166 S
(1) := SE
(Character'Pos (Item
));
1168 Ada
.Streams
.Write
(Stream
.all, S
);
1175 procedure W_F
(Stream
: not null access RST
; Item
: Float) is
1176 I
: constant Precision
:= Single
;
1177 E_Size
: Integer renames Fields
(I
).E_Size
;
1178 E_Bias
: Integer renames Fields
(I
).E_Bias
;
1179 E_Bytes
: SEO
renames Fields
(I
).E_Bytes
;
1180 F_Bytes
: SEO
renames Fields
(I
).F_Bytes
;
1181 F_Size
: Integer renames Fields
(I
).F_Size
;
1182 F_Mask
: SE
renames Fields
(I
).F_Mask
;
1184 Exponent
: Long_Unsigned
;
1185 Fraction
: Long_Unsigned
;
1189 S
: SEA
(1 .. F_L
) := (others => 0);
1192 if not Item
'Valid then
1193 raise Constraint_Error
;
1198 Positive := (0.0 <= Item
);
1208 E
:= Float'Exponent (F
) - 1;
1210 -- Denormalized float
1212 if E
<= -E_Bias
then
1213 F
:= Float'Scaling (F
, F_Size
+ E_Bias
- 1);
1216 F
:= Float'Scaling (Float'Fraction (F
), F_Size
+ 1);
1219 -- Compute Exponent and Fraction
1221 Exponent
:= Long_Unsigned
(E
+ E_Bias
);
1222 Fraction
:= Long_Unsigned
(F
* 2.0) / 2;
1227 for I
in reverse F_L
- F_Bytes
+ 1 .. F_L
loop
1228 S
(I
) := SE
(Fraction
mod BB
);
1229 Fraction
:= Fraction
/ BB
;
1232 -- Remove implicit bit
1234 S
(F_L
- F_Bytes
+ 1) := S
(F_L
- F_Bytes
+ 1) and F_Mask
;
1236 -- Store Exponent (not always at the beginning of a byte)
1238 Exponent
:= Shift_Left
(Exponent
, Integer (E_Bytes
) * SU
- E_Size
- 1);
1239 for N
in reverse 1 .. E_Bytes
loop
1240 S
(N
) := SE
(Exponent
mod BB
) + S
(N
);
1241 Exponent
:= Exponent
/ BB
;
1246 if not Positive then
1247 S
(1) := S
(1) + BS
;
1250 Ada
.Streams
.Write
(Stream
.all, S
);
1257 procedure W_I
(Stream
: not null access RST
; Item
: Integer) is
1262 if Optimize_Integers
then
1263 S
:= Integer_To_XDR_S_I
(Item
);
1266 -- Test sign and apply two complement notation
1269 U
:= 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
;
1305 S
: SEA
(1 .. LF_L
) := (others => 0);
1308 if not Item
'Valid then
1309 raise Constraint_Error
;
1314 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 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
1392 -- rather than long_unsigned.
1394 for N
in reverse S
'Range loop
1396 -- We have filled an unsigned
1398 if (LU_L
- N
) mod UB
= 0 then
1399 U
:= Unsigned
(X
and UL
);
1400 X
:= Shift_Right
(X
, US
);
1403 S
(N
) := SE
(U
mod BB
);
1412 Ada
.Streams
.Write
(Stream
.all, S
);
1419 procedure W_LLF
(Stream
: not null access RST
; Item
: Long_Long_Float) is
1420 I
: constant Precision
:= Quadruple
;
1421 E_Size
: Integer renames Fields
(I
).E_Size
;
1422 E_Bias
: Integer renames Fields
(I
).E_Bias
;
1423 E_Bytes
: SEO
renames Fields
(I
).E_Bytes
;
1424 F_Bytes
: SEO
renames Fields
(I
).F_Bytes
;
1425 F_Size
: Integer renames Fields
(I
).F_Size
;
1427 HFS
: constant Integer := F_Size
/ 2;
1429 Exponent
: Long_Unsigned
;
1430 Fraction_1
: Long_Long_Unsigned
;
1431 Fraction_2
: Long_Long_Unsigned
;
1434 F
: Long_Long_Float := Item
;
1435 S
: SEA
(1 .. LLF_L
) := (others => 0);
1438 if not Item
'Valid then
1439 raise Constraint_Error
;
1444 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
:= Long_Long_Float (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 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
1536 -- rather than long_long_unsigned.
1538 for N
in reverse S
'Range loop
1540 -- We have filled an unsigned
1542 if (LLU_L
- N
) mod UB
= 0 then
1543 U
:= Unsigned
(X
and UL
);
1544 X
:= Shift_Right
(X
, US
);
1547 S
(N
) := SE
(U
mod BB
);
1556 Ada
.Streams
.Write
(Stream
.all, S
);
1564 (Stream
: not null access RST
;
1565 Item
: Long_Long_Unsigned
)
1569 X
: Long_Long_Unsigned
:= Item
;
1572 if Optimize_Integers
then
1573 S
:= Long_Long_Unsigned_To_XDR_S_LLU
(Item
);
1576 -- Compute using machine unsigned
1577 -- rather than long_long_unsigned.
1579 for N
in reverse S
'Range loop
1581 -- We have filled an unsigned
1583 if (LLU_L
- N
) mod UB
= 0 then
1584 U
:= Unsigned
(X
and UL
);
1585 X
:= Shift_Right
(X
, US
);
1588 S
(N
) := SE
(U
mod BB
);
1597 Ada
.Streams
.Write
(Stream
.all, S
);
1604 procedure W_LU
(Stream
: not null access RST
; Item
: Long_Unsigned
) is
1607 X
: Long_Unsigned
:= Item
;
1610 if Optimize_Integers
then
1611 S
:= Long_Long_Unsigned_To_XDR_S_LU
(Long_Long_Unsigned
(Item
));
1614 -- Compute using machine unsigned
1615 -- rather than long_unsigned.
1617 for N
in reverse S
'Range loop
1619 -- We have filled an unsigned
1621 if (LU_L
- N
) mod UB
= 0 then
1622 U
:= Unsigned
(X
and UL
);
1623 X
:= Shift_Right
(X
, US
);
1625 S
(N
) := SE
(U
mod BB
);
1634 Ada
.Streams
.Write
(Stream
.all, S
);
1641 procedure W_SF
(Stream
: not null access RST
; Item
: Short_Float) is
1642 I
: constant Precision
:= Single
;
1643 E_Size
: Integer renames Fields
(I
).E_Size
;
1644 E_Bias
: Integer renames Fields
(I
).E_Bias
;
1645 E_Bytes
: SEO
renames Fields
(I
).E_Bytes
;
1646 F_Bytes
: SEO
renames Fields
(I
).F_Bytes
;
1647 F_Size
: Integer renames Fields
(I
).F_Size
;
1648 F_Mask
: SE
renames Fields
(I
).F_Mask
;
1650 Exponent
: Long_Unsigned
;
1651 Fraction
: Long_Unsigned
;
1655 S
: SEA
(1 .. SF_L
) := (others => 0);
1658 if not Item
'Valid then
1659 raise Constraint_Error
;
1664 Positive := (0.0 <= Item
);
1674 E
:= Short_Float'Exponent (F
) - 1;
1676 -- Denormalized float
1678 if E
<= -E_Bias
then
1680 F
:= Short_Float'Scaling (F
, F_Size
+ E_Bias
- 1);
1682 F
:= Short_Float'Scaling (F
, F_Size
- E
);
1685 -- Compute Exponent and Fraction
1687 Exponent
:= Long_Unsigned
(E
+ E_Bias
);
1688 Fraction
:= Long_Unsigned
(F
* 2.0) / 2;
1693 for I
in reverse SF_L
- F_Bytes
+ 1 .. SF_L
loop
1694 S
(I
) := SE
(Fraction
mod BB
);
1695 Fraction
:= Fraction
/ BB
;
1698 -- Remove implicit bit
1700 S
(SF_L
- F_Bytes
+ 1) := S
(SF_L
- F_Bytes
+ 1) and F_Mask
;
1702 -- Store Exponent (not always at the beginning of a byte)
1704 Exponent
:= Shift_Left
(Exponent
, Integer (E_Bytes
) * SU
- E_Size
- 1);
1705 for N
in reverse 1 .. E_Bytes
loop
1706 S
(N
) := SE
(Exponent
mod BB
) + S
(N
);
1707 Exponent
:= Exponent
/ BB
;
1712 if not Positive then
1713 S
(1) := S
(1) + BS
;
1716 Ada
.Streams
.Write
(Stream
.all, S
);
1723 procedure W_SI
(Stream
: not null access RST
; Item
: Short_Integer) is
1728 if Optimize_Integers
then
1729 S
:= Short_Integer_To_XDR_S_SI
(Item
);
1732 -- Test sign and apply two complement's notation
1735 U
:= XDR_SU
'Last xor XDR_SU
(-(Item
+ 1));
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 U
:= XDR_SSU
'Last xor XDR_SSU
(-(Item
+ 1));
1774 U
:= XDR_SSU
(Item
);
1780 Ada
.Streams
.Write
(Stream
.all, S
);
1788 (Stream
: not null access RST
;
1789 Item
: Short_Short_Unsigned
)
1791 U
: constant XDR_SSU
:= XDR_SSU
(Item
);
1796 Ada
.Streams
.Write
(Stream
.all, S
);
1803 procedure W_SU
(Stream
: not null access RST
; Item
: Short_Unsigned
) is
1805 U
: XDR_SU
:= XDR_SU
(Item
);
1808 if Optimize_Integers
then
1809 S
:= Short_Unsigned_To_XDR_S_SU
(Item
);
1812 for N
in reverse S
'Range loop
1813 S
(N
) := SE
(U
mod BB
);
1822 Ada
.Streams
.Write
(Stream
.all, S
);
1829 procedure W_U
(Stream
: not null access RST
; Item
: Unsigned
) is
1831 U
: XDR_U
:= XDR_U
(Item
);
1834 if Optimize_Integers
then
1835 S
:= Unsigned_To_XDR_S_U
(Item
);
1838 for N
in reverse S
'Range loop
1839 S
(N
) := SE
(U
mod BB
);
1848 Ada
.Streams
.Write
(Stream
.all, S
);
1855 procedure W_WC
(Stream
: not null access RST
; Item
: Wide_Character) is
1860 -- Use Ada requirements on Wide_Character representation clause
1862 U
:= XDR_WC
(Wide_Character'Pos (Item
));
1864 for N
in reverse S
'Range loop
1865 S
(N
) := SE
(U
mod BB
);
1869 Ada
.Streams
.Write
(Stream
.all, S
);
1881 (Stream
: not null access RST
; Item
: Wide_Wide_Character
)
1887 -- Use Ada requirements on Wide_Wide_Character representation clause
1889 U
:= XDR_WWC
(Wide_Wide_Character
'Pos (Item
));
1891 for N
in reverse S
'Range loop
1892 S
(N
) := SE
(U
mod BB
);
1896 Ada
.Streams
.Write
(Stream
.all, S
);
1903 end System
.Stream_Attributes
;