[gcc]
[official-gcc.git] / gcc / ada / s-stratt-xdr.adb
blob1c5d3cf62d13ade24172ba66ea276be4610408d4
1 ------------------------------------------------------------------------------
2 -- --
3 -- GNAT RUN-TIME COMPONENTS --
4 -- --
5 -- S Y S T E M . S T R E A M _ A T T R I B U T E S --
6 -- --
7 -- B o d y --
8 -- --
9 -- Copyright (C) 1996-2016, Free Software Foundation, Inc. --
10 -- --
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. --
17 -- --
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. --
21 -- --
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/>. --
26 -- --
27 -- GNAT was originally developed by the GNAT team at New York University. --
28 -- Extensive contributions were provided by Ada Core Technologies Inc. --
29 -- --
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);
50 use UST;
52 Data_Error : exception renames Ada.IO_Exceptions.End_Error;
53 -- Exception raised if insufficient data read (End_Error is mandated by
54 -- AI95-00132).
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;
73 type Field_Type is
74 record
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
83 end record;
85 type Precision is (Single, Double, Quadruple);
87 Fields : constant array (Precision) of Field_Type := (
89 -- Single precision
91 (E_Size => 8,
92 E_Bias => 127,
93 F_Size => 23,
94 E_Last => 2 ** 8 - 1,
95 F_Mask => 16#7F#, -- 2 ** 7 - 1,
96 E_Bytes => 2,
97 F_Bytes => 3,
98 F_Bits => 23 mod US),
100 -- Double precision
102 (E_Size => 11,
103 E_Bias => 1023,
104 F_Size => 52,
105 E_Last => 2 ** 11 - 1,
106 F_Mask => 16#0F#, -- 2 ** 4 - 1,
107 E_Bytes => 2,
108 F_Bytes => 7,
109 F_Bits => 52 mod US),
111 -- Quadruple precision
113 (E_Size => 15,
114 E_Bias => 16383,
115 F_Size => 112,
116 E_Last => 2 ** 8 - 1,
117 F_Mask => 16#FF#, -- 2 ** 8 - 1,
118 E_Bytes => 2,
119 F_Bytes => 14,
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:
134 -- (MSB) (LSB)
135 -- +-------+-------+-------+-------+
136 -- |byte 0 |byte 1 |byte 2 |byte 3 |
137 -- +-------+-------+-------+-------+
138 -- <------------32 bits------------>
140 SSI_L : constant := 1;
141 SI_L : constant := 2;
142 I_L : constant := 4;
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:
182 -- (MSB) (LSB)
183 -- +-------+-------+-------+-------+
184 -- |byte 0 |byte 1 |byte 2 |byte 3 |
185 -- +-------+-------+-------+-------+
186 -- <------------32 bits------------>
188 SSU_L : constant := 1;
189 SU_L : constant := 2;
190 U_L : constant := 4;
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
231 -- numbers.
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
262 -- type.
264 C_L : constant := 1;
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
282 -- conversions.
284 Optimize_Integers : constant Boolean :=
285 Default_Bit_Order = High_Order_First;
287 -----------------
288 -- Block_IO_OK --
289 -----------------
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
296 begin
297 return False;
298 end Block_IO_OK;
300 ----------
301 -- I_AD --
302 ----------
304 function I_AD (Stream : not null access RST) return Fat_Pointer is
305 FP : Fat_Pointer;
307 begin
308 FP.P1 := I_AS (Stream).P1;
309 FP.P2 := I_AS (Stream).P1;
311 return FP;
312 end I_AD;
314 ----------
315 -- I_AS --
316 ----------
318 function I_AS (Stream : not null access RST) return Thin_Pointer is
319 S : XDR_S_TM;
320 L : SEO;
321 U : XDR_TM := 0;
323 begin
324 Ada.Streams.Read (Stream.all, S, L);
326 if L /= S'Last then
327 raise Data_Error;
329 else
330 for N in S'Range loop
331 U := U * BB + XDR_TM (S (N));
332 end loop;
334 return (P1 => To_XDR_SA (XDR_SA (U)));
335 end if;
336 end I_AS;
338 ---------
339 -- I_B --
340 ---------
342 function I_B (Stream : not null access RST) return Boolean is
343 begin
344 case I_SSU (Stream) is
345 when 0 => return False;
346 when 1 => return True;
347 when others => raise Data_Error;
348 end case;
349 end I_B;
351 ---------
352 -- I_C --
353 ---------
355 function I_C (Stream : not null access RST) return Character is
356 S : XDR_S_C;
357 L : SEO;
359 begin
360 Ada.Streams.Read (Stream.all, S, L);
362 if L /= S'Last then
363 raise Data_Error;
365 else
366 -- Use Ada requirements on Character representation clause
368 return Character'Val (S (1));
369 end if;
370 end I_C;
372 ---------
373 -- I_F --
374 ---------
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;
389 Result : Float;
390 S : SEA (1 .. F_L);
391 L : SEO;
393 begin
394 Ada.Streams.Read (Stream.all, S, L);
396 if L /= S'Last then
397 raise Data_Error;
398 end if;
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));
405 end loop;
406 Result := Float'Scaling (Float (Fraction), -F_Size);
408 if BS <= S (1) then
409 Is_Positive := False;
410 Exponent := Long_Unsigned (S (1) - BS);
411 else
412 Is_Positive := True;
413 Exponent := Long_Unsigned (S (1));
414 end if;
416 for N in 2 .. E_Bytes loop
417 Exponent := Exponent * BB + Long_Unsigned (S (N));
418 end loop;
419 Exponent := Shift_Right (Exponent, Integer (E_Bytes) * SU - E_Size - 1);
421 -- NaN or Infinities
423 if Integer (Exponent) = E_Last then
424 raise Constraint_Error;
426 elsif Exponent = 0 then
428 -- Signed zeros
430 if Fraction = 0 then
431 null;
433 -- Denormalized float
435 else
436 Result := Float'Scaling (Result, 1 - E_Bias);
437 end if;
439 -- Normalized float
441 else
442 Result := Float'Scaling
443 (1.0 + Result, Integer (Exponent) - E_Bias);
444 end if;
446 if not Is_Positive then
447 Result := -Result;
448 end if;
450 return Result;
451 end I_F;
453 ---------
454 -- I_I --
455 ---------
457 function I_I (Stream : not null access RST) return Integer is
458 S : XDR_S_I;
459 L : SEO;
460 U : XDR_U := 0;
462 begin
463 Ada.Streams.Read (Stream.all, S, L);
465 if L /= S'Last then
466 raise Data_Error;
468 elsif Optimize_Integers then
469 return XDR_S_I_To_Integer (S);
471 else
472 for N in S'Range loop
473 U := U * BB + XDR_U (S (N));
474 end loop;
476 -- Test sign and apply two complement notation
478 if S (1) < BL then
479 return Integer (U);
481 else
482 return Integer (-((XDR_U'Last xor U) + 1));
483 end if;
484 end if;
485 end I_I;
487 ----------
488 -- I_LF --
489 ----------
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;
504 Result : Long_Float;
505 S : SEA (1 .. LF_L);
506 L : SEO;
508 begin
509 Ada.Streams.Read (Stream.all, S, L);
511 if L /= S'Last then
512 raise Data_Error;
513 end if;
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));
520 end loop;
522 Result := Long_Float'Scaling (Long_Float (Fraction), -F_Size);
524 if BS <= S (1) then
525 Is_Positive := False;
526 Exponent := Long_Unsigned (S (1) - BS);
527 else
528 Is_Positive := True;
529 Exponent := Long_Unsigned (S (1));
530 end if;
532 for N in 2 .. E_Bytes loop
533 Exponent := Exponent * BB + Long_Unsigned (S (N));
534 end loop;
536 Exponent := Shift_Right (Exponent, Integer (E_Bytes) * SU - E_Size - 1);
538 -- NaN or Infinities
540 if Integer (Exponent) = E_Last then
541 raise Constraint_Error;
543 elsif Exponent = 0 then
545 -- Signed zeros
547 if Fraction = 0 then
548 null;
550 -- Denormalized float
552 else
553 Result := Long_Float'Scaling (Result, 1 - E_Bias);
554 end if;
556 -- Normalized float
558 else
559 Result := Long_Float'Scaling
560 (1.0 + Result, Integer (Exponent) - E_Bias);
561 end if;
563 if not Is_Positive then
564 Result := -Result;
565 end if;
567 return Result;
568 end I_LF;
570 ----------
571 -- I_LI --
572 ----------
574 function I_LI (Stream : not null access RST) return Long_Integer is
575 S : XDR_S_LI;
576 L : SEO;
577 U : Unsigned := 0;
578 X : Long_Unsigned := 0;
580 begin
581 Ada.Streams.Read (Stream.all, S, L);
583 if L /= S'Last then
584 raise Data_Error;
586 elsif Optimize_Integers then
587 return Long_Integer (XDR_S_LI_To_Long_Long_Integer (S));
589 else
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
599 if N mod UB = 0 then
600 X := Shift_Left (X, US) + Long_Unsigned (U);
601 U := 0;
602 end if;
603 end loop;
605 -- Test sign and apply two complement notation
607 if S (1) < BL then
608 return Long_Integer (X);
609 else
610 return Long_Integer (-((Long_Unsigned'Last xor X) + 1));
611 end if;
613 end if;
614 end I_LI;
616 -----------
617 -- I_LLF --
618 -----------
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);
636 L : SEO;
638 begin
639 Ada.Streams.Read (Stream.all, S, L);
641 if L /= S'Last then
642 raise Data_Error;
643 end if;
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));
649 end loop;
651 for I in SEO (LLF_L - 6) .. SEO (LLF_L) loop
652 Fraction_2 := Fraction_2 * BB + Long_Long_Unsigned (S (I));
653 end loop;
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);
659 if BS <= S (1) then
660 Is_Positive := False;
661 Exponent := Long_Unsigned (S (1) - BS);
662 else
663 Is_Positive := True;
664 Exponent := Long_Unsigned (S (1));
665 end if;
667 for N in 2 .. E_Bytes loop
668 Exponent := Exponent * BB + Long_Unsigned (S (N));
669 end loop;
671 Exponent := Shift_Right (Exponent, Integer (E_Bytes) * SU - E_Size - 1);
673 -- NaN or Infinities
675 if Integer (Exponent) = E_Last then
676 raise Constraint_Error;
678 elsif Exponent = 0 then
680 -- Signed zeros
682 if Fraction_1 = 0 and then Fraction_2 = 0 then
683 null;
685 -- Denormalized float
687 else
688 Result := Long_Long_Float'Scaling (Result, 1 - E_Bias);
689 end if;
691 -- Normalized float
693 else
694 Result := Long_Long_Float'Scaling
695 (1.0 + Result, Integer (Exponent) - E_Bias);
696 end if;
698 if not Is_Positive then
699 Result := -Result;
700 end if;
702 return Result;
703 end I_LLF;
705 -----------
706 -- I_LLI --
707 -----------
709 function I_LLI (Stream : not null access RST) return Long_Long_Integer is
710 S : XDR_S_LLI;
711 L : SEO;
712 U : Unsigned := 0;
713 X : Long_Long_Unsigned := 0;
715 begin
716 Ada.Streams.Read (Stream.all, S, L);
718 if L /= S'Last then
719 raise Data_Error;
721 elsif Optimize_Integers then
722 return XDR_S_LLI_To_Long_Long_Integer (S);
724 else
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
733 if N mod UB = 0 then
734 X := Shift_Left (X, US) + Long_Long_Unsigned (U);
735 U := 0;
736 end if;
737 end loop;
739 -- Test sign and apply two complement notation
741 if S (1) < BL then
742 return Long_Long_Integer (X);
743 else
744 return Long_Long_Integer (-((Long_Long_Unsigned'Last xor X) + 1));
745 end if;
746 end if;
747 end I_LLI;
749 -----------
750 -- I_LLU --
751 -----------
753 function I_LLU (Stream : not null access RST) return Long_Long_Unsigned is
754 S : XDR_S_LLU;
755 L : SEO;
756 U : Unsigned := 0;
757 X : Long_Long_Unsigned := 0;
759 begin
760 Ada.Streams.Read (Stream.all, S, L);
762 if L /= S'Last then
763 raise Data_Error;
765 elsif Optimize_Integers then
766 return XDR_S_LLU_To_Long_Long_Unsigned (S);
768 else
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
777 if N mod UB = 0 then
778 X := Shift_Left (X, US) + Long_Long_Unsigned (U);
779 U := 0;
780 end if;
781 end loop;
783 return X;
784 end if;
785 end I_LLU;
787 ----------
788 -- I_LU --
789 ----------
791 function I_LU (Stream : not null access RST) return Long_Unsigned is
792 S : XDR_S_LU;
793 L : SEO;
794 U : Unsigned := 0;
795 X : Long_Unsigned := 0;
797 begin
798 Ada.Streams.Read (Stream.all, S, L);
800 if L /= S'Last then
801 raise Data_Error;
803 elsif Optimize_Integers then
804 return Long_Unsigned (XDR_S_LU_To_Long_Long_Unsigned (S));
806 else
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
815 if N mod UB = 0 then
816 X := Shift_Left (X, US) + Long_Unsigned (U);
817 U := 0;
818 end if;
819 end loop;
821 return X;
822 end if;
823 end I_LU;
825 ----------
826 -- I_SF --
827 ----------
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;
843 S : SEA (1 .. SF_L);
844 L : SEO;
846 begin
847 Ada.Streams.Read (Stream.all, S, L);
849 if L /= S'Last then
850 raise Data_Error;
851 end if;
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));
858 end loop;
859 Result := Short_Float'Scaling (Short_Float (Fraction), -F_Size);
861 if BS <= S (1) then
862 Is_Positive := False;
863 Exponent := Long_Unsigned (S (1) - BS);
864 else
865 Is_Positive := True;
866 Exponent := Long_Unsigned (S (1));
867 end if;
869 for N in 2 .. E_Bytes loop
870 Exponent := Exponent * BB + Long_Unsigned (S (N));
871 end loop;
872 Exponent := Shift_Right (Exponent, Integer (E_Bytes) * SU - E_Size - 1);
874 -- NaN or Infinities
876 if Integer (Exponent) = E_Last then
877 raise Constraint_Error;
879 elsif Exponent = 0 then
881 -- Signed zeros
883 if Fraction = 0 then
884 null;
886 -- Denormalized float
888 else
889 Result := Short_Float'Scaling (Result, 1 - E_Bias);
890 end if;
892 -- Normalized float
894 else
895 Result := Short_Float'Scaling
896 (1.0 + Result, Integer (Exponent) - E_Bias);
897 end if;
899 if not Is_Positive then
900 Result := -Result;
901 end if;
903 return Result;
904 end I_SF;
906 ----------
907 -- I_SI --
908 ----------
910 function I_SI (Stream : not null access RST) return Short_Integer is
911 S : XDR_S_SI;
912 L : SEO;
913 U : XDR_SU := 0;
915 begin
916 Ada.Streams.Read (Stream.all, S, L);
918 if L /= S'Last then
919 raise Data_Error;
921 elsif Optimize_Integers then
922 return XDR_S_SI_To_Short_Integer (S);
924 else
925 for N in S'Range loop
926 U := U * BB + XDR_SU (S (N));
927 end loop;
929 -- Test sign and apply two complement notation
931 if S (1) < BL then
932 return Short_Integer (U);
933 else
934 return Short_Integer (-((XDR_SU'Last xor U) + 1));
935 end if;
936 end if;
937 end I_SI;
939 -----------
940 -- I_SSI --
941 -----------
943 function I_SSI (Stream : not null access RST) return Short_Short_Integer is
944 S : XDR_S_SSI;
945 L : SEO;
946 U : XDR_SSU;
948 begin
949 Ada.Streams.Read (Stream.all, S, L);
951 if L /= S'Last then
952 raise Data_Error;
954 elsif Optimize_Integers then
955 return XDR_S_SSI_To_Short_Short_Integer (S);
957 else
958 U := XDR_SSU (S (1));
960 -- Test sign and apply two complement notation
962 if S (1) < BL then
963 return Short_Short_Integer (U);
964 else
965 return Short_Short_Integer (-((XDR_SSU'Last xor U) + 1));
966 end if;
967 end if;
968 end I_SSI;
970 -----------
971 -- I_SSU --
972 -----------
974 function I_SSU (Stream : not null access RST) return Short_Short_Unsigned is
975 S : XDR_S_SSU;
976 L : SEO;
977 U : XDR_SSU := 0;
979 begin
980 Ada.Streams.Read (Stream.all, S, L);
982 if L /= S'Last then
983 raise Data_Error;
985 else
986 U := XDR_SSU (S (1));
987 return Short_Short_Unsigned (U);
988 end if;
989 end I_SSU;
991 ----------
992 -- I_SU --
993 ----------
995 function I_SU (Stream : not null access RST) return Short_Unsigned is
996 S : XDR_S_SU;
997 L : SEO;
998 U : XDR_SU := 0;
1000 begin
1001 Ada.Streams.Read (Stream.all, S, L);
1003 if L /= S'Last then
1004 raise Data_Error;
1006 elsif Optimize_Integers then
1007 return XDR_S_SU_To_Short_Unsigned (S);
1009 else
1010 for N in S'Range loop
1011 U := U * BB + XDR_SU (S (N));
1012 end loop;
1014 return Short_Unsigned (U);
1015 end if;
1016 end I_SU;
1018 ---------
1019 -- I_U --
1020 ---------
1022 function I_U (Stream : not null access RST) return Unsigned is
1023 S : XDR_S_U;
1024 L : SEO;
1025 U : XDR_U := 0;
1027 begin
1028 Ada.Streams.Read (Stream.all, S, L);
1030 if L /= S'Last then
1031 raise Data_Error;
1033 elsif Optimize_Integers then
1034 return XDR_S_U_To_Unsigned (S);
1036 else
1037 for N in S'Range loop
1038 U := U * BB + XDR_U (S (N));
1039 end loop;
1041 return Unsigned (U);
1042 end if;
1043 end I_U;
1045 ----------
1046 -- I_WC --
1047 ----------
1049 function I_WC (Stream : not null access RST) return Wide_Character is
1050 S : XDR_S_WC;
1051 L : SEO;
1052 U : XDR_WC := 0;
1054 begin
1055 Ada.Streams.Read (Stream.all, S, L);
1057 if L /= S'Last then
1058 raise Data_Error;
1060 else
1061 for N in S'Range loop
1062 U := U * BB + XDR_WC (S (N));
1063 end loop;
1065 -- Use Ada requirements on Wide_Character representation clause
1067 return Wide_Character'Val (U);
1068 end if;
1069 end I_WC;
1071 -----------
1072 -- I_WWC --
1073 -----------
1075 function I_WWC (Stream : not null access RST) return Wide_Wide_Character is
1076 S : XDR_S_WWC;
1077 L : SEO;
1078 U : XDR_WWC := 0;
1080 begin
1081 Ada.Streams.Read (Stream.all, S, L);
1083 if L /= S'Last then
1084 raise Data_Error;
1086 else
1087 for N in S'Range loop
1088 U := U * BB + XDR_WWC (S (N));
1089 end loop;
1091 -- Use Ada requirements on Wide_Wide_Character representation clause
1093 return Wide_Wide_Character'Val (U);
1094 end if;
1095 end I_WWC;
1097 ----------
1098 -- W_AD --
1099 ----------
1101 procedure W_AD (Stream : not null access RST; Item : Fat_Pointer) is
1102 S : XDR_S_TM;
1103 U : XDR_TM;
1105 begin
1106 U := XDR_TM (To_XDR_SA (Item.P1));
1107 for N in reverse S'Range loop
1108 S (N) := SE (U mod BB);
1109 U := U / BB;
1110 end loop;
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);
1117 U := U / BB;
1118 end loop;
1120 Ada.Streams.Write (Stream.all, S);
1122 if U /= 0 then
1123 raise Data_Error;
1124 end if;
1125 end W_AD;
1127 ----------
1128 -- W_AS --
1129 ----------
1131 procedure W_AS (Stream : not null access RST; Item : Thin_Pointer) is
1132 S : XDR_S_TM;
1133 U : XDR_TM := XDR_TM (To_XDR_SA (Item.P1));
1135 begin
1136 for N in reverse S'Range loop
1137 S (N) := SE (U mod BB);
1138 U := U / BB;
1139 end loop;
1141 Ada.Streams.Write (Stream.all, S);
1143 if U /= 0 then
1144 raise Data_Error;
1145 end if;
1146 end W_AS;
1148 ---------
1149 -- W_B --
1150 ---------
1152 procedure W_B (Stream : not null access RST; Item : Boolean) is
1153 begin
1154 if Item then
1155 W_SSU (Stream, 1);
1156 else
1157 W_SSU (Stream, 0);
1158 end if;
1159 end W_B;
1161 ---------
1162 -- W_C --
1163 ---------
1165 procedure W_C (Stream : not null access RST; Item : Character) is
1166 S : XDR_S_C;
1168 pragma Assert (C_L = 1);
1170 begin
1171 -- Use Ada requirements on Character representation clause
1173 S (1) := SE (Character'Pos (Item));
1175 Ada.Streams.Write (Stream.all, S);
1176 end W_C;
1178 ---------
1179 -- W_F --
1180 ---------
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;
1194 E : Integer;
1195 F : Float;
1196 S : SEA (1 .. F_L) := (others => 0);
1198 begin
1199 if not Item'Valid then
1200 raise Constraint_Error;
1201 end if;
1203 -- Compute Sign
1205 Is_Positive := (0.0 <= Item);
1206 F := abs (Item);
1208 -- Signed zero
1210 if F = 0.0 then
1211 Exponent := 0;
1212 Fraction := 0;
1214 else
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);
1221 E := -E_Bias;
1222 else
1223 F := Float'Scaling (Float'Fraction (F), F_Size + 1);
1224 end if;
1226 -- Compute Exponent and Fraction
1228 Exponent := Long_Unsigned (E + E_Bias);
1229 Fraction := Long_Unsigned (F * 2.0) / 2;
1230 end if;
1232 -- Store Fraction
1234 for I in reverse F_L - F_Bytes + 1 .. F_L loop
1235 S (I) := SE (Fraction mod BB);
1236 Fraction := Fraction / BB;
1237 end loop;
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;
1249 end loop;
1251 -- Store Sign
1253 if not Is_Positive then
1254 S (1) := S (1) + BS;
1255 end if;
1257 Ada.Streams.Write (Stream.all, S);
1258 end W_F;
1260 ---------
1261 -- W_I --
1262 ---------
1264 procedure W_I (Stream : not null access RST; Item : Integer) is
1265 S : XDR_S_I;
1266 U : XDR_U;
1268 begin
1269 if Optimize_Integers then
1270 S := Integer_To_XDR_S_I (Item);
1272 else
1273 -- Test sign and apply two complement notation
1275 U := (if Item < 0
1276 then XDR_U'Last xor XDR_U (-(Item + 1))
1277 else XDR_U (Item));
1279 for N in reverse S'Range loop
1280 S (N) := SE (U mod BB);
1281 U := U / BB;
1282 end loop;
1284 if U /= 0 then
1285 raise Data_Error;
1286 end if;
1287 end if;
1289 Ada.Streams.Write (Stream.all, S);
1290 end W_I;
1292 ----------
1293 -- W_LF --
1294 ----------
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;
1308 E : Integer;
1309 F : Long_Float;
1310 S : SEA (1 .. LF_L) := (others => 0);
1312 begin
1313 if not Item'Valid then
1314 raise Constraint_Error;
1315 end if;
1317 -- Compute Sign
1319 Is_Positive := (0.0 <= Item);
1320 F := abs (Item);
1322 -- Signed zero
1324 if F = 0.0 then
1325 Exponent := 0;
1326 Fraction := 0;
1328 else
1329 E := Long_Float'Exponent (F) - 1;
1331 -- Denormalized float
1333 if E <= -E_Bias then
1334 E := -E_Bias;
1335 F := Long_Float'Scaling (F, F_Size + E_Bias - 1);
1336 else
1337 F := Long_Float'Scaling (F, F_Size - E);
1338 end if;
1340 -- Compute Exponent and Fraction
1342 Exponent := Long_Unsigned (E + E_Bias);
1343 Fraction := Long_Long_Unsigned (F * 2.0) / 2;
1344 end if;
1346 -- Store Fraction
1348 for I in reverse LF_L - F_Bytes + 1 .. LF_L loop
1349 S (I) := SE (Fraction mod BB);
1350 Fraction := Fraction / BB;
1351 end loop;
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;
1363 end loop;
1365 -- Store Sign
1367 if not Is_Positive then
1368 S (1) := S (1) + BS;
1369 end if;
1371 Ada.Streams.Write (Stream.all, S);
1372 end W_LF;
1374 ----------
1375 -- W_LI --
1376 ----------
1378 procedure W_LI (Stream : not null access RST; Item : Long_Integer) is
1379 S : XDR_S_LI;
1380 U : Unsigned;
1381 X : Long_Unsigned;
1383 begin
1384 if Optimize_Integers then
1385 S := Long_Long_Integer_To_XDR_S_LI (Long_Long_Integer (Item));
1387 else
1388 -- Test sign and apply two complement notation
1390 if Item < 0 then
1391 X := Long_Unsigned'Last xor Long_Unsigned (-(Item + 1));
1392 else
1393 X := Long_Unsigned (Item);
1394 end if;
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);
1405 end if;
1407 S (N) := SE (U mod BB);
1408 U := U / BB;
1409 end loop;
1411 if U /= 0 then
1412 raise Data_Error;
1413 end if;
1414 end if;
1416 Ada.Streams.Write (Stream.all, S);
1417 end W_LI;
1419 -----------
1420 -- W_LLF --
1421 -----------
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;
1437 E : Integer;
1438 F : Long_Long_Float := Item;
1439 S : SEA (1 .. LLF_L) := (others => 0);
1441 begin
1442 if not Item'Valid then
1443 raise Constraint_Error;
1444 end if;
1446 -- Compute Sign
1448 Is_Positive := (0.0 <= Item);
1450 if F < 0.0 then
1451 F := -Item;
1452 end if;
1454 -- Signed zero
1456 if F = 0.0 then
1457 Exponent := 0;
1458 Fraction_1 := 0;
1459 Fraction_2 := 0;
1461 else
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);
1468 E := -E_Bias;
1469 else
1470 F := Long_Long_Float'Scaling
1471 (Long_Long_Float'Fraction (F), 1);
1472 end if;
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));
1482 end if;
1484 -- Store Fraction_1
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;
1489 end loop;
1491 -- Store Fraction_2
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;
1496 end loop;
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;
1504 end loop;
1506 -- Store Sign
1508 if not Is_Positive then
1509 S (1) := S (1) + BS;
1510 end if;
1512 Ada.Streams.Write (Stream.all, S);
1513 end W_LLF;
1515 -----------
1516 -- W_LLI --
1517 -----------
1519 procedure W_LLI
1520 (Stream : not null access RST;
1521 Item : Long_Long_Integer)
1523 S : XDR_S_LLI;
1524 U : Unsigned;
1525 X : Long_Long_Unsigned;
1527 begin
1528 if Optimize_Integers then
1529 S := Long_Long_Integer_To_XDR_S_LLI (Item);
1531 else
1532 -- Test sign and apply two complement notation
1534 if Item < 0 then
1535 X := Long_Long_Unsigned'Last xor Long_Long_Unsigned (-(Item + 1));
1536 else
1537 X := Long_Long_Unsigned (Item);
1538 end if;
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);
1549 end if;
1551 S (N) := SE (U mod BB);
1552 U := U / BB;
1553 end loop;
1555 if U /= 0 then
1556 raise Data_Error;
1557 end if;
1558 end if;
1560 Ada.Streams.Write (Stream.all, S);
1561 end W_LLI;
1563 -----------
1564 -- W_LLU --
1565 -----------
1567 procedure W_LLU
1568 (Stream : not null access RST;
1569 Item : Long_Long_Unsigned)
1571 S : XDR_S_LLU;
1572 U : Unsigned;
1573 X : Long_Long_Unsigned := Item;
1575 begin
1576 if Optimize_Integers then
1577 S := Long_Long_Unsigned_To_XDR_S_LLU (Item);
1579 else
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);
1589 end if;
1591 S (N) := SE (U mod BB);
1592 U := U / BB;
1593 end loop;
1595 if U /= 0 then
1596 raise Data_Error;
1597 end if;
1598 end if;
1600 Ada.Streams.Write (Stream.all, S);
1601 end W_LLU;
1603 ----------
1604 -- W_LU --
1605 ----------
1607 procedure W_LU (Stream : not null access RST; Item : Long_Unsigned) is
1608 S : XDR_S_LU;
1609 U : Unsigned;
1610 X : Long_Unsigned := Item;
1612 begin
1613 if Optimize_Integers then
1614 S := Long_Long_Unsigned_To_XDR_S_LU (Long_Long_Unsigned (Item));
1616 else
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);
1626 end if;
1627 S (N) := SE (U mod BB);
1628 U := U / BB;
1629 end loop;
1631 if U /= 0 then
1632 raise Data_Error;
1633 end if;
1634 end if;
1636 Ada.Streams.Write (Stream.all, S);
1637 end W_LU;
1639 ----------
1640 -- W_SF --
1641 ----------
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;
1655 E : Integer;
1656 F : Short_Float;
1657 S : SEA (1 .. SF_L) := (others => 0);
1659 begin
1660 if not Item'Valid then
1661 raise Constraint_Error;
1662 end if;
1664 -- Compute Sign
1666 Is_Positive := (0.0 <= Item);
1667 F := abs (Item);
1669 -- Signed zero
1671 if F = 0.0 then
1672 Exponent := 0;
1673 Fraction := 0;
1675 else
1676 E := Short_Float'Exponent (F) - 1;
1678 -- Denormalized float
1680 if E <= -E_Bias then
1681 E := -E_Bias;
1682 F := Short_Float'Scaling (F, F_Size + E_Bias - 1);
1683 else
1684 F := Short_Float'Scaling (F, F_Size - E);
1685 end if;
1687 -- Compute Exponent and Fraction
1689 Exponent := Long_Unsigned (E + E_Bias);
1690 Fraction := Long_Unsigned (F * 2.0) / 2;
1691 end if;
1693 -- Store Fraction
1695 for I in reverse SF_L - F_Bytes + 1 .. SF_L loop
1696 S (I) := SE (Fraction mod BB);
1697 Fraction := Fraction / BB;
1698 end loop;
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;
1710 end loop;
1712 -- Store Sign
1714 if not Is_Positive then
1715 S (1) := S (1) + BS;
1716 end if;
1718 Ada.Streams.Write (Stream.all, S);
1719 end W_SF;
1721 ----------
1722 -- W_SI --
1723 ----------
1725 procedure W_SI (Stream : not null access RST; Item : Short_Integer) is
1726 S : XDR_S_SI;
1727 U : XDR_SU;
1729 begin
1730 if Optimize_Integers then
1731 S := Short_Integer_To_XDR_S_SI (Item);
1733 else
1734 -- Test sign and apply two complement's notation
1736 U := (if Item < 0
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);
1742 U := U / BB;
1743 end loop;
1745 if U /= 0 then
1746 raise Data_Error;
1747 end if;
1748 end if;
1750 Ada.Streams.Write (Stream.all, S);
1751 end W_SI;
1753 -----------
1754 -- W_SSI --
1755 -----------
1757 procedure W_SSI
1758 (Stream : not null access RST;
1759 Item : Short_Short_Integer)
1761 S : XDR_S_SSI;
1762 U : XDR_SSU;
1764 begin
1765 if Optimize_Integers then
1766 S := Short_Short_Integer_To_XDR_S_SSI (Item);
1768 else
1769 -- Test sign and apply two complement's notation
1771 U := (if Item < 0
1772 then XDR_SSU'Last xor XDR_SSU (-(Item + 1))
1773 else XDR_SSU (Item));
1775 S (1) := SE (U);
1776 end if;
1778 Ada.Streams.Write (Stream.all, S);
1779 end W_SSI;
1781 -----------
1782 -- W_SSU --
1783 -----------
1785 procedure W_SSU
1786 (Stream : not null access RST;
1787 Item : Short_Short_Unsigned)
1789 U : constant XDR_SSU := XDR_SSU (Item);
1790 S : XDR_S_SSU;
1792 begin
1793 S (1) := SE (U);
1794 Ada.Streams.Write (Stream.all, S);
1795 end W_SSU;
1797 ----------
1798 -- W_SU --
1799 ----------
1801 procedure W_SU (Stream : not null access RST; Item : Short_Unsigned) is
1802 S : XDR_S_SU;
1803 U : XDR_SU := XDR_SU (Item);
1805 begin
1806 if Optimize_Integers then
1807 S := Short_Unsigned_To_XDR_S_SU (Item);
1809 else
1810 for N in reverse S'Range loop
1811 S (N) := SE (U mod BB);
1812 U := U / BB;
1813 end loop;
1815 if U /= 0 then
1816 raise Data_Error;
1817 end if;
1818 end if;
1820 Ada.Streams.Write (Stream.all, S);
1821 end W_SU;
1823 ---------
1824 -- W_U --
1825 ---------
1827 procedure W_U (Stream : not null access RST; Item : Unsigned) is
1828 S : XDR_S_U;
1829 U : XDR_U := XDR_U (Item);
1831 begin
1832 if Optimize_Integers then
1833 S := Unsigned_To_XDR_S_U (Item);
1835 else
1836 for N in reverse S'Range loop
1837 S (N) := SE (U mod BB);
1838 U := U / BB;
1839 end loop;
1841 if U /= 0 then
1842 raise Data_Error;
1843 end if;
1844 end if;
1846 Ada.Streams.Write (Stream.all, S);
1847 end W_U;
1849 ----------
1850 -- W_WC --
1851 ----------
1853 procedure W_WC (Stream : not null access RST; Item : Wide_Character) is
1854 S : XDR_S_WC;
1855 U : XDR_WC;
1857 begin
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);
1864 U := U / BB;
1865 end loop;
1867 Ada.Streams.Write (Stream.all, S);
1869 if U /= 0 then
1870 raise Data_Error;
1871 end if;
1872 end W_WC;
1874 -----------
1875 -- W_WWC --
1876 -----------
1878 procedure W_WWC
1879 (Stream : not null access RST; Item : Wide_Wide_Character)
1881 S : XDR_S_WWC;
1882 U : XDR_WWC;
1884 begin
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);
1891 U := U / BB;
1892 end loop;
1894 Ada.Streams.Write (Stream.all, S);
1896 if U /= 0 then
1897 raise Data_Error;
1898 end if;
1899 end W_WWC;
1901 end System.Stream_Attributes;