/usr/share/ada/adainclude/gmpada/gmp-binding.adb is in libgmpada3-dev 0.0.20110925-2.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 | -- GMPAda, binding to the Ada Language for the GNU MultiPrecision library.
-- Copyright (C) 2007-2011 Nicolas Boulenguez <nicolas.boulenguez@free.fr>
--
-- This program is free software: you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation, either version 3 of the License, or
-- (at your option) any later version.
--
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY 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
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
package body GMP.Binding is
Bytes_Per_Limb : constant := Mp_Bits_Per_Limb / 8;
procedure Read_Limb
(Stream : access Ada.Streams.Root_Stream_Type'Class;
Value : out Mp_Limb_T;
Count : in unsigned := Bytes_Per_Limb - 1);
procedure Write_4_Bytes
(Stream : access Ada.Streams.Root_Stream_Type'Class;
Value : in size_t);
procedure Write_Limb
(Stream : access Ada.Streams.Root_Stream_Type'Class;
Value : in Mp_Limb_T;
Count : in Natural := Bytes_Per_Limb - 1);
pragma Inline (Read_Limb);
procedure Read_Limb (Stream : access Ada.Streams.Root_Stream_Type'Class;
Value : out Mp_Limb_T;
Count : in unsigned := Bytes_Per_Limb - 1) is
begin
Value := 0;
for I in reverse 0 .. Count loop
Value := Value * 16#100# or Mp_Limb_T (unsigned_char'Input (Stream));
end loop;
end Read_Limb;
pragma Inline (Write_4_Bytes);
procedure Write_4_Bytes (Stream : access Ada.Streams.Root_Stream_Type'Class;
Value : in size_t) is
begin
for I in reverse 0 .. 3 loop
unsigned_char'Write (Stream, unsigned_char (Value / 16#100#**I and 16#FF#));
end loop;
end Write_4_Bytes;
pragma Inline (Write_Limb);
procedure Write_Limb (Stream : access Ada.Streams.Root_Stream_Type'Class;
Value : in Mp_Limb_T;
Count : in Natural := Bytes_Per_Limb - 1) is
begin
for I in reverse 0 .. Count loop
unsigned_char'Write (Stream, unsigned_char (Value / 16#100#**I and 16#FF#));
end loop;
end Write_Limb;
procedure Read (Stream : access Ada.Streams.Root_Stream_Type'Class;
Item : out Mpz_T)
is
use Limbs;
Size : unsigned := 0;
Negative : Boolean;
P : Pointer;
begin
for I in 0 .. 3 loop
Size := Size * 256 or unsigned (unsigned_char'Input (Stream));
end loop;
Negative := (Size and 2 ** (unsigned'Size - 1)) /= 0;
if Negative then
Size := -Size;
end if;
Mpz_Init2 (Item, 8 * unsigned_long (Size));
-- Using C memory allocation is more portable.
if Size = 0 then
return;
end if;
Item.Mp_Size := int ((Size + Bytes_Per_Limb - 1) / Bytes_Per_Limb);
pragma Assert (Item.Mp_Size <= Item.Mp_Alloc);
P := Item.Mp_D + ptrdiff_t (Item.Mp_Size) - 1;
Read_Limb (Stream, P.all, (Size - 1) mod Bytes_Per_Limb);
pragma Assert ((P.all and 16#FF#*16#100#**Integer ((Size - 1) mod Bytes_Per_Limb)) /= 0);
while P /= Item.Mp_D loop
Decrement (P);
Read_Limb (Stream, P.all);
end loop;
if Negative then
pragma Warnings (Off, "writable actual for ""Rop"" overlaps with actual for ""Op""");
Mpz_Neg (Item, Item);
pragma Warnings (On, "writable actual for ""Rop"" overlaps with actual for ""Op""");
end if;
end Read;
procedure Write (Stream : access Ada.Streams.Root_Stream_Type'Class;
Item : in Mpz_T)
is
Limb_Size : constant size_t := Mpz_Size (Item);
Size : size_t := Limb_Size * Bytes_Per_Limb;
Mask : Mp_Limb_T := 16#FF# * 16#100#**(Bytes_Per_Limb - 1);
L : Mp_Limb_T;
begin
if Limb_Size = 0 then
Write_4_Bytes (Stream, 0);
return;
end if;
L := Mpz_Getlimbn (Item, Mp_Size_T (Limb_Size - 1));
while (L and Mask) = 0 loop
Mask := Mask / 16#100#;
Size := Size - 1;
pragma Assert (Mask /= 0);
end loop;
if Mpz_Sgn (Item) < 0 then
Write_4_Bytes (Stream, -Size);
else
Write_4_Bytes (Stream, +Size);
end if;
Write_Limb (Stream, L, Natural ((Size - 1) mod Bytes_Per_Limb));
if Limb_Size = 1 then
return;
end if;
-- Mp_size_t is unsigned, so 0 .. -1 is NOT an empty range.
for N in reverse 0 .. Mp_Size_T (Limb_Size - 2) loop
Write_Limb (Stream, Mpz_Getlimbn (Item, N));
end loop;
end Write;
end GMP.Binding;
|