------------------------------------------------------------------------------ ------------------------------------------------------------------------------ -- This file is part of 'Finite Field Arithmetic', aka 'FFA'. -- -- -- -- (C) 2019 Stanislav Datskovskiy ( www.loper-os.org ) -- -- http://wot.deedbot.org/17215D118B7239507FAFED98B98228A001ABFFC7.html -- -- -- -- You do not have, nor can you ever acquire the right to use, copy or -- -- distribute this software ; Should you use this software for any purpose, -- -- or copy and distribute it to anyone or in any manner, you are breaking -- -- the laws of whatever soi-disant jurisdiction, and you promise to -- -- continue doing so for the indefinite future. In any case, please -- -- always : read and understand any software ; verify any PGP signatures -- -- that you use - for any purpose. -- -- -- -- See also http://trilema.com/2015/a-new-software-licensing-paradigm . -- ------------------------------------------------------------------------------ ------------------------------------------------------------------------------ with W_Pred; use W_Pred; with W_Shifts; use W_Shifts; with FZ_BitOp; use FZ_BitOp; with FZ_Shift; use FZ_Shift; package body FZ_IO is -- Expand FZ N by nibble D, and determine whether this operation overflowed procedure FZ_Insert_Bottom_Nibble(N : in out FZ; D : in Nibble; Overflow : out WBool) is -- The overflow, if any, from shifting N in-place leftward by 4 bits Shifted_N_Overflow : Word := 0; begin -- Make room in N for one additional hex digit (i.e. multiply N by 16) FZ_ShiftLeft_O(N => N, ShiftedN => N, Count => 4, Overflow => Shifted_N_Overflow); -- Place the new digit into the now-vacated four bits at the bottom of N. FZ_Or_W(N, D); -- Record whether the above operation overflowed N: Overflow := W_NZeroP(Shifted_N_Overflow); end FZ_Insert_Bottom_Nibble; -- Determine the number of ASCII characters required to represent N function FZ_ASCII_Length(N : in FZ) return Char_Count is begin return N'Length * Nibbleness; end FZ_ASCII_Length; -- Write an ASCII hex representation of N into existing string buffer S procedure FZ_To_Hex_String(N : in FZ; S : out String) is -- Indices into the string S (note, String always indexes from 1) subtype SiRange is Natural range S'First .. S'Last; -- Position of current character in S being written Si : SiRange; -- Walks from 1 to the string length of S begin -- Step through all indices of N, regardless of how it was indexed: for i in 0 .. Word_Index(N'Length - 1) loop declare -- Index of current Word, walks from ~top~ Word of N to ~bottom~ Wi : constant Word_Index := N'Last - i; -- Currently-selected Word of N W : Word := N(Wi); begin -- For each nibble in the Word: for j in 1 .. Nibbleness loop -- Current position in S that is to be written Si := (Natural(i) * Nibbleness) + j; -- Rotate the top nibble of W into the bottom nibble. W := Rotate_Left(W, 4); -- Write the ASCII representation of the bottom nibble. S(Si) := HexDigs(Natural(W and 16#F#)); end loop; -- Barring cosmic ray, W will have rotated to its initial value pragma Assert(W = N(Wi)); end; end loop; -- Barring cosmic ray, the last char written was to the final pos in S, pragma Assert(Si = SiRange'Last); -- as S is mandatorily exactly-sized. end FZ_To_Hex_String; end FZ_IO;