## pack-big-endian-unt1.pkg
# Compiled by:
#
src/lib/std/src/standard-core.sublib# This is the non-native implementation of 32-bit big-endian packing
# operations.
### "I've made an odd discovery.
###
### "Every time I talk to a savant
### I feel quite sure that happiness
### is no longer a possibility.
###
### "Yet when I talk with my gardener,
### I'm convinced of the opposite."
###
### -- Bertrand Russell
stipulate
package unt = unt_guts; # unt_guts is from
src/lib/std/src/bind-unt-guts.pkg package large_unt= large_unt_guts; # large_unt_guts is from
src/lib/std/src/bind-largeword-32.pkg package one_byte_unt= one_byte_unt_guts; # one_byte_unt_guts is from
src/lib/std/src/one-byte-unt-guts.pkg package lun = large_unt; # large_unt is from
src/lib/std/types-only/bind-largest32.pkg package w8 = one_byte_unt; # one_byte_unt is from
src/lib/std/types-only/basis-structs.pkg package w8v = inline_t::vector_of_one_byte_unts; # inline_t is from
src/lib/core/init/built-in.pkg package w8a = inline_t::rw_vector_of_one_byte_unts;
herein
package pack_big_endian_unt1: (weak) Pack_Unt { # Pack_Unt is from
src/lib/std/src/pack-unt.api #
#
bytes_per_element = 4; # Possible 64-BIT-ISSUE
# -- but probably not: this is infrastructure parallel to
src/lib/std/src/pack-big-endian-unt16.pkg # which is to say, below the level of caring about 32- vs 64-bit systems.
is_big_endian = TRUE;
# Convert the byte length into one_word_unt length (n div 4), and check the index
#
fun check_index (len, i)
=
{ len = unt::to_int_x (unt::(>>) (unt::from_int len, 0u2)); # len /= 4;
if (not (inline_t::default_int::ltu (i, len))) # "ltu" == "less-than (unsigned)"
#
raise exception INDEX_OUT_OF_BOUNDS;
fi;
};
fun make_unt (b1, b2, b3, b4)
=
lun::bitwise_or (lun::(<<) (one_byte_unt::to_large_unt b1, 0u24),
lun::bitwise_or (lun::(<<) (one_byte_unt::to_large_unt b2, 0u16),
lun::bitwise_or (lun::(<<) (one_byte_unt::to_large_unt b3, 0u8),
one_byte_unt::to_large_unt b4)));
# Fetch i-th 32-bit value from given byte-vector:
#
fun get_vec (vec, i)
=
{ check_index (w8v::length vec, i);
k = unt::to_int_x (unt::(<<) (unt::from_int i, 0u2)); # k = i * 4;
make_unt
( w8v::get (vec, k),
w8v::get (vec, k+1),
w8v::get (vec, k+2),
w8v::get (vec, k+3)
);
};
# As above, with sign extension. Except that
# since large_unt is 32-bits, no sign extension is required :
#
fun get_vec_x (vec, i)
=
get_vec (vec, i);
# As above, but from a mutable byte-vector:
#
fun get_rw_vec (vec, i)
=
{ check_index (w8a::length vec, i);
k = unt::to_int_x (unt::(<<) (unt::from_int i, 0u2)); # k = i * 4;
make_unt
( w8a::get (vec, k),
w8a::get (vec, k+1),
w8a::get (vec, k+2),
w8a::get (vec, k+3)
);
};
# As above, with sign extension. Except that
# since large_unt is 32-bits, no sign extension is required
#
fun get_rw_vec_x (vec, i)
=
get_rw_vec (vec, i);
# Possible 64-BIT-ISSUE.
fun set # Store a 32-bit unsigned into a byte array.
( vector: rw_vector_of_one_byte_unts::Rw_Vector, # Store into this vector.
index: Int, # Store starting at this index in vector.
value: large_unt::Unt # Store this value into vector.
)
=
{ check_index (w8a::length vector, index);
k = unt::to_int_x (unt::(<<) (unt::from_int index, 0u2));
w8a::set (vector, k, w8::from_large_unt (lun::(>>) (value, 0u24)));
w8a::set (vector, k+1, w8::from_large_unt (lun::(>>) (value, 0u16)));
w8a::set (vector, k+2, w8::from_large_unt (lun::(>>) (value, 0u8)));
w8a::set (vector, k+3, w8::from_large_unt value);
};
};
end;
## Copyright (c) 2005 by The Fellowship of SML/NJ
## Subsequent changes by Jeff Prothero Copyright (c) 2010-2015,
## released per terms of SMLNJ-COPYRIGHT.