2015-09-28 Paul Thomas <pault@gcc.gnu.org>
[official-gcc.git] / gcc / ada / s-stratt-xdr.adb
blobae4c9b37e7c444323f7ed2eb579928b8648f1cf6
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-2013, 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 with Ada.IO_Exceptions;
37 with Ada.Streams; use Ada.Streams;
38 with Ada.Unchecked_Conversion;
40 package body System.Stream_Attributes is
42 pragma Suppress (Range_Check);
43 pragma Suppress (Overflow_Check);
45 use UST;
47 Data_Error : exception renames Ada.IO_Exceptions.End_Error;
48 -- Exception raised if insufficient data read (End_Error is mandated by
49 -- AI95-00132).
51 SU : constant := System.Storage_Unit;
52 -- The code in this body assumes that SU = 8
54 BB : constant := 2 ** SU; -- Byte base
55 BL : constant := 2 ** SU - 1; -- Byte last
56 BS : constant := 2 ** (SU - 1); -- Byte sign
58 US : constant := Unsigned'Size; -- Unsigned size
59 UB : constant := (US - 1) / SU + 1; -- Unsigned byte
60 UL : constant := 2 ** US - 1; -- Unsigned last
62 subtype SE is Ada.Streams.Stream_Element;
63 subtype SEA is Ada.Streams.Stream_Element_Array;
64 subtype SEO is Ada.Streams.Stream_Element_Offset;
66 generic function UC renames Ada.Unchecked_Conversion;
68 type Field_Type is
69 record
70 E_Size : Integer; -- Exponent bit size
71 E_Bias : Integer; -- Exponent bias
72 F_Size : Integer; -- Fraction bit size
73 E_Last : Integer; -- Max exponent value
74 F_Mask : SE; -- Mask to apply on first fraction byte
75 E_Bytes : SEO; -- N. of exponent bytes completely used
76 F_Bytes : SEO; -- N. of fraction bytes completely used
77 F_Bits : Integer; -- N. of bits used on first fraction word
78 end record;
80 type Precision is (Single, Double, Quadruple);
82 Fields : constant array (Precision) of Field_Type := (
84 -- Single precision
86 (E_Size => 8,
87 E_Bias => 127,
88 F_Size => 23,
89 E_Last => 2 ** 8 - 1,
90 F_Mask => 16#7F#, -- 2 ** 7 - 1,
91 E_Bytes => 2,
92 F_Bytes => 3,
93 F_Bits => 23 mod US),
95 -- Double precision
97 (E_Size => 11,
98 E_Bias => 1023,
99 F_Size => 52,
100 E_Last => 2 ** 11 - 1,
101 F_Mask => 16#0F#, -- 2 ** 4 - 1,
102 E_Bytes => 2,
103 F_Bytes => 7,
104 F_Bits => 52 mod US),
106 -- Quadruple precision
108 (E_Size => 15,
109 E_Bias => 16383,
110 F_Size => 112,
111 E_Last => 2 ** 8 - 1,
112 F_Mask => 16#FF#, -- 2 ** 8 - 1,
113 E_Bytes => 2,
114 F_Bytes => 14,
115 F_Bits => 112 mod US));
117 -- The representation of all items requires a multiple of four bytes
118 -- (or 32 bits) of data. The bytes are numbered 0 through n-1. The bytes
119 -- are read or written to some byte stream such that byte m always
120 -- precedes byte m+1. If the n bytes needed to contain the data are not
121 -- a multiple of four, then the n bytes are followed by enough (0 to 3)
122 -- residual zero bytes, r, to make the total byte count a multiple of 4.
124 -- An XDR signed integer is a 32-bit datum that encodes an integer
125 -- in the range [-2147483648,2147483647]. The integer is represented
126 -- in two's complement notation. The most and least significant bytes
127 -- are 0 and 3, respectively. Integers are declared as follows:
129 -- (MSB) (LSB)
130 -- +-------+-------+-------+-------+
131 -- |byte 0 |byte 1 |byte 2 |byte 3 |
132 -- +-------+-------+-------+-------+
133 -- <------------32 bits------------>
135 SSI_L : constant := 1;
136 SI_L : constant := 2;
137 I_L : constant := 4;
138 LI_L : constant := 8;
139 LLI_L : constant := 8;
141 subtype XDR_S_SSI is SEA (1 .. SSI_L);
142 subtype XDR_S_SI is SEA (1 .. SI_L);
143 subtype XDR_S_I is SEA (1 .. I_L);
144 subtype XDR_S_LI is SEA (1 .. LI_L);
145 subtype XDR_S_LLI is SEA (1 .. LLI_L);
147 function Short_Short_Integer_To_XDR_S_SSI is
148 new Ada.Unchecked_Conversion (Short_Short_Integer, XDR_S_SSI);
149 function XDR_S_SSI_To_Short_Short_Integer is
150 new Ada.Unchecked_Conversion (XDR_S_SSI, Short_Short_Integer);
152 function Short_Integer_To_XDR_S_SI is
153 new Ada.Unchecked_Conversion (Short_Integer, XDR_S_SI);
154 function XDR_S_SI_To_Short_Integer is
155 new Ada.Unchecked_Conversion (XDR_S_SI, Short_Integer);
157 function Integer_To_XDR_S_I is
158 new Ada.Unchecked_Conversion (Integer, XDR_S_I);
159 function XDR_S_I_To_Integer is
160 new Ada.Unchecked_Conversion (XDR_S_I, Integer);
162 function Long_Long_Integer_To_XDR_S_LI is
163 new Ada.Unchecked_Conversion (Long_Long_Integer, XDR_S_LI);
164 function XDR_S_LI_To_Long_Long_Integer is
165 new Ada.Unchecked_Conversion (XDR_S_LI, Long_Long_Integer);
167 function Long_Long_Integer_To_XDR_S_LLI is
168 new Ada.Unchecked_Conversion (Long_Long_Integer, XDR_S_LLI);
169 function XDR_S_LLI_To_Long_Long_Integer is
170 new Ada.Unchecked_Conversion (XDR_S_LLI, Long_Long_Integer);
172 -- An XDR unsigned integer is a 32-bit datum that encodes a nonnegative
173 -- integer in the range [0,4294967295]. It is represented by an unsigned
174 -- binary number whose most and least significant bytes are 0 and 3,
175 -- respectively. An unsigned integer is declared as follows:
177 -- (MSB) (LSB)
178 -- +-------+-------+-------+-------+
179 -- |byte 0 |byte 1 |byte 2 |byte 3 |
180 -- +-------+-------+-------+-------+
181 -- <------------32 bits------------>
183 SSU_L : constant := 1;
184 SU_L : constant := 2;
185 U_L : constant := 4;
186 LU_L : constant := 8;
187 LLU_L : constant := 8;
189 subtype XDR_S_SSU is SEA (1 .. SSU_L);
190 subtype XDR_S_SU is SEA (1 .. SU_L);
191 subtype XDR_S_U is SEA (1 .. U_L);
192 subtype XDR_S_LU is SEA (1 .. LU_L);
193 subtype XDR_S_LLU is SEA (1 .. LLU_L);
195 type XDR_SSU is mod BB ** SSU_L;
196 type XDR_SU is mod BB ** SU_L;
197 type XDR_U is mod BB ** U_L;
199 function Short_Unsigned_To_XDR_S_SU is
200 new Ada.Unchecked_Conversion (Short_Unsigned, XDR_S_SU);
201 function XDR_S_SU_To_Short_Unsigned is
202 new Ada.Unchecked_Conversion (XDR_S_SU, Short_Unsigned);
204 function Unsigned_To_XDR_S_U is
205 new Ada.Unchecked_Conversion (Unsigned, XDR_S_U);
206 function XDR_S_U_To_Unsigned is
207 new Ada.Unchecked_Conversion (XDR_S_U, Unsigned);
209 function Long_Long_Unsigned_To_XDR_S_LU is
210 new Ada.Unchecked_Conversion (Long_Long_Unsigned, XDR_S_LU);
211 function XDR_S_LU_To_Long_Long_Unsigned is
212 new Ada.Unchecked_Conversion (XDR_S_LU, Long_Long_Unsigned);
214 function Long_Long_Unsigned_To_XDR_S_LLU is
215 new Ada.Unchecked_Conversion (Long_Long_Unsigned, XDR_S_LLU);
216 function XDR_S_LLU_To_Long_Long_Unsigned is
217 new Ada.Unchecked_Conversion (XDR_S_LLU, Long_Long_Unsigned);
219 -- The standard defines the floating-point data type "float" (32 bits
220 -- or 4 bytes). The encoding used is the IEEE standard for normalized
221 -- single-precision floating-point numbers.
223 -- The standard defines the encoding used for the double-precision
224 -- floating-point data type "double" (64 bits or 8 bytes). The encoding
225 -- used is the IEEE standard for normalized double-precision floating-point
226 -- numbers.
228 SF_L : constant := 4; -- Single precision
229 F_L : constant := 4; -- Single precision
230 LF_L : constant := 8; -- Double precision
231 LLF_L : constant := 16; -- Quadruple precision
233 TM_L : constant := 8;
234 subtype XDR_S_TM is SEA (1 .. TM_L);
235 type XDR_TM is mod BB ** TM_L;
237 type XDR_SA is mod 2 ** Standard'Address_Size;
238 function To_XDR_SA is new UC (System.Address, XDR_SA);
239 function To_XDR_SA is new UC (XDR_SA, System.Address);
241 -- Enumerations have the same representation as signed integers.
242 -- Enumerations are handy for describing subsets of the integers.
244 -- Booleans are important enough and occur frequently enough to warrant
245 -- their own explicit type in the standard. Booleans are declared as
246 -- an enumeration, with FALSE = 0 and TRUE = 1.
248 -- The standard defines a string of n (numbered 0 through n-1) ASCII
249 -- bytes to be the number n encoded as an unsigned integer (as described
250 -- above), and followed by the n bytes of the string. Byte m of the string
251 -- always precedes byte m+1 of the string, and byte 0 of the string always
252 -- follows the string's length. If n is not a multiple of four, then the
253 -- n bytes are followed by enough (0 to 3) residual zero bytes, r, to make
254 -- the total byte count a multiple of four.
256 -- To fit with XDR string, do not consider character as an enumeration
257 -- type.
259 C_L : constant := 1;
260 subtype XDR_S_C is SEA (1 .. C_L);
262 -- Consider Wide_Character as an enumeration type
264 WC_L : constant := 4;
265 subtype XDR_S_WC is SEA (1 .. WC_L);
266 type XDR_WC is mod BB ** WC_L;
268 -- Consider Wide_Wide_Character as an enumeration type
270 WWC_L : constant := 8;
271 subtype XDR_S_WWC is SEA (1 .. WWC_L);
272 type XDR_WWC is mod BB ** WWC_L;
274 -- Optimization: if we already have the correct Bit_Order, then some
275 -- computations can be avoided since the source and the target will be
276 -- identical anyway. They will be replaced by direct unchecked
277 -- conversions.
279 Optimize_Integers : constant Boolean :=
280 Default_Bit_Order = High_Order_First;
282 -----------------
283 -- Block_IO_OK --
284 -----------------
286 -- We must inhibit Block_IO, because in XDR mode, each element is output
287 -- according to XDR requirements, which is not at all the same as writing
288 -- the whole array in one block.
290 function Block_IO_OK return Boolean is
291 begin
292 return False;
293 end Block_IO_OK;
295 ----------
296 -- I_AD --
297 ----------
299 function I_AD (Stream : not null access RST) return Fat_Pointer is
300 FP : Fat_Pointer;
302 begin
303 FP.P1 := I_AS (Stream).P1;
304 FP.P2 := I_AS (Stream).P1;
306 return FP;
307 end I_AD;
309 ----------
310 -- I_AS --
311 ----------
313 function I_AS (Stream : not null access RST) return Thin_Pointer is
314 S : XDR_S_TM;
315 L : SEO;
316 U : XDR_TM := 0;
318 begin
319 Ada.Streams.Read (Stream.all, S, L);
321 if L /= S'Last then
322 raise Data_Error;
324 else
325 for N in S'Range loop
326 U := U * BB + XDR_TM (S (N));
327 end loop;
329 return (P1 => To_XDR_SA (XDR_SA (U)));
330 end if;
331 end I_AS;
333 ---------
334 -- I_B --
335 ---------
337 function I_B (Stream : not null access RST) return Boolean is
338 begin
339 case I_SSU (Stream) is
340 when 0 => return False;
341 when 1 => return True;
342 when others => raise Data_Error;
343 end case;
344 end I_B;
346 ---------
347 -- I_C --
348 ---------
350 function I_C (Stream : not null access RST) return Character is
351 S : XDR_S_C;
352 L : SEO;
354 begin
355 Ada.Streams.Read (Stream.all, S, L);
357 if L /= S'Last then
358 raise Data_Error;
360 else
361 -- Use Ada requirements on Character representation clause
363 return Character'Val (S (1));
364 end if;
365 end I_C;
367 ---------
368 -- I_F --
369 ---------
371 function I_F (Stream : not null access RST) return Float is
372 I : constant Precision := Single;
373 E_Size : Integer renames Fields (I).E_Size;
374 E_Bias : Integer renames Fields (I).E_Bias;
375 E_Last : Integer renames Fields (I).E_Last;
376 F_Mask : SE renames Fields (I).F_Mask;
377 E_Bytes : SEO renames Fields (I).E_Bytes;
378 F_Bytes : SEO renames Fields (I).F_Bytes;
379 F_Size : Integer renames Fields (I).F_Size;
381 Is_Positive : Boolean;
382 Exponent : Long_Unsigned;
383 Fraction : Long_Unsigned;
384 Result : Float;
385 S : SEA (1 .. F_L);
386 L : SEO;
388 begin
389 Ada.Streams.Read (Stream.all, S, L);
391 if L /= S'Last then
392 raise Data_Error;
393 end if;
395 -- Extract Fraction, Sign and Exponent
397 Fraction := Long_Unsigned (S (F_L + 1 - F_Bytes) and F_Mask);
398 for N in F_L + 2 - F_Bytes .. F_L loop
399 Fraction := Fraction * BB + Long_Unsigned (S (N));
400 end loop;
401 Result := Float'Scaling (Float (Fraction), -F_Size);
403 if BS <= S (1) then
404 Is_Positive := False;
405 Exponent := Long_Unsigned (S (1) - BS);
406 else
407 Is_Positive := True;
408 Exponent := Long_Unsigned (S (1));
409 end if;
411 for N in 2 .. E_Bytes loop
412 Exponent := Exponent * BB + Long_Unsigned (S (N));
413 end loop;
414 Exponent := Shift_Right (Exponent, Integer (E_Bytes) * SU - E_Size - 1);
416 -- NaN or Infinities
418 if Integer (Exponent) = E_Last then
419 raise Constraint_Error;
421 elsif Exponent = 0 then
423 -- Signed zeros
425 if Fraction = 0 then
426 null;
428 -- Denormalized float
430 else
431 Result := Float'Scaling (Result, 1 - E_Bias);
432 end if;
434 -- Normalized float
436 else
437 Result := Float'Scaling
438 (1.0 + Result, Integer (Exponent) - E_Bias);
439 end if;
441 if not Is_Positive then
442 Result := -Result;
443 end if;
445 return Result;
446 end I_F;
448 ---------
449 -- I_I --
450 ---------
452 function I_I (Stream : not null access RST) return Integer is
453 S : XDR_S_I;
454 L : SEO;
455 U : XDR_U := 0;
457 begin
458 Ada.Streams.Read (Stream.all, S, L);
460 if L /= S'Last then
461 raise Data_Error;
463 elsif Optimize_Integers then
464 return XDR_S_I_To_Integer (S);
466 else
467 for N in S'Range loop
468 U := U * BB + XDR_U (S (N));
469 end loop;
471 -- Test sign and apply two complement notation
473 if S (1) < BL then
474 return Integer (U);
476 else
477 return Integer (-((XDR_U'Last xor U) + 1));
478 end if;
479 end if;
480 end I_I;
482 ----------
483 -- I_LF --
484 ----------
486 function I_LF (Stream : not null access RST) return Long_Float is
487 I : constant Precision := Double;
488 E_Size : Integer renames Fields (I).E_Size;
489 E_Bias : Integer renames Fields (I).E_Bias;
490 E_Last : Integer renames Fields (I).E_Last;
491 F_Mask : SE renames Fields (I).F_Mask;
492 E_Bytes : SEO renames Fields (I).E_Bytes;
493 F_Bytes : SEO renames Fields (I).F_Bytes;
494 F_Size : Integer renames Fields (I).F_Size;
496 Is_Positive : Boolean;
497 Exponent : Long_Unsigned;
498 Fraction : Long_Long_Unsigned;
499 Result : Long_Float;
500 S : SEA (1 .. LF_L);
501 L : SEO;
503 begin
504 Ada.Streams.Read (Stream.all, S, L);
506 if L /= S'Last then
507 raise Data_Error;
508 end if;
510 -- Extract Fraction, Sign and Exponent
512 Fraction := Long_Long_Unsigned (S (LF_L + 1 - F_Bytes) and F_Mask);
513 for N in LF_L + 2 - F_Bytes .. LF_L loop
514 Fraction := Fraction * BB + Long_Long_Unsigned (S (N));
515 end loop;
517 Result := Long_Float'Scaling (Long_Float (Fraction), -F_Size);
519 if BS <= S (1) then
520 Is_Positive := False;
521 Exponent := Long_Unsigned (S (1) - BS);
522 else
523 Is_Positive := True;
524 Exponent := Long_Unsigned (S (1));
525 end if;
527 for N in 2 .. E_Bytes loop
528 Exponent := Exponent * BB + Long_Unsigned (S (N));
529 end loop;
531 Exponent := Shift_Right (Exponent, Integer (E_Bytes) * SU - E_Size - 1);
533 -- NaN or Infinities
535 if Integer (Exponent) = E_Last then
536 raise Constraint_Error;
538 elsif Exponent = 0 then
540 -- Signed zeros
542 if Fraction = 0 then
543 null;
545 -- Denormalized float
547 else
548 Result := Long_Float'Scaling (Result, 1 - E_Bias);
549 end if;
551 -- Normalized float
553 else
554 Result := Long_Float'Scaling
555 (1.0 + Result, Integer (Exponent) - E_Bias);
556 end if;
558 if not Is_Positive then
559 Result := -Result;
560 end if;
562 return Result;
563 end I_LF;
565 ----------
566 -- I_LI --
567 ----------
569 function I_LI (Stream : not null access RST) return Long_Integer is
570 S : XDR_S_LI;
571 L : SEO;
572 U : Unsigned := 0;
573 X : Long_Unsigned := 0;
575 begin
576 Ada.Streams.Read (Stream.all, S, L);
578 if L /= S'Last then
579 raise Data_Error;
581 elsif Optimize_Integers then
582 return Long_Integer (XDR_S_LI_To_Long_Long_Integer (S));
584 else
586 -- Compute using machine unsigned
587 -- rather than long_long_unsigned
589 for N in S'Range loop
590 U := U * BB + Unsigned (S (N));
592 -- We have filled an unsigned
594 if N mod UB = 0 then
595 X := Shift_Left (X, US) + Long_Unsigned (U);
596 U := 0;
597 end if;
598 end loop;
600 -- Test sign and apply two complement notation
602 if S (1) < BL then
603 return Long_Integer (X);
604 else
605 return Long_Integer (-((Long_Unsigned'Last xor X) + 1));
606 end if;
608 end if;
609 end I_LI;
611 -----------
612 -- I_LLF --
613 -----------
615 function I_LLF (Stream : not null access RST) return Long_Long_Float is
616 I : constant Precision := Quadruple;
617 E_Size : Integer renames Fields (I).E_Size;
618 E_Bias : Integer renames Fields (I).E_Bias;
619 E_Last : Integer renames Fields (I).E_Last;
620 E_Bytes : SEO renames Fields (I).E_Bytes;
621 F_Bytes : SEO renames Fields (I).F_Bytes;
622 F_Size : Integer renames Fields (I).F_Size;
624 Is_Positive : Boolean;
625 Exponent : Long_Unsigned;
626 Fraction_1 : Long_Long_Unsigned := 0;
627 Fraction_2 : Long_Long_Unsigned := 0;
628 Result : Long_Long_Float;
629 HF : constant Natural := F_Size / 2;
630 S : SEA (1 .. LLF_L);
631 L : SEO;
633 begin
634 Ada.Streams.Read (Stream.all, S, L);
636 if L /= S'Last then
637 raise Data_Error;
638 end if;
640 -- Extract Fraction, Sign and Exponent
642 for I in LLF_L - F_Bytes + 1 .. LLF_L - 7 loop
643 Fraction_1 := Fraction_1 * BB + Long_Long_Unsigned (S (I));
644 end loop;
646 for I in SEO (LLF_L - 6) .. SEO (LLF_L) loop
647 Fraction_2 := Fraction_2 * BB + Long_Long_Unsigned (S (I));
648 end loop;
650 Result := Long_Long_Float'Scaling (Long_Long_Float (Fraction_2), -HF);
651 Result := Long_Long_Float (Fraction_1) + Result;
652 Result := Long_Long_Float'Scaling (Result, HF - F_Size);
654 if BS <= S (1) then
655 Is_Positive := False;
656 Exponent := Long_Unsigned (S (1) - BS);
657 else
658 Is_Positive := True;
659 Exponent := Long_Unsigned (S (1));
660 end if;
662 for N in 2 .. E_Bytes loop
663 Exponent := Exponent * BB + Long_Unsigned (S (N));
664 end loop;
666 Exponent := Shift_Right (Exponent, Integer (E_Bytes) * SU - E_Size - 1);
668 -- NaN or Infinities
670 if Integer (Exponent) = E_Last then
671 raise Constraint_Error;
673 elsif Exponent = 0 then
675 -- Signed zeros
677 if Fraction_1 = 0 and then Fraction_2 = 0 then
678 null;
680 -- Denormalized float
682 else
683 Result := Long_Long_Float'Scaling (Result, 1 - E_Bias);
684 end if;
686 -- Normalized float
688 else
689 Result := Long_Long_Float'Scaling
690 (1.0 + Result, Integer (Exponent) - E_Bias);
691 end if;
693 if not Is_Positive then
694 Result := -Result;
695 end if;
697 return Result;
698 end I_LLF;
700 -----------
701 -- I_LLI --
702 -----------
704 function I_LLI (Stream : not null access RST) return Long_Long_Integer is
705 S : XDR_S_LLI;
706 L : SEO;
707 U : Unsigned := 0;
708 X : Long_Long_Unsigned := 0;
710 begin
711 Ada.Streams.Read (Stream.all, S, L);
713 if L /= S'Last then
714 raise Data_Error;
716 elsif Optimize_Integers then
717 return XDR_S_LLI_To_Long_Long_Integer (S);
719 else
720 -- Compute using machine unsigned for computing
721 -- rather than long_long_unsigned.
723 for N in S'Range loop
724 U := U * BB + Unsigned (S (N));
726 -- We have filled an unsigned
728 if N mod UB = 0 then
729 X := Shift_Left (X, US) + Long_Long_Unsigned (U);
730 U := 0;
731 end if;
732 end loop;
734 -- Test sign and apply two complement notation
736 if S (1) < BL then
737 return Long_Long_Integer (X);
738 else
739 return Long_Long_Integer (-((Long_Long_Unsigned'Last xor X) + 1));
740 end if;
741 end if;
742 end I_LLI;
744 -----------
745 -- I_LLU --
746 -----------
748 function I_LLU (Stream : not null access RST) return Long_Long_Unsigned is
749 S : XDR_S_LLU;
750 L : SEO;
751 U : Unsigned := 0;
752 X : Long_Long_Unsigned := 0;
754 begin
755 Ada.Streams.Read (Stream.all, S, L);
757 if L /= S'Last then
758 raise Data_Error;
760 elsif Optimize_Integers then
761 return XDR_S_LLU_To_Long_Long_Unsigned (S);
763 else
764 -- Compute using machine unsigned
765 -- rather than long_long_unsigned.
767 for N in S'Range loop
768 U := U * BB + Unsigned (S (N));
770 -- We have filled an unsigned
772 if N mod UB = 0 then
773 X := Shift_Left (X, US) + Long_Long_Unsigned (U);
774 U := 0;
775 end if;
776 end loop;
778 return X;
779 end if;
780 end I_LLU;
782 ----------
783 -- I_LU --
784 ----------
786 function I_LU (Stream : not null access RST) return Long_Unsigned is
787 S : XDR_S_LU;
788 L : SEO;
789 U : Unsigned := 0;
790 X : Long_Unsigned := 0;
792 begin
793 Ada.Streams.Read (Stream.all, S, L);
795 if L /= S'Last then
796 raise Data_Error;
798 elsif Optimize_Integers then
799 return Long_Unsigned (XDR_S_LU_To_Long_Long_Unsigned (S));
801 else
802 -- Compute using machine unsigned
803 -- rather than long_unsigned.
805 for N in S'Range loop
806 U := U * BB + Unsigned (S (N));
808 -- We have filled an unsigned
810 if N mod UB = 0 then
811 X := Shift_Left (X, US) + Long_Unsigned (U);
812 U := 0;
813 end if;
814 end loop;
816 return X;
817 end if;
818 end I_LU;
820 ----------
821 -- I_SF --
822 ----------
824 function I_SF (Stream : not null access RST) return Short_Float is
825 I : constant Precision := Single;
826 E_Size : Integer renames Fields (I).E_Size;
827 E_Bias : Integer renames Fields (I).E_Bias;
828 E_Last : Integer renames Fields (I).E_Last;
829 F_Mask : SE renames Fields (I).F_Mask;
830 E_Bytes : SEO renames Fields (I).E_Bytes;
831 F_Bytes : SEO renames Fields (I).F_Bytes;
832 F_Size : Integer renames Fields (I).F_Size;
834 Exponent : Long_Unsigned;
835 Fraction : Long_Unsigned;
836 Is_Positive : Boolean;
837 Result : Short_Float;
838 S : SEA (1 .. SF_L);
839 L : SEO;
841 begin
842 Ada.Streams.Read (Stream.all, S, L);
844 if L /= S'Last then
845 raise Data_Error;
846 end if;
848 -- Extract Fraction, Sign and Exponent
850 Fraction := Long_Unsigned (S (SF_L + 1 - F_Bytes) and F_Mask);
851 for N in SF_L + 2 - F_Bytes .. SF_L loop
852 Fraction := Fraction * BB + Long_Unsigned (S (N));
853 end loop;
854 Result := Short_Float'Scaling (Short_Float (Fraction), -F_Size);
856 if BS <= S (1) then
857 Is_Positive := False;
858 Exponent := Long_Unsigned (S (1) - BS);
859 else
860 Is_Positive := True;
861 Exponent := Long_Unsigned (S (1));
862 end if;
864 for N in 2 .. E_Bytes loop
865 Exponent := Exponent * BB + Long_Unsigned (S (N));
866 end loop;
867 Exponent := Shift_Right (Exponent, Integer (E_Bytes) * SU - E_Size - 1);
869 -- NaN or Infinities
871 if Integer (Exponent) = E_Last then
872 raise Constraint_Error;
874 elsif Exponent = 0 then
876 -- Signed zeros
878 if Fraction = 0 then
879 null;
881 -- Denormalized float
883 else
884 Result := Short_Float'Scaling (Result, 1 - E_Bias);
885 end if;
887 -- Normalized float
889 else
890 Result := Short_Float'Scaling
891 (1.0 + Result, Integer (Exponent) - E_Bias);
892 end if;
894 if not Is_Positive then
895 Result := -Result;
896 end if;
898 return Result;
899 end I_SF;
901 ----------
902 -- I_SI --
903 ----------
905 function I_SI (Stream : not null access RST) return Short_Integer is
906 S : XDR_S_SI;
907 L : SEO;
908 U : XDR_SU := 0;
910 begin
911 Ada.Streams.Read (Stream.all, S, L);
913 if L /= S'Last then
914 raise Data_Error;
916 elsif Optimize_Integers then
917 return XDR_S_SI_To_Short_Integer (S);
919 else
920 for N in S'Range loop
921 U := U * BB + XDR_SU (S (N));
922 end loop;
924 -- Test sign and apply two complement notation
926 if S (1) < BL then
927 return Short_Integer (U);
928 else
929 return Short_Integer (-((XDR_SU'Last xor U) + 1));
930 end if;
931 end if;
932 end I_SI;
934 -----------
935 -- I_SSI --
936 -----------
938 function I_SSI (Stream : not null access RST) return Short_Short_Integer is
939 S : XDR_S_SSI;
940 L : SEO;
941 U : XDR_SSU;
943 begin
944 Ada.Streams.Read (Stream.all, S, L);
946 if L /= S'Last then
947 raise Data_Error;
949 elsif Optimize_Integers then
950 return XDR_S_SSI_To_Short_Short_Integer (S);
952 else
953 U := XDR_SSU (S (1));
955 -- Test sign and apply two complement notation
957 if S (1) < BL then
958 return Short_Short_Integer (U);
959 else
960 return Short_Short_Integer (-((XDR_SSU'Last xor U) + 1));
961 end if;
962 end if;
963 end I_SSI;
965 -----------
966 -- I_SSU --
967 -----------
969 function I_SSU (Stream : not null access RST) return Short_Short_Unsigned is
970 S : XDR_S_SSU;
971 L : SEO;
972 U : XDR_SSU := 0;
974 begin
975 Ada.Streams.Read (Stream.all, S, L);
977 if L /= S'Last then
978 raise Data_Error;
980 else
981 U := XDR_SSU (S (1));
982 return Short_Short_Unsigned (U);
983 end if;
984 end I_SSU;
986 ----------
987 -- I_SU --
988 ----------
990 function I_SU (Stream : not null access RST) return Short_Unsigned is
991 S : XDR_S_SU;
992 L : SEO;
993 U : XDR_SU := 0;
995 begin
996 Ada.Streams.Read (Stream.all, S, L);
998 if L /= S'Last then
999 raise Data_Error;
1001 elsif Optimize_Integers then
1002 return XDR_S_SU_To_Short_Unsigned (S);
1004 else
1005 for N in S'Range loop
1006 U := U * BB + XDR_SU (S (N));
1007 end loop;
1009 return Short_Unsigned (U);
1010 end if;
1011 end I_SU;
1013 ---------
1014 -- I_U --
1015 ---------
1017 function I_U (Stream : not null access RST) return Unsigned is
1018 S : XDR_S_U;
1019 L : SEO;
1020 U : XDR_U := 0;
1022 begin
1023 Ada.Streams.Read (Stream.all, S, L);
1025 if L /= S'Last then
1026 raise Data_Error;
1028 elsif Optimize_Integers then
1029 return XDR_S_U_To_Unsigned (S);
1031 else
1032 for N in S'Range loop
1033 U := U * BB + XDR_U (S (N));
1034 end loop;
1036 return Unsigned (U);
1037 end if;
1038 end I_U;
1040 ----------
1041 -- I_WC --
1042 ----------
1044 function I_WC (Stream : not null access RST) return Wide_Character is
1045 S : XDR_S_WC;
1046 L : SEO;
1047 U : XDR_WC := 0;
1049 begin
1050 Ada.Streams.Read (Stream.all, S, L);
1052 if L /= S'Last then
1053 raise Data_Error;
1055 else
1056 for N in S'Range loop
1057 U := U * BB + XDR_WC (S (N));
1058 end loop;
1060 -- Use Ada requirements on Wide_Character representation clause
1062 return Wide_Character'Val (U);
1063 end if;
1064 end I_WC;
1066 -----------
1067 -- I_WWC --
1068 -----------
1070 function I_WWC (Stream : not null access RST) return Wide_Wide_Character is
1071 S : XDR_S_WWC;
1072 L : SEO;
1073 U : XDR_WWC := 0;
1075 begin
1076 Ada.Streams.Read (Stream.all, S, L);
1078 if L /= S'Last then
1079 raise Data_Error;
1081 else
1082 for N in S'Range loop
1083 U := U * BB + XDR_WWC (S (N));
1084 end loop;
1086 -- Use Ada requirements on Wide_Wide_Character representation clause
1088 return Wide_Wide_Character'Val (U);
1089 end if;
1090 end I_WWC;
1092 ----------
1093 -- W_AD --
1094 ----------
1096 procedure W_AD (Stream : not null access RST; Item : Fat_Pointer) is
1097 S : XDR_S_TM;
1098 U : XDR_TM;
1100 begin
1101 U := XDR_TM (To_XDR_SA (Item.P1));
1102 for N in reverse S'Range loop
1103 S (N) := SE (U mod BB);
1104 U := U / BB;
1105 end loop;
1107 Ada.Streams.Write (Stream.all, S);
1109 U := XDR_TM (To_XDR_SA (Item.P2));
1110 for N in reverse S'Range loop
1111 S (N) := SE (U mod BB);
1112 U := U / BB;
1113 end loop;
1115 Ada.Streams.Write (Stream.all, S);
1117 if U /= 0 then
1118 raise Data_Error;
1119 end if;
1120 end W_AD;
1122 ----------
1123 -- W_AS --
1124 ----------
1126 procedure W_AS (Stream : not null access RST; Item : Thin_Pointer) is
1127 S : XDR_S_TM;
1128 U : XDR_TM := XDR_TM (To_XDR_SA (Item.P1));
1130 begin
1131 for N in reverse S'Range loop
1132 S (N) := SE (U mod BB);
1133 U := U / BB;
1134 end loop;
1136 Ada.Streams.Write (Stream.all, S);
1138 if U /= 0 then
1139 raise Data_Error;
1140 end if;
1141 end W_AS;
1143 ---------
1144 -- W_B --
1145 ---------
1147 procedure W_B (Stream : not null access RST; Item : Boolean) is
1148 begin
1149 if Item then
1150 W_SSU (Stream, 1);
1151 else
1152 W_SSU (Stream, 0);
1153 end if;
1154 end W_B;
1156 ---------
1157 -- W_C --
1158 ---------
1160 procedure W_C (Stream : not null access RST; Item : Character) is
1161 S : XDR_S_C;
1163 pragma Assert (C_L = 1);
1165 begin
1166 -- Use Ada requirements on Character representation clause
1168 S (1) := SE (Character'Pos (Item));
1170 Ada.Streams.Write (Stream.all, S);
1171 end W_C;
1173 ---------
1174 -- W_F --
1175 ---------
1177 procedure W_F (Stream : not null access RST; Item : Float) is
1178 I : constant Precision := Single;
1179 E_Size : Integer renames Fields (I).E_Size;
1180 E_Bias : Integer renames Fields (I).E_Bias;
1181 E_Bytes : SEO renames Fields (I).E_Bytes;
1182 F_Bytes : SEO renames Fields (I).F_Bytes;
1183 F_Size : Integer renames Fields (I).F_Size;
1184 F_Mask : SE renames Fields (I).F_Mask;
1186 Exponent : Long_Unsigned;
1187 Fraction : Long_Unsigned;
1188 Is_Positive : Boolean;
1189 E : Integer;
1190 F : Float;
1191 S : SEA (1 .. F_L) := (others => 0);
1193 begin
1194 if not Item'Valid then
1195 raise Constraint_Error;
1196 end if;
1198 -- Compute Sign
1200 Is_Positive := (0.0 <= Item);
1201 F := abs (Item);
1203 -- Signed zero
1205 if F = 0.0 then
1206 Exponent := 0;
1207 Fraction := 0;
1209 else
1210 E := Float'Exponent (F) - 1;
1212 -- Denormalized float
1214 if E <= -E_Bias then
1215 F := Float'Scaling (F, F_Size + E_Bias - 1);
1216 E := -E_Bias;
1217 else
1218 F := Float'Scaling (Float'Fraction (F), F_Size + 1);
1219 end if;
1221 -- Compute Exponent and Fraction
1223 Exponent := Long_Unsigned (E + E_Bias);
1224 Fraction := Long_Unsigned (F * 2.0) / 2;
1225 end if;
1227 -- Store Fraction
1229 for I in reverse F_L - F_Bytes + 1 .. F_L loop
1230 S (I) := SE (Fraction mod BB);
1231 Fraction := Fraction / BB;
1232 end loop;
1234 -- Remove implicit bit
1236 S (F_L - F_Bytes + 1) := S (F_L - F_Bytes + 1) and F_Mask;
1238 -- Store Exponent (not always at the beginning of a byte)
1240 Exponent := Shift_Left (Exponent, Integer (E_Bytes) * SU - E_Size - 1);
1241 for N in reverse 1 .. E_Bytes loop
1242 S (N) := SE (Exponent mod BB) + S (N);
1243 Exponent := Exponent / BB;
1244 end loop;
1246 -- Store Sign
1248 if not Is_Positive then
1249 S (1) := S (1) + BS;
1250 end if;
1252 Ada.Streams.Write (Stream.all, S);
1253 end W_F;
1255 ---------
1256 -- W_I --
1257 ---------
1259 procedure W_I (Stream : not null access RST; Item : Integer) is
1260 S : XDR_S_I;
1261 U : XDR_U;
1263 begin
1264 if Optimize_Integers then
1265 S := Integer_To_XDR_S_I (Item);
1267 else
1268 -- Test sign and apply two complement notation
1270 U := (if Item < 0
1271 then XDR_U'Last xor XDR_U (-(Item + 1))
1272 else XDR_U (Item));
1274 for N in reverse S'Range loop
1275 S (N) := SE (U mod BB);
1276 U := U / BB;
1277 end loop;
1279 if U /= 0 then
1280 raise Data_Error;
1281 end if;
1282 end if;
1284 Ada.Streams.Write (Stream.all, S);
1285 end W_I;
1287 ----------
1288 -- W_LF --
1289 ----------
1291 procedure W_LF (Stream : not null access RST; Item : Long_Float) is
1292 I : constant Precision := Double;
1293 E_Size : Integer renames Fields (I).E_Size;
1294 E_Bias : Integer renames Fields (I).E_Bias;
1295 E_Bytes : SEO renames Fields (I).E_Bytes;
1296 F_Bytes : SEO renames Fields (I).F_Bytes;
1297 F_Size : Integer renames Fields (I).F_Size;
1298 F_Mask : SE renames Fields (I).F_Mask;
1300 Exponent : Long_Unsigned;
1301 Fraction : Long_Long_Unsigned;
1302 Is_Positive : Boolean;
1303 E : Integer;
1304 F : Long_Float;
1305 S : SEA (1 .. LF_L) := (others => 0);
1307 begin
1308 if not Item'Valid then
1309 raise Constraint_Error;
1310 end if;
1312 -- Compute Sign
1314 Is_Positive := (0.0 <= Item);
1315 F := abs (Item);
1317 -- Signed zero
1319 if F = 0.0 then
1320 Exponent := 0;
1321 Fraction := 0;
1323 else
1324 E := Long_Float'Exponent (F) - 1;
1326 -- Denormalized float
1328 if E <= -E_Bias then
1329 E := -E_Bias;
1330 F := Long_Float'Scaling (F, F_Size + E_Bias - 1);
1331 else
1332 F := Long_Float'Scaling (F, F_Size - E);
1333 end if;
1335 -- Compute Exponent and Fraction
1337 Exponent := Long_Unsigned (E + E_Bias);
1338 Fraction := Long_Long_Unsigned (F * 2.0) / 2;
1339 end if;
1341 -- Store Fraction
1343 for I in reverse LF_L - F_Bytes + 1 .. LF_L loop
1344 S (I) := SE (Fraction mod BB);
1345 Fraction := Fraction / BB;
1346 end loop;
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;
1358 end loop;
1360 -- Store Sign
1362 if not Is_Positive then
1363 S (1) := S (1) + BS;
1364 end if;
1366 Ada.Streams.Write (Stream.all, S);
1367 end W_LF;
1369 ----------
1370 -- W_LI --
1371 ----------
1373 procedure W_LI (Stream : not null access RST; Item : Long_Integer) is
1374 S : XDR_S_LI;
1375 U : Unsigned;
1376 X : Long_Unsigned;
1378 begin
1379 if Optimize_Integers then
1380 S := Long_Long_Integer_To_XDR_S_LI (Long_Long_Integer (Item));
1382 else
1383 -- Test sign and apply two complement notation
1385 if Item < 0 then
1386 X := Long_Unsigned'Last xor Long_Unsigned (-(Item + 1));
1387 else
1388 X := Long_Unsigned (Item);
1389 end if;
1391 -- Compute using machine unsigned rather than long_unsigned
1393 for N in reverse S'Range loop
1395 -- We have filled an unsigned
1397 if (LU_L - N) mod UB = 0 then
1398 U := Unsigned (X and UL);
1399 X := Shift_Right (X, US);
1400 end if;
1402 S (N) := SE (U mod BB);
1403 U := U / BB;
1404 end loop;
1406 if U /= 0 then
1407 raise Data_Error;
1408 end if;
1409 end if;
1411 Ada.Streams.Write (Stream.all, S);
1412 end W_LI;
1414 -----------
1415 -- W_LLF --
1416 -----------
1418 procedure W_LLF (Stream : not null access RST; Item : Long_Long_Float) is
1419 I : constant Precision := Quadruple;
1420 E_Size : Integer renames Fields (I).E_Size;
1421 E_Bias : Integer renames Fields (I).E_Bias;
1422 E_Bytes : SEO renames Fields (I).E_Bytes;
1423 F_Bytes : SEO renames Fields (I).F_Bytes;
1424 F_Size : Integer renames Fields (I).F_Size;
1426 HFS : constant Integer := F_Size / 2;
1428 Exponent : Long_Unsigned;
1429 Fraction_1 : Long_Long_Unsigned;
1430 Fraction_2 : Long_Long_Unsigned;
1431 Is_Positive : Boolean;
1432 E : Integer;
1433 F : Long_Long_Float := Item;
1434 S : SEA (1 .. LLF_L) := (others => 0);
1436 begin
1437 if not Item'Valid then
1438 raise Constraint_Error;
1439 end if;
1441 -- Compute Sign
1443 Is_Positive := (0.0 <= Item);
1445 if F < 0.0 then
1446 F := -Item;
1447 end if;
1449 -- Signed zero
1451 if F = 0.0 then
1452 Exponent := 0;
1453 Fraction_1 := 0;
1454 Fraction_2 := 0;
1456 else
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);
1463 E := -E_Bias;
1464 else
1465 F := Long_Long_Float'Scaling
1466 (Long_Long_Float'Fraction (F), 1);
1467 end if;
1469 -- Compute Exponent and Fraction
1471 Exponent := Long_Unsigned (E + E_Bias);
1472 F := Long_Long_Float'Scaling (F, F_Size - HFS);
1473 Fraction_1 := Long_Long_Unsigned (Long_Long_Float'Floor (F));
1474 F := F - Long_Long_Float (Fraction_1);
1475 F := Long_Long_Float'Scaling (F, HFS);
1476 Fraction_2 := Long_Long_Unsigned (Long_Long_Float'Floor (F));
1477 end if;
1479 -- Store Fraction_1
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;
1484 end loop;
1486 -- Store Fraction_2
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;
1491 end loop;
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;
1499 end loop;
1501 -- Store Sign
1503 if not Is_Positive then
1504 S (1) := S (1) + BS;
1505 end if;
1507 Ada.Streams.Write (Stream.all, S);
1508 end W_LLF;
1510 -----------
1511 -- W_LLI --
1512 -----------
1514 procedure W_LLI
1515 (Stream : not null access RST;
1516 Item : Long_Long_Integer)
1518 S : XDR_S_LLI;
1519 U : Unsigned;
1520 X : Long_Long_Unsigned;
1522 begin
1523 if Optimize_Integers then
1524 S := Long_Long_Integer_To_XDR_S_LLI (Item);
1526 else
1527 -- Test sign and apply two complement notation
1529 if Item < 0 then
1530 X := Long_Long_Unsigned'Last xor Long_Long_Unsigned (-(Item + 1));
1531 else
1532 X := Long_Long_Unsigned (Item);
1533 end if;
1535 -- Compute using machine unsigned rather than long_long_unsigned
1537 for N in reverse S'Range loop
1539 -- We have filled an unsigned
1541 if (LLU_L - N) mod UB = 0 then
1542 U := Unsigned (X and UL);
1543 X := Shift_Right (X, US);
1544 end if;
1546 S (N) := SE (U mod BB);
1547 U := U / BB;
1548 end loop;
1550 if U /= 0 then
1551 raise Data_Error;
1552 end if;
1553 end if;
1555 Ada.Streams.Write (Stream.all, S);
1556 end W_LLI;
1558 -----------
1559 -- W_LLU --
1560 -----------
1562 procedure W_LLU
1563 (Stream : not null access RST;
1564 Item : Long_Long_Unsigned)
1566 S : XDR_S_LLU;
1567 U : Unsigned;
1568 X : Long_Long_Unsigned := Item;
1570 begin
1571 if Optimize_Integers then
1572 S := Long_Long_Unsigned_To_XDR_S_LLU (Item);
1574 else
1575 -- Compute using machine unsigned rather than long_long_unsigned
1577 for N in reverse S'Range loop
1579 -- We have filled an unsigned
1581 if (LLU_L - N) mod UB = 0 then
1582 U := Unsigned (X and UL);
1583 X := Shift_Right (X, US);
1584 end if;
1586 S (N) := SE (U mod BB);
1587 U := U / BB;
1588 end loop;
1590 if U /= 0 then
1591 raise Data_Error;
1592 end if;
1593 end if;
1595 Ada.Streams.Write (Stream.all, S);
1596 end W_LLU;
1598 ----------
1599 -- W_LU --
1600 ----------
1602 procedure W_LU (Stream : not null access RST; Item : Long_Unsigned) is
1603 S : XDR_S_LU;
1604 U : Unsigned;
1605 X : Long_Unsigned := Item;
1607 begin
1608 if Optimize_Integers then
1609 S := Long_Long_Unsigned_To_XDR_S_LU (Long_Long_Unsigned (Item));
1611 else
1612 -- Compute using machine unsigned rather than long_unsigned
1614 for N in reverse S'Range loop
1616 -- We have filled an unsigned
1618 if (LU_L - N) mod UB = 0 then
1619 U := Unsigned (X and UL);
1620 X := Shift_Right (X, US);
1621 end if;
1622 S (N) := SE (U mod BB);
1623 U := U / BB;
1624 end loop;
1626 if U /= 0 then
1627 raise Data_Error;
1628 end if;
1629 end if;
1631 Ada.Streams.Write (Stream.all, S);
1632 end W_LU;
1634 ----------
1635 -- W_SF --
1636 ----------
1638 procedure W_SF (Stream : not null access RST; Item : Short_Float) is
1639 I : constant Precision := Single;
1640 E_Size : Integer renames Fields (I).E_Size;
1641 E_Bias : Integer renames Fields (I).E_Bias;
1642 E_Bytes : SEO renames Fields (I).E_Bytes;
1643 F_Bytes : SEO renames Fields (I).F_Bytes;
1644 F_Size : Integer renames Fields (I).F_Size;
1645 F_Mask : SE renames Fields (I).F_Mask;
1647 Exponent : Long_Unsigned;
1648 Fraction : Long_Unsigned;
1649 Is_Positive : Boolean;
1650 E : Integer;
1651 F : Short_Float;
1652 S : SEA (1 .. SF_L) := (others => 0);
1654 begin
1655 if not Item'Valid then
1656 raise Constraint_Error;
1657 end if;
1659 -- Compute Sign
1661 Is_Positive := (0.0 <= Item);
1662 F := abs (Item);
1664 -- Signed zero
1666 if F = 0.0 then
1667 Exponent := 0;
1668 Fraction := 0;
1670 else
1671 E := Short_Float'Exponent (F) - 1;
1673 -- Denormalized float
1675 if E <= -E_Bias then
1676 E := -E_Bias;
1677 F := Short_Float'Scaling (F, F_Size + E_Bias - 1);
1678 else
1679 F := Short_Float'Scaling (F, F_Size - E);
1680 end if;
1682 -- Compute Exponent and Fraction
1684 Exponent := Long_Unsigned (E + E_Bias);
1685 Fraction := Long_Unsigned (F * 2.0) / 2;
1686 end if;
1688 -- Store Fraction
1690 for I in reverse SF_L - F_Bytes + 1 .. SF_L loop
1691 S (I) := SE (Fraction mod BB);
1692 Fraction := Fraction / BB;
1693 end loop;
1695 -- Remove implicit bit
1697 S (SF_L - F_Bytes + 1) := S (SF_L - F_Bytes + 1) and F_Mask;
1699 -- Store Exponent (not always at the beginning of a byte)
1701 Exponent := Shift_Left (Exponent, Integer (E_Bytes) * SU - E_Size - 1);
1702 for N in reverse 1 .. E_Bytes loop
1703 S (N) := SE (Exponent mod BB) + S (N);
1704 Exponent := Exponent / BB;
1705 end loop;
1707 -- Store Sign
1709 if not Is_Positive then
1710 S (1) := S (1) + BS;
1711 end if;
1713 Ada.Streams.Write (Stream.all, S);
1714 end W_SF;
1716 ----------
1717 -- W_SI --
1718 ----------
1720 procedure W_SI (Stream : not null access RST; Item : Short_Integer) is
1721 S : XDR_S_SI;
1722 U : XDR_SU;
1724 begin
1725 if Optimize_Integers then
1726 S := Short_Integer_To_XDR_S_SI (Item);
1728 else
1729 -- Test sign and apply two complement's notation
1731 U := (if Item < 0
1732 then XDR_SU'Last xor XDR_SU (-(Item + 1))
1733 else XDR_SU (Item));
1735 for N in reverse S'Range loop
1736 S (N) := SE (U mod BB);
1737 U := U / BB;
1738 end loop;
1740 if U /= 0 then
1741 raise Data_Error;
1742 end if;
1743 end if;
1745 Ada.Streams.Write (Stream.all, S);
1746 end W_SI;
1748 -----------
1749 -- W_SSI --
1750 -----------
1752 procedure W_SSI
1753 (Stream : not null access RST;
1754 Item : Short_Short_Integer)
1756 S : XDR_S_SSI;
1757 U : XDR_SSU;
1759 begin
1760 if Optimize_Integers then
1761 S := Short_Short_Integer_To_XDR_S_SSI (Item);
1763 else
1764 -- Test sign and apply two complement's notation
1766 U := (if Item < 0
1767 then XDR_SSU'Last xor XDR_SSU (-(Item + 1))
1768 else XDR_SSU (Item));
1770 S (1) := SE (U);
1771 end if;
1773 Ada.Streams.Write (Stream.all, S);
1774 end W_SSI;
1776 -----------
1777 -- W_SSU --
1778 -----------
1780 procedure W_SSU
1781 (Stream : not null access RST;
1782 Item : Short_Short_Unsigned)
1784 U : constant XDR_SSU := XDR_SSU (Item);
1785 S : XDR_S_SSU;
1787 begin
1788 S (1) := SE (U);
1789 Ada.Streams.Write (Stream.all, S);
1790 end W_SSU;
1792 ----------
1793 -- W_SU --
1794 ----------
1796 procedure W_SU (Stream : not null access RST; Item : Short_Unsigned) is
1797 S : XDR_S_SU;
1798 U : XDR_SU := XDR_SU (Item);
1800 begin
1801 if Optimize_Integers then
1802 S := Short_Unsigned_To_XDR_S_SU (Item);
1804 else
1805 for N in reverse S'Range loop
1806 S (N) := SE (U mod BB);
1807 U := U / BB;
1808 end loop;
1810 if U /= 0 then
1811 raise Data_Error;
1812 end if;
1813 end if;
1815 Ada.Streams.Write (Stream.all, S);
1816 end W_SU;
1818 ---------
1819 -- W_U --
1820 ---------
1822 procedure W_U (Stream : not null access RST; Item : Unsigned) is
1823 S : XDR_S_U;
1824 U : XDR_U := XDR_U (Item);
1826 begin
1827 if Optimize_Integers then
1828 S := Unsigned_To_XDR_S_U (Item);
1830 else
1831 for N in reverse S'Range loop
1832 S (N) := SE (U mod BB);
1833 U := U / BB;
1834 end loop;
1836 if U /= 0 then
1837 raise Data_Error;
1838 end if;
1839 end if;
1841 Ada.Streams.Write (Stream.all, S);
1842 end W_U;
1844 ----------
1845 -- W_WC --
1846 ----------
1848 procedure W_WC (Stream : not null access RST; Item : Wide_Character) is
1849 S : XDR_S_WC;
1850 U : XDR_WC;
1852 begin
1853 -- Use Ada requirements on Wide_Character representation clause
1855 U := XDR_WC (Wide_Character'Pos (Item));
1857 for N in reverse S'Range loop
1858 S (N) := SE (U mod BB);
1859 U := U / BB;
1860 end loop;
1862 Ada.Streams.Write (Stream.all, S);
1864 if U /= 0 then
1865 raise Data_Error;
1866 end if;
1867 end W_WC;
1869 -----------
1870 -- W_WWC --
1871 -----------
1873 procedure W_WWC
1874 (Stream : not null access RST; Item : Wide_Wide_Character)
1876 S : XDR_S_WWC;
1877 U : XDR_WWC;
1879 begin
1880 -- Use Ada requirements on Wide_Wide_Character representation clause
1882 U := XDR_WWC (Wide_Wide_Character'Pos (Item));
1884 for N in reverse S'Range loop
1885 S (N) := SE (U mod BB);
1886 U := U / BB;
1887 end loop;
1889 Ada.Streams.Write (Stream.all, S);
1891 if U /= 0 then
1892 raise Data_Error;
1893 end if;
1894 end W_WWC;
1896 end System.Stream_Attributes;