-- --
-- B o d y --
-- --
--- Copyright (C) 1996-2005 Free Software Foundation, Inc. --
+-- Copyright (C) 1996-2009, Free Software Foundation, Inc. --
-- --
-- GARLIC is free software; you can redistribute it and/or modify it under --
--- terms of the GNU General Public License as published by the Free Soft- --
--- ware Foundation; either version 2, or (at your option) any later ver- --
--- sion. GARLIC is distributed in the hope that it will be useful, but --
--- WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABI- --
--- LITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public --
--- License for more details. You should have received a copy of the GNU --
--- General Public License distributed with GARLIC; see file COPYING. If --
--- not, write to the Free Software Foundation, 51 Franklin Street, Fifth --
--- Floor, Boston, MA 02110-1301, USA. --
+-- terms of the GNU General Public License as published by the Free Soft- --
+-- ware Foundation; either version 3, or (at your option) any later ver- --
+-- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
+-- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
+-- or FITNESS FOR A PARTICULAR PURPOSE. --
-- --
--- As a special exception, if other files instantiate generics from this --
--- unit, or you link this unit with other files to produce an executable, --
--- this unit does not by itself cause the resulting executable to be --
--- covered by the GNU General Public License. This exception does not --
--- however invalidate any other reasons why the executable file might be --
--- covered by the GNU Public License. --
+-- As a special exception under Section 7 of GPL version 3, you are granted --
+-- additional permissions described in the GCC Runtime Library Exception, --
+-- version 3.1, as published by the Free Software Foundation. --
+-- --
+-- You should have received a copy of the GNU General Public License and --
+-- a copy of the GCC Runtime Library Exception along with this program; --
+-- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --
+-- <http://www.gnu.org/licenses/>. --
-- --
-- GNAT was originally developed by the GNAT team at New York University. --
-- Extensive contributions were provided by Ada Core Technologies Inc. --
-- This file is an alternate version of s-stratt.adb based on the XDR
-- standard. It is especially useful for exchanging streams between two
--- different systems with different basic type representations and endianess.
+-- different systems with different basic type representations and endianness.
with Ada.IO_Exceptions;
with Ada.Streams; use Ada.Streams;
use UST;
Data_Error : exception renames Ada.IO_Exceptions.End_Error;
- -- Exception raised if insufficient data read (End_Error is
- -- mandated by AI95-00132).
+ -- Exception raised if insufficient data read (End_Error is mandated by
+ -- AI95-00132).
SU : constant := System.Storage_Unit;
- -- XXXXX pragma Assert (SU = 8);
+ -- The code in this body assumes that SU = 8
BB : constant := 2 ** SU; -- Byte base
BL : constant := 2 ** SU - 1; -- Byte last
F_Size : Integer; -- Fraction bit size
E_Last : Integer; -- Max exponent value
F_Mask : SE; -- Mask to apply on first fraction byte
- E_Bytes : SEO; -- N. of exponent bytes completly used
- F_Bytes : SEO; -- N. of fraction bytes completly used
+ E_Bytes : SEO; -- N. of exponent bytes completely used
+ F_Bytes : SEO; -- N. of fraction bytes completely used
F_Bits : Integer; -- N. of bits used on first fraction word
end record;
-- in the range [-2147483648,2147483647]. The integer is represented
-- in two's complement notation. The most and least significant bytes
-- are 0 and 3, respectively. Integers are declared as follows:
- --
+
-- (MSB) (LSB)
-- +-------+-------+-------+-------+
-- |byte 0 |byte 1 |byte 2 |byte 3 |
-- integer in the range [0,4294967295]. It is represented by an unsigned
-- binary number whose most and least significant bytes are 0 and 3,
-- respectively. An unsigned integer is declared as follows:
- --
+
-- (MSB) (LSB)
-- +-------+-------+-------+-------+
-- |byte 0 |byte 1 |byte 2 |byte 3 |
-- or 4 bytes). The encoding used is the IEEE standard for normalized
-- single-precision floating-point numbers.
- -- The standard defines the encoding for the double-precision
- -- floating-point data type "double" (64 bits or 8 bytes). The
- -- encoding used is the IEEE standard for normalized double-precision
- -- floating-point numbers.
+ -- The standard defines the encoding used for the double-precision
+ -- floating-point data type "double" (64 bits or 8 bytes). The encoding
+ -- used is the IEEE standard for normalized double-precision floating-point
+ -- numbers.
SF_L : constant := 4; -- Single precision
F_L : constant := 4; -- Single precision
subtype XDR_S_WC is SEA (1 .. WC_L);
type XDR_WC is mod BB ** WC_L;
+ -- Consider Wide_Wide_Character as an enumeration type
+
+ WWC_L : constant := 8;
+ subtype XDR_S_WWC is SEA (1 .. WWC_L);
+ type XDR_WWC is mod BB ** WWC_L;
+
-- Optimization: if we already have the correct Bit_Order, then some
-- computations can be avoided since the source and the target will be
-- identical anyway. They will be replaced by direct unchecked
Optimize_Integers : constant Boolean :=
Default_Bit_Order = High_Order_First;
+ -----------------
+ -- Block_IO_OK --
+ -----------------
+
+ function Block_IO_OK return Boolean is
+ begin
+ return False;
+ end Block_IO_OK;
+
----------
-- I_AD --
----------
- function I_AD (Stream : access RST) return Fat_Pointer is
+ function I_AD (Stream : not null access RST) return Fat_Pointer is
FP : Fat_Pointer;
begin
-- I_AS --
----------
- function I_AS (Stream : access RST) return Thin_Pointer is
+ function I_AS (Stream : not null access RST) return Thin_Pointer is
S : XDR_S_TM;
L : SEO;
U : XDR_TM := 0;
if L /= S'Last then
raise Data_Error;
+
else
for N in S'Range loop
U := U * BB + XDR_TM (S (N));
-- I_B --
---------
- function I_B (Stream : access RST) return Boolean is
+ function I_B (Stream : not null access RST) return Boolean is
begin
case I_SSU (Stream) is
when 0 => return False;
-- I_C --
---------
- function I_C (Stream : access RST) return Character is
+ function I_C (Stream : not null access RST) return Character is
S : XDR_S_C;
L : SEO;
if L /= S'Last then
raise Data_Error;
- else
+ else
-- Use Ada requirements on Character representation clause
return Character'Val (S (1));
-- I_F --
---------
- function I_F (Stream : access RST) return Float is
+ function I_F (Stream : not null access RST) return Float is
I : constant Precision := Single;
E_Size : Integer renames Fields (I).E_Size;
E_Bias : Integer renames Fields (I).E_Bias;
-- I_I --
---------
- function I_I (Stream : access RST) return Integer is
+ function I_I (Stream : not null access RST) return Integer is
S : XDR_S_I;
L : SEO;
U : XDR_U := 0;
-- I_LF --
----------
- function I_LF (Stream : access RST) return Long_Float is
+ function I_LF (Stream : not null access RST) return Long_Float is
I : constant Precision := Double;
E_Size : Integer renames Fields (I).E_Size;
E_Bias : Integer renames Fields (I).E_Bias;
-- I_LI --
----------
- function I_LI (Stream : access RST) return Long_Integer is
+ function I_LI (Stream : not null access RST) return Long_Integer is
S : XDR_S_LI;
L : SEO;
U : Unsigned := 0;
-- I_LLF --
-----------
- function I_LLF (Stream : access RST) return Long_Long_Float is
+ function I_LLF (Stream : not null access RST) return Long_Long_Float is
I : constant Precision := Quadruple;
E_Size : Integer renames Fields (I).E_Size;
E_Bias : Integer renames Fields (I).E_Bias;
-- I_LLI --
-----------
- function I_LLI (Stream : access RST) return Long_Long_Integer is
+ function I_LLI (Stream : not null access RST) return Long_Long_Integer is
S : XDR_S_LLI;
L : SEO;
U : Unsigned := 0;
if L /= S'Last then
raise Data_Error;
+
elsif Optimize_Integers then
return XDR_S_LLI_To_Long_Long_Integer (S);
- else
+ else
-- Compute using machine unsigned for computing
-- rather than long_long_unsigned.
-- I_LLU --
-----------
- function I_LLU (Stream : access RST) return Long_Long_Unsigned is
+ function I_LLU (Stream : not null access RST) return Long_Long_Unsigned is
S : XDR_S_LLU;
L : SEO;
U : Unsigned := 0;
if L /= S'Last then
raise Data_Error;
+
elsif Optimize_Integers then
return XDR_S_LLU_To_Long_Long_Unsigned (S);
- else
+ else
-- Compute using machine unsigned
-- rather than long_long_unsigned.
-- I_LU --
----------
- function I_LU (Stream : access RST) return Long_Unsigned is
+ function I_LU (Stream : not null access RST) return Long_Unsigned is
S : XDR_S_LU;
L : SEO;
U : Unsigned := 0;
if L /= S'Last then
raise Data_Error;
+
elsif Optimize_Integers then
return Long_Unsigned (XDR_S_LU_To_Long_Long_Unsigned (S));
- else
+ else
-- Compute using machine unsigned
-- rather than long_unsigned.
-- I_SF --
----------
- function I_SF (Stream : access RST) return Short_Float is
+ function I_SF (Stream : not null access RST) return Short_Float is
I : constant Precision := Single;
E_Size : Integer renames Fields (I).E_Size;
E_Bias : Integer renames Fields (I).E_Bias;
-- I_SI --
----------
- function I_SI (Stream : access RST) return Short_Integer is
+ function I_SI (Stream : not null access RST) return Short_Integer is
S : XDR_S_SI;
L : SEO;
U : XDR_SU := 0;
-- I_SSI --
-----------
- function I_SSI (Stream : access RST) return Short_Short_Integer is
+ function I_SSI (Stream : not null access RST) return Short_Short_Integer is
S : XDR_S_SSI;
L : SEO;
U : XDR_SSU;
if L /= S'Last then
raise Data_Error;
+
elsif Optimize_Integers then
return XDR_S_SSI_To_Short_Short_Integer (S);
+
else
U := XDR_SSU (S (1));
-- I_SSU --
-----------
- function I_SSU (Stream : access RST) return Short_Short_Unsigned is
+ function I_SSU (Stream : not null access RST) return Short_Short_Unsigned is
S : XDR_S_SSU;
L : SEO;
U : XDR_SSU := 0;
if L /= S'Last then
raise Data_Error;
+
else
U := XDR_SSU (S (1));
-
return Short_Short_Unsigned (U);
end if;
end I_SSU;
-- I_SU --
----------
- function I_SU (Stream : access RST) return Short_Unsigned is
+ function I_SU (Stream : not null access RST) return Short_Unsigned is
S : XDR_S_SU;
L : SEO;
U : XDR_SU := 0;
if L /= S'Last then
raise Data_Error;
+
elsif Optimize_Integers then
return XDR_S_SU_To_Short_Unsigned (S);
+
else
for N in S'Range loop
U := U * BB + XDR_SU (S (N));
-- I_U --
---------
- function I_U (Stream : access RST) return Unsigned is
+ function I_U (Stream : not null access RST) return Unsigned is
S : XDR_S_U;
L : SEO;
U : XDR_U := 0;
-- I_WC --
----------
- function I_WC (Stream : access RST) return Wide_Character is
+ function I_WC (Stream : not null access RST) return Wide_Character is
S : XDR_S_WC;
L : SEO;
U : XDR_WC := 0;
if L /= S'Last then
raise Data_Error;
+
else
for N in S'Range loop
U := U * BB + XDR_WC (S (N));
end if;
end I_WC;
+ -----------
+ -- I_WWC --
+ -----------
+
+ function I_WWC (Stream : not null access RST) return Wide_Wide_Character is
+ S : XDR_S_WWC;
+ L : SEO;
+ U : XDR_WWC := 0;
+
+ begin
+ Ada.Streams.Read (Stream.all, S, L);
+
+ if L /= S'Last then
+ raise Data_Error;
+
+ else
+ for N in S'Range loop
+ U := U * BB + XDR_WWC (S (N));
+ end loop;
+
+ -- Use Ada requirements on Wide_Wide_Character representation clause
+
+ return Wide_Wide_Character'Val (U);
+ end if;
+ end I_WWC;
+
----------
-- W_AD --
----------
- procedure W_AD (Stream : access RST; Item : in Fat_Pointer) is
+ procedure W_AD (Stream : not null access RST; Item : Fat_Pointer) is
S : XDR_S_TM;
U : XDR_TM;
-- W_AS --
----------
- procedure W_AS (Stream : access RST; Item : in Thin_Pointer) is
+ procedure W_AS (Stream : not null access RST; Item : Thin_Pointer) is
S : XDR_S_TM;
U : XDR_TM := XDR_TM (To_XDR_SA (Item.P1));
-- W_B --
---------
- procedure W_B (Stream : access RST; Item : in Boolean) is
+ procedure W_B (Stream : not null access RST; Item : Boolean) is
begin
if Item then
W_SSU (Stream, 1);
-- W_C --
---------
- procedure W_C (Stream : access RST; Item : in Character) is
+ procedure W_C (Stream : not null access RST; Item : Character) is
S : XDR_S_C;
pragma Assert (C_L = 1);
begin
-
-- Use Ada requirements on Character representation clause
S (1) := SE (Character'Pos (Item));
-- W_F --
---------
- procedure W_F (Stream : access RST; Item : in Float) is
+ procedure W_F (Stream : not null access RST; Item : Float) is
I : constant Precision := Single;
E_Size : Integer renames Fields (I).E_Size;
E_Bias : Integer renames Fields (I).E_Bias;
-- W_I --
---------
- procedure W_I (Stream : access RST; Item : in Integer) is
+ procedure W_I (Stream : not null access RST; Item : Integer) is
S : XDR_S_I;
U : XDR_U;
begin
if Optimize_Integers then
S := Integer_To_XDR_S_I (Item);
- else
+ else
-- Test sign and apply two complement notation
if Item < 0 then
-- W_LF --
----------
- procedure W_LF (Stream : access RST; Item : in Long_Float) is
+ procedure W_LF (Stream : not null access RST; Item : Long_Float) is
I : constant Precision := Double;
E_Size : Integer renames Fields (I).E_Size;
E_Bias : Integer renames Fields (I).E_Bias;
-- W_LI --
----------
- procedure W_LI (Stream : access RST; Item : in Long_Integer) is
+ procedure W_LI (Stream : not null access RST; Item : Long_Integer) is
S : XDR_S_LI;
U : Unsigned;
X : Long_Unsigned;
begin
if Optimize_Integers then
S := Long_Long_Integer_To_XDR_S_LI (Long_Long_Integer (Item));
- else
+ else
-- Test sign and apply two complement notation
if Item < 0 then
-- W_LLF --
-----------
- procedure W_LLF (Stream : access RST; Item : in Long_Long_Float) is
+ procedure W_LLF (Stream : not null access RST; Item : Long_Long_Float) is
I : constant Precision := Quadruple;
E_Size : Integer renames Fields (I).E_Size;
E_Bias : Integer renames Fields (I).E_Bias;
-- W_LLI --
-----------
- procedure W_LLI (Stream : access RST; Item : in Long_Long_Integer) is
+ procedure W_LLI
+ (Stream : not null access RST;
+ Item : Long_Long_Integer)
+ is
S : XDR_S_LLI;
U : Unsigned;
X : Long_Long_Unsigned;
begin
if Optimize_Integers then
S := Long_Long_Integer_To_XDR_S_LLI (Item);
- else
+ else
-- Test sign and apply two complement notation
if Item < 0 then
-- W_LLU --
-----------
- procedure W_LLU (Stream : access RST; Item : in Long_Long_Unsigned) is
+ procedure W_LLU
+ (Stream : not null access RST;
+ Item : Long_Long_Unsigned)
+ is
S : XDR_S_LLU;
U : Unsigned;
X : Long_Long_Unsigned := Item;
begin
if Optimize_Integers then
S := Long_Long_Unsigned_To_XDR_S_LLU (Item);
+
else
-- Compute using machine unsigned
-- rather than long_long_unsigned.
-- W_LU --
----------
- procedure W_LU (Stream : access RST; Item : in Long_Unsigned) is
+ procedure W_LU (Stream : not null access RST; Item : Long_Unsigned) is
S : XDR_S_LU;
U : Unsigned;
X : Long_Unsigned := Item;
begin
if Optimize_Integers then
S := Long_Long_Unsigned_To_XDR_S_LU (Long_Long_Unsigned (Item));
+
else
-- Compute using machine unsigned
-- rather than long_unsigned.
-- W_SF --
----------
- procedure W_SF (Stream : access RST; Item : in Short_Float) is
+ procedure W_SF (Stream : not null access RST; Item : Short_Float) is
I : constant Precision := Single;
E_Size : Integer renames Fields (I).E_Size;
E_Bias : Integer renames Fields (I).E_Bias;
-- W_SI --
----------
- procedure W_SI (Stream : access RST; Item : in Short_Integer) is
+ procedure W_SI (Stream : not null access RST; Item : Short_Integer) is
S : XDR_S_SI;
U : XDR_SU;
begin
if Optimize_Integers then
S := Short_Integer_To_XDR_S_SI (Item);
- else
+ else
-- Test sign and apply two complement's notation
if Item < 0 then
-- W_SSI --
-----------
- procedure W_SSI (Stream : access RST; Item : in Short_Short_Integer) is
+ procedure W_SSI
+ (Stream : not null access RST;
+ Item : Short_Short_Integer)
+ is
S : XDR_S_SSI;
U : XDR_SSU;
begin
if Optimize_Integers then
S := Short_Short_Integer_To_XDR_S_SSI (Item);
- else
+ else
-- Test sign and apply two complement's notation
if Item < 0 then
-- W_SSU --
-----------
- procedure W_SSU (Stream : access RST; Item : in Short_Short_Unsigned) is
+ procedure W_SSU
+ (Stream : not null access RST;
+ Item : Short_Short_Unsigned)
+ is
+ U : constant XDR_SSU := XDR_SSU (Item);
S : XDR_S_SSU;
- U : XDR_SSU := XDR_SSU (Item);
begin
S (1) := SE (U);
-
Ada.Streams.Write (Stream.all, S);
end W_SSU;
-- W_SU --
----------
- procedure W_SU (Stream : access RST; Item : in Short_Unsigned) is
+ procedure W_SU (Stream : not null access RST; Item : Short_Unsigned) is
S : XDR_S_SU;
U : XDR_SU := XDR_SU (Item);
begin
if Optimize_Integers then
S := Short_Unsigned_To_XDR_S_SU (Item);
+
else
for N in reverse S'Range loop
S (N) := SE (U mod BB);
-- W_U --
---------
- procedure W_U (Stream : access RST; Item : in Unsigned) is
+ procedure W_U (Stream : not null access RST; Item : Unsigned) is
S : XDR_S_U;
U : XDR_U := XDR_U (Item);
begin
if Optimize_Integers then
S := Unsigned_To_XDR_S_U (Item);
+
else
for N in reverse S'Range loop
S (N) := SE (U mod BB);
-- W_WC --
----------
- procedure W_WC (Stream : access RST; Item : in Wide_Character) is
+ procedure W_WC (Stream : not null access RST; Item : Wide_Character) is
S : XDR_S_WC;
U : XDR_WC;
begin
-
-- Use Ada requirements on Wide_Character representation clause
U := XDR_WC (Wide_Character'Pos (Item));
end if;
end W_WC;
+ -----------
+ -- W_WWC --
+ -----------
+
+ procedure W_WWC
+ (Stream : not null access RST; Item : Wide_Wide_Character)
+ is
+ S : XDR_S_WWC;
+ U : XDR_WWC;
+
+ begin
+ -- Use Ada requirements on Wide_Wide_Character representation clause
+
+ U := XDR_WWC (Wide_Wide_Character'Pos (Item));
+
+ for N in reverse S'Range loop
+ S (N) := SE (U mod BB);
+ U := U / BB;
+ end loop;
+
+ Ada.Streams.Write (Stream.all, S);
+
+ if U /= 0 then
+ raise Data_Error;
+ end if;
+ end W_WWC;
+
end System.Stream_Attributes;