mirror of
https://github.com/ilyakooo0/urbit.git
synced 2024-12-14 17:41:33 +03:00
Merge pull request #3577 from urbit/jb/base16-jets
vere: adds jets for en/decoding base16
This commit is contained in:
commit
6b5be2b5cf
@ -152,6 +152,9 @@
|
||||
u3_noun u3qe_reco(u3_atom has, u3_atom sig_v, u3_atom sig_r, u3_atom sig_s);
|
||||
u3_noun u3qe_sign(u3_atom has, u3_atom prv);
|
||||
|
||||
u3_noun u3qe_en_base16(u3_atom len, u3_atom dat);
|
||||
u3_noun u3qe_de_base16(u3_atom inp);
|
||||
|
||||
u3_noun u3qeo_raw(u3_atom, u3_atom);
|
||||
|
||||
u3_noun u3qef_drg(u3_noun, u3_atom);
|
||||
|
@ -181,6 +181,9 @@
|
||||
u3_noun u3we_sign(u3_noun);
|
||||
u3_noun u3we_reco(u3_noun);
|
||||
|
||||
u3_noun u3we_en_base16(u3_noun);
|
||||
u3_noun u3we_de_base16(u3_noun);
|
||||
|
||||
u3_noun u3we_bend_fun(u3_noun);
|
||||
u3_noun u3we_cold_fun(u3_noun);
|
||||
u3_noun u3we_cook_fun(u3_noun);
|
||||
|
@ -368,6 +368,14 @@
|
||||
u3r_mp(mpz_t a_mp,
|
||||
u3_atom b);
|
||||
|
||||
/* u3r_short():
|
||||
**
|
||||
** Return short (a_w) of (b).
|
||||
*/
|
||||
c3_s
|
||||
u3r_short(c3_w a_w,
|
||||
u3_atom b);
|
||||
|
||||
/* u3r_word():
|
||||
**
|
||||
** Return word (a_w) of (b).
|
||||
|
@ -57,6 +57,11 @@
|
||||
# define u3x_peg(a_w, b_w) \
|
||||
( (a_w << u3x_dep(b_w)) | (b_w &~ (1 << u3x_dep(b_w))) )
|
||||
|
||||
/* u3x_atom(): atom or exit.
|
||||
*/
|
||||
# define u3x_atom(a) \
|
||||
( (c3y == u3a_is_cell(a)) ? u3m_bail(c3__exit) : a )
|
||||
|
||||
/** Functions.
|
||||
**/
|
||||
/** u3x_*: read, but bail with c3__exit on a crash.
|
||||
|
153
pkg/urbit/jets/e/base.c
Normal file
153
pkg/urbit/jets/e/base.c
Normal file
@ -0,0 +1,153 @@
|
||||
/* j/5/base.c
|
||||
**
|
||||
*/
|
||||
#include "all.h"
|
||||
|
||||
const c3_y hex_y[16] = { '0', '1', '2', '3', '4', '5', '6', '7',
|
||||
'8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
|
||||
|
||||
u3_noun
|
||||
u3qe_en_base16(u3_atom len, u3_atom dat)
|
||||
{
|
||||
if ( c3n == u3a_is_cat(len) ) {
|
||||
return u3m_bail(c3__fail);
|
||||
}
|
||||
else {
|
||||
c3_w len_w = (c3_w)len;
|
||||
u3i_slab sab_u;
|
||||
|
||||
u3i_slab_bare(&sab_u, 4, len_w);
|
||||
sab_u.buf_w[sab_u.len_w - 1] = 0;
|
||||
|
||||
{
|
||||
c3_y* buf_y = sab_u.buf_y;
|
||||
c3_y inp_y;
|
||||
|
||||
while ( len_w-- ) {
|
||||
inp_y = u3r_byte(len_w, dat);
|
||||
|
||||
*buf_y++ = hex_y[inp_y >> 4];
|
||||
*buf_y++ = hex_y[inp_y & 0xf];
|
||||
}
|
||||
}
|
||||
|
||||
return u3i_slab_moot_bytes(&sab_u);
|
||||
}
|
||||
}
|
||||
|
||||
static inline c3_o
|
||||
_of_hex_digit(c3_y inp_y, c3_y* out_y)
|
||||
{
|
||||
if ( inp_y >= '0' && inp_y <= '9' ) {
|
||||
*out_y = inp_y - '0';
|
||||
return c3y;
|
||||
}
|
||||
else if ( inp_y >= 'a' && inp_y <= 'f' ) {
|
||||
*out_y = inp_y - 87;
|
||||
return c3y;
|
||||
}
|
||||
else if ( inp_y >= 'A' && inp_y <= 'F' ) {
|
||||
*out_y = inp_y - 55;
|
||||
return c3y;
|
||||
}
|
||||
|
||||
return c3n;
|
||||
}
|
||||
|
||||
static inline c3_o
|
||||
_of_hex_odd(u3_atom inp, c3_w len_w, c3_w byt_w, c3_y* buf_y)
|
||||
{
|
||||
c3_y low_y, hig_y, lit_y, hit_y;
|
||||
|
||||
hig_y = u3r_byte(--byt_w, inp);
|
||||
|
||||
while ( --len_w ) {
|
||||
low_y = u3r_byte(--byt_w, inp);
|
||||
|
||||
if ( (c3n == _of_hex_digit(low_y, &lit_y))
|
||||
|| (c3n == _of_hex_digit(hig_y, &hit_y)) )
|
||||
{
|
||||
return c3n;
|
||||
}
|
||||
else {
|
||||
*buf_y++ = (hit_y & 0xf) ^ (lit_y << 4);
|
||||
}
|
||||
|
||||
hig_y = u3r_byte(--byt_w, inp);
|
||||
}
|
||||
|
||||
if ( c3n == _of_hex_digit(hig_y, &hit_y) ) {
|
||||
return c3n;
|
||||
}
|
||||
else {
|
||||
*buf_y = hit_y & 0xf;
|
||||
}
|
||||
|
||||
return c3y;
|
||||
}
|
||||
|
||||
static inline c3_o
|
||||
_of_hex_even(u3_atom inp, c3_w len_w, c3_y* buf_y)
|
||||
{
|
||||
c3_y lit_y, hit_y;
|
||||
c3_s inp_s;
|
||||
|
||||
while ( len_w-- ) {
|
||||
inp_s = u3r_short(len_w, inp);
|
||||
|
||||
if ( (c3n == _of_hex_digit(inp_s & 0xff, &lit_y))
|
||||
|| (c3n == _of_hex_digit(inp_s >> 8, &hit_y)) )
|
||||
{
|
||||
return c3n;
|
||||
}
|
||||
else {
|
||||
*buf_y++ = (hit_y & 0xf) ^ (lit_y << 4);
|
||||
}
|
||||
}
|
||||
|
||||
return c3y;
|
||||
}
|
||||
|
||||
u3_noun
|
||||
u3qe_de_base16(u3_atom inp)
|
||||
{
|
||||
c3_w len_w = u3r_met(4, inp);
|
||||
u3i_slab sab_u;
|
||||
|
||||
u3i_slab_bare(&sab_u, 3, len_w);
|
||||
sab_u.buf_w[sab_u.len_w - 1] = 0;
|
||||
|
||||
// even byte-length input can be parsed in aligned, 16-bit increments,
|
||||
// but odd byte-length input cannot, and is expressed more simply in bytes.
|
||||
//
|
||||
{
|
||||
c3_w byt_w = u3r_met(3, inp);
|
||||
c3_o ret_o = ( byt_w & 1 )
|
||||
? _of_hex_odd(inp, len_w, byt_w, sab_u.buf_y)
|
||||
: _of_hex_even(inp, len_w, sab_u.buf_y);
|
||||
|
||||
if ( c3n == ret_o ) {
|
||||
u3i_slab_free(&sab_u);
|
||||
return u3_nul;
|
||||
}
|
||||
else {
|
||||
u3_noun dat = u3i_slab_mint_bytes(&sab_u);
|
||||
return u3nt(u3_nul, u3i_word(len_w), dat);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
u3_noun
|
||||
u3we_en_base16(u3_noun cor)
|
||||
{
|
||||
u3_noun a, b;
|
||||
u3x_mean(cor, u3x_sam_2, &a, u3x_sam_3, &b, 0);
|
||||
return u3qe_en_base16(u3x_atom(a), u3x_atom(b));
|
||||
}
|
||||
|
||||
u3_noun
|
||||
u3we_de_base16(u3_noun cor)
|
||||
{
|
||||
u3_noun sam = u3x_at(u3x_sam, cor);
|
||||
return u3qe_de_base16(u3x_atom(sam));
|
||||
}
|
@ -15,6 +15,33 @@
|
||||
|
||||
#include "all.h"
|
||||
|
||||
static u3j_harm _141_hex_mimes_base16_en_a[] = {{".2", u3we_en_base16}, {}};
|
||||
static c3_c* _141_hex_mimes_base16_en_ha[] = {
|
||||
0
|
||||
};
|
||||
|
||||
static u3j_harm _141_hex_mimes_base16_de_a[] = {{".2", u3we_de_base16}, {}};
|
||||
static c3_c* _141_hex_mimes_base16_de_ha[] = {
|
||||
0
|
||||
};
|
||||
|
||||
static u3j_core _141_hex_mimes_base16_d[] =
|
||||
{ { "en", 7, _141_hex_mimes_base16_en_a, 0, _141_hex_mimes_base16_en_ha },
|
||||
{ "de", 7, _141_hex_mimes_base16_de_a, 0, _141_hex_mimes_base16_de_ha },
|
||||
{}
|
||||
};
|
||||
static c3_c* _141_hex_mimes_base16_ha[] = {
|
||||
0
|
||||
};
|
||||
|
||||
static u3j_core _141_hex_mimes_d[] =
|
||||
{ { "base16", 3, 0, _141_hex_mimes_base16_d, _141_hex_mimes_base16_ha },
|
||||
{}
|
||||
};
|
||||
static c3_c* _141_hex_mimes_ha[] = {
|
||||
0
|
||||
};
|
||||
|
||||
static u3j_harm _141_hex_aes_ecba_en_a[] = {{".2", u3wea_ecba_en}, {}};
|
||||
static c3_c* _141_hex_aes_ecba_en_ha[] = {
|
||||
"a4eaaead7ffeb213cf8d611f20d7be4786b34f31a27f41c77538125992107c2d",
|
||||
@ -397,6 +424,7 @@ static u3j_core _141_hex_d[] =
|
||||
{ "blake", 31, 0, _141_hex_blake_d, _141_hex_blake_ha },
|
||||
{ "ripemd", 31, 0, _141_hex_ripe_d, _141_hex_ripe_ha },
|
||||
{ "secp", 31, 0, _141_hex_secp_d, _141_hex_secp_ha },
|
||||
{ "mimes", 31, 0, _141_hex_mimes_d, _141_hex_mimes_ha },
|
||||
{}
|
||||
};
|
||||
static c3_c* _141_hex_ha[] = {
|
||||
|
@ -1195,6 +1195,39 @@ u3r_mp(mpz_t a_mp,
|
||||
}
|
||||
}
|
||||
|
||||
/* u3r_short():
|
||||
**
|
||||
** Return short (a_w) of (b).
|
||||
*/
|
||||
c3_s
|
||||
u3r_short(c3_w a_w,
|
||||
u3_atom b)
|
||||
{
|
||||
c3_assert( u3_none != b );
|
||||
c3_assert( c3y == u3a_is_atom(b) );
|
||||
|
||||
if ( c3y == u3a_is_cat(b) ) {
|
||||
switch ( a_w ) {
|
||||
case 0: return b & 0xffff;
|
||||
case 1: return b >> 16;
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
u3a_atom* b_u = u3a_to_ptr(b);
|
||||
c3_w nix_w = a_w >> 1;
|
||||
|
||||
if ( nix_w >= b_u->len_w ) {
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
c3_w wor_w = b_u->buf_w[nix_w];
|
||||
|
||||
return ( a_w & 1 ) ? (wor_w >> 16) : (wor_w & 0xffff);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* u3r_word():
|
||||
**
|
||||
** Return word (a_w) of (b).
|
||||
|
279
pkg/urbit/tests/jet_tests.c
Normal file
279
pkg/urbit/tests/jet_tests.c
Normal file
@ -0,0 +1,279 @@
|
||||
#include "all.h"
|
||||
|
||||
/* _setup(): prepare for tests.
|
||||
*/
|
||||
static void
|
||||
_setup(void)
|
||||
{
|
||||
u3m_init();
|
||||
u3m_pave(c3y, c3n);
|
||||
}
|
||||
|
||||
static c3_i
|
||||
_test_en_base16(void)
|
||||
{
|
||||
c3_i ret_i = 1;
|
||||
|
||||
{
|
||||
u3_atom dat = 0xaa;
|
||||
u3_atom pro = u3qe_en_base16(u3r_met(3, dat), dat);
|
||||
|
||||
if ( c3n == u3r_sing_c("aa", pro) ) {
|
||||
fprintf(stderr, "en_base16: fail (a)\r\n");
|
||||
ret_i = 0;
|
||||
}
|
||||
|
||||
u3z(pro);
|
||||
}
|
||||
|
||||
{
|
||||
u3_atom dat = 0x1234;
|
||||
u3_atom pro = u3qe_en_base16(u3r_met(3, dat), dat);
|
||||
|
||||
if ( c3n == u3r_sing_c("1234", pro) ) {
|
||||
fprintf(stderr, "en_base16: fail (b)\r\n");
|
||||
ret_i = 0;
|
||||
}
|
||||
|
||||
u3z(pro);
|
||||
}
|
||||
|
||||
{
|
||||
u3_atom dat = 0xf012;
|
||||
u3_atom pro = u3qe_en_base16(u3r_met(3, dat), dat);
|
||||
|
||||
if ( c3n == u3r_sing_c("f012", pro) ) {
|
||||
fprintf(stderr, "en_base16: fail (c)\r\n");
|
||||
ret_i = 0;
|
||||
}
|
||||
|
||||
u3z(pro);
|
||||
}
|
||||
|
||||
{
|
||||
u3_atom dat = 0x10b;
|
||||
u3_atom pro = u3qe_en_base16(u3r_met(3, dat), dat);
|
||||
|
||||
if ( c3n == u3r_sing_c("010b", pro) ) {
|
||||
fprintf(stderr, "en_base16: fail (d)\r\n");
|
||||
ret_i = 0;
|
||||
}
|
||||
|
||||
u3z(pro);
|
||||
}
|
||||
|
||||
{
|
||||
u3_atom pro = u3qe_en_base16(3, 0x1234);
|
||||
|
||||
if ( c3n == u3r_sing_c("001234", pro) ) {
|
||||
fprintf(stderr, "en_base16: fail (e)\r\n");
|
||||
ret_i = 0;
|
||||
}
|
||||
|
||||
u3z(pro);
|
||||
}
|
||||
|
||||
{
|
||||
u3_atom pro = u3qe_en_base16(1, 0x1234);
|
||||
|
||||
if ( c3n == u3r_sing_c("34", pro) ) {
|
||||
fprintf(stderr, "en_base16: fail (f)\r\n");
|
||||
ret_i = 0;
|
||||
}
|
||||
|
||||
u3z(pro);
|
||||
}
|
||||
|
||||
return ret_i;
|
||||
}
|
||||
|
||||
|
||||
static c3_i
|
||||
_test_de_base16(void)
|
||||
{
|
||||
c3_i ret_i = 1;
|
||||
|
||||
{
|
||||
u3_noun inp = u3i_string("aa");
|
||||
u3_noun pro = u3qe_de_base16(inp);
|
||||
u3_atom len, dat;
|
||||
|
||||
if ( c3n == u3r_pq(pro, u3_nul, &len, &dat) ) {
|
||||
fprintf(stderr, "de_base16: fail cell (a)\r\n");
|
||||
ret_i = 0;
|
||||
}
|
||||
|
||||
if ( 1 != len ) {
|
||||
fprintf(stderr, "de_base16: fail len (a)\r\n");
|
||||
ret_i = 0;
|
||||
}
|
||||
|
||||
if ( 0xaa != dat ) {
|
||||
fprintf(stderr, "de_base16: fail dat (a)\r\n");
|
||||
ret_i = 0;
|
||||
}
|
||||
|
||||
u3z(inp); u3z(pro);
|
||||
}
|
||||
|
||||
{
|
||||
u3_noun inp = u3i_string("1234");
|
||||
u3_noun pro = u3qe_de_base16(inp);
|
||||
u3_atom len, dat;
|
||||
|
||||
if ( c3n == u3r_pq(pro, u3_nul, &len, &dat) ) {
|
||||
fprintf(stderr, "de_base16: fail cell (b)\r\n");
|
||||
ret_i = 0;
|
||||
}
|
||||
|
||||
if ( 2 != len ) {
|
||||
fprintf(stderr, "de_base16: fail len (b)\r\n");
|
||||
ret_i = 0;
|
||||
}
|
||||
|
||||
if ( 0x1234 != dat ) {
|
||||
fprintf(stderr, "de_base16: fail dat (b)\r\n");
|
||||
ret_i = 0;
|
||||
}
|
||||
|
||||
u3z(inp); u3z(pro);
|
||||
}
|
||||
|
||||
{
|
||||
u3_noun inp = u3i_string("f012");
|
||||
u3_noun pro = u3qe_de_base16(inp);
|
||||
u3_atom len, dat;
|
||||
|
||||
if ( c3n == u3r_pq(pro, u3_nul, &len, &dat) ) {
|
||||
fprintf(stderr, "de_base16: fail cell (c)\r\n");
|
||||
ret_i = 0;
|
||||
}
|
||||
|
||||
if ( 2 != len ) {
|
||||
fprintf(stderr, "de_base16: fail len (c)\r\n");
|
||||
ret_i = 0;
|
||||
}
|
||||
|
||||
if ( 0xf012 != dat ) {
|
||||
fprintf(stderr, "de_base16: fail dat (c)\r\n");
|
||||
ret_i = 0;
|
||||
}
|
||||
|
||||
u3z(inp); u3z(pro);
|
||||
}
|
||||
|
||||
{
|
||||
u3_noun inp = u3i_string("010b");
|
||||
u3_noun pro = u3qe_de_base16(inp);
|
||||
u3_atom len, dat;
|
||||
|
||||
if ( c3n == u3r_pq(pro, u3_nul, &len, &dat) ) {
|
||||
fprintf(stderr, "de_base16: fail cell (d)\r\n");
|
||||
ret_i = 0;
|
||||
}
|
||||
|
||||
if ( 2 != len ) {
|
||||
fprintf(stderr, "de_base16: fail len (d)\r\n");
|
||||
ret_i = 0;
|
||||
}
|
||||
|
||||
if ( 0x10b != dat ) {
|
||||
fprintf(stderr, "de_base16: fail dat (d)\r\n");
|
||||
ret_i = 0;
|
||||
}
|
||||
|
||||
u3z(inp); u3z(pro);
|
||||
}
|
||||
|
||||
{
|
||||
u3_noun inp = u3i_string("10b");
|
||||
u3_noun pro = u3qe_de_base16(inp);
|
||||
u3_atom len, dat;
|
||||
|
||||
if ( c3n == u3r_pq(pro, u3_nul, &len, &dat) ) {
|
||||
fprintf(stderr, "de_base16: fail cell (e)\r\n");
|
||||
ret_i = 0;
|
||||
}
|
||||
|
||||
if ( 2 != len ) {
|
||||
fprintf(stderr, "de_base16: fail len (e)\r\n");
|
||||
ret_i = 0;
|
||||
}
|
||||
|
||||
if ( 0x10b != dat ) {
|
||||
fprintf(stderr, "de_base16: fail dat (e)\r\n");
|
||||
ret_i = 0;
|
||||
}
|
||||
|
||||
u3z(inp); u3z(pro);
|
||||
}
|
||||
|
||||
{
|
||||
u3_noun inp = u3i_string("001234");
|
||||
u3_noun pro = u3qe_de_base16(inp);
|
||||
u3_atom len, dat;
|
||||
|
||||
if ( c3n == u3r_pq(pro, u3_nul, &len, &dat) ) {
|
||||
fprintf(stderr, "de_base16: fail cell (f)\r\n");
|
||||
ret_i = 0;
|
||||
}
|
||||
|
||||
if ( 3 != len ) {
|
||||
fprintf(stderr, "de_base16: fail len (f)\r\n");
|
||||
ret_i = 0;
|
||||
}
|
||||
|
||||
if ( 0x1234 != dat ) {
|
||||
fprintf(stderr, "de_base16: fail dat (f)\r\n");
|
||||
ret_i = 0;
|
||||
}
|
||||
|
||||
u3z(inp); u3z(pro);
|
||||
}
|
||||
|
||||
return ret_i;
|
||||
}
|
||||
|
||||
static c3_i
|
||||
_test_base16(void)
|
||||
{
|
||||
c3_i ret_i = 1;
|
||||
|
||||
ret_i &= _test_en_base16();
|
||||
ret_i &= _test_de_base16();
|
||||
|
||||
return ret_i;
|
||||
}
|
||||
|
||||
static c3_i
|
||||
_test_jets(void)
|
||||
{
|
||||
c3_i ret_i = 1;
|
||||
|
||||
if ( !_test_base16() ) {
|
||||
fprintf(stderr, "test jets: base16: failed\r\n");
|
||||
ret_i = 0;
|
||||
}
|
||||
|
||||
return ret_i;
|
||||
}
|
||||
|
||||
/* main(): run all test cases.
|
||||
*/
|
||||
int
|
||||
main(int argc, char* argv[])
|
||||
{
|
||||
_setup();
|
||||
|
||||
if ( !_test_jets() ) {
|
||||
fprintf(stderr, "test jets: failed\r\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// GC
|
||||
//
|
||||
u3m_grab(u3_none);
|
||||
|
||||
fprintf(stderr, "test jets: ok\r\n");
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue
Block a user