1 ------------------------------------------------------------------------------ 2 ------------------------------------------------------------------------------ 3 -- This file is part of 'Finite Field Arithmetic', aka 'FFA'. -- 4 -- -- 5 -- (C) 2019 Stanislav Datskovskiy ( www.loper-os.org ) -- 6 -- http://wot.deedbot.org/17215D118B7239507FAFED98B98228A001ABFFC7.html -- 7 -- -- 8 -- You do not have, nor can you ever acquire the right to use, copy or -- 9 -- distribute this software ; Should you use this software for any purpose, -- 10 -- or copy and distribute it to anyone or in any manner, you are breaking -- 11 -- the laws of whatever soi-disant jurisdiction, and you promise to -- 12 -- continue doing so for the indefinite future. In any case, please -- 13 -- always : read and understand any software ; verify any PGP signatures -- 14 -- that you use - for any purpose. -- 15 -- -- 16 -- See also http://trilema.com/2015/a-new-software-licensing-paradigm . -- 17 ------------------------------------------------------------------------------ 18 ------------------------------------------------------------------------------ 19 20 with W_Pred; use W_Pred; 21 with W_Shifts; use W_Shifts; 22 with FZ_BitOp; use FZ_BitOp; 23 with FZ_Shift; use FZ_Shift; 24 25 26 package body FZ_IO is 27 28 -- Expand FZ N by nibble D, and determine whether this operation overflowed 29 procedure FZ_Insert_Bottom_Nibble(N : in out FZ; 30 D : in Nibble; 31 Overflow : out WBool) is 32 33 -- The overflow, if any, from shifting N in-place leftward by 4 bits 34 Shifted_N_Overflow : Word := 0; 35 36 begin 37 -- Make room in N for one additional hex digit (i.e. multiply N by 16) 38 FZ_ShiftLeft_O(N => N, 39 ShiftedN => N, 40 Count => 4, 41 Overflow => Shifted_N_Overflow); 42 43 -- Place the new digit into the now-vacated four bits at the bottom of N. 44 FZ_Or_W(N, D); 45 46 -- Record whether the above operation overflowed N: 47 Overflow := W_NZeroP(Shifted_N_Overflow); 48 49 end FZ_Insert_Bottom_Nibble; 50 51 52 -- Determine the number of ASCII characters required to represent N 53 function FZ_ASCII_Length(N : in FZ) return Char_Count is 54 begin 55 return N'Length * Nibbleness; 56 end FZ_ASCII_Length; 57 58 59 -- Write an ASCII hex representation of N into existing string buffer S 60 procedure FZ_To_Hex_String(N : in FZ; S : out String) is 61 62 -- Indices into the string S (note, String always indexes from 1) 63 subtype SiRange is Natural range S'First .. S'Last; 64 65 -- Position of current character in S being written 66 Si : SiRange; -- Walks from 1 to the string length of S 67 68 begin 69 70 -- Step through all indices of N, regardless of how it was indexed: 71 for i in 0 .. Word_Index(N'Length - 1) loop 72 declare 73 74 -- Index of current Word, walks from ~top~ Word of N to ~bottom~ 75 Wi : constant Word_Index := N'Last - i; 76 77 -- Currently-selected Word of N 78 W : Word := N(Wi); 79 80 begin 81 82 -- For each nibble in the Word: 83 for j in 1 .. Nibbleness loop 84 85 -- Current position in S that is to be written 86 Si := (Natural(i) * Nibbleness) + j; 87 88 -- Rotate the top nibble of W into the bottom nibble. 89 W := Rotate_Left(W, 4); 90 91 -- Write the ASCII representation of the bottom nibble. 92 S(Si) := HexDigs(Natural(W and 16#F#)); 93 94 end loop; 95 96 -- Barring cosmic ray, W will have rotated to its initial value 97 pragma Assert(W = N(Wi)); 98 99 end; 100 101 end loop; 102 103 -- Barring cosmic ray, the last char written was to the final pos in S, 104 pragma Assert(Si = SiRange'Last); -- as S is mandatorily exactly-sized. 105 106 end FZ_To_Hex_String; 107 108 end FZ_IO;