added some code for sys::unpack()
This commit is contained in:
parent
40c750ef3b
commit
55e1003715
@ -4971,10 +4971,7 @@ static hawk_int_t pack_data (hawk_rtx_t* rtx, const hawk_oocs_t* fmt, const hawk
|
||||
break;
|
||||
|
||||
case '>': /* big-endian */
|
||||
endian = ENDIAN_BIG;
|
||||
break;
|
||||
|
||||
case '!': /* network (= big-endian) */
|
||||
case '!': /* network */
|
||||
endian = ENDIAN_BIG;
|
||||
break;
|
||||
|
||||
@ -5148,49 +5145,293 @@ oops_internal:
|
||||
return copy_error_to_sys_list (rtx, &rdp->sys_list);
|
||||
}
|
||||
|
||||
static hawk_uint16_t unpack_uint16 (const hawk_uint8_t* binp, int endian)
|
||||
{
|
||||
hawk_uint16_t v;
|
||||
|
||||
if (endian == ENDIAN_NATIVE)
|
||||
{
|
||||
v = *binp++;
|
||||
v |= (hawk_uint16_t)(*binp++) << 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
v = (hawk_uint16_t)(*binp++) << 8;
|
||||
v |= *binp++;
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
static hawk_int16_t unpack_int16 (const hawk_uint8_t* binp, int endian)
|
||||
{
|
||||
hawk_uint16_t v = unpack_uint16 (binp, endian);
|
||||
return (v <= HAWK_TYPE_MAX(hawk_int16_t))? (hawk_int16_t)v: ((hawk_int16_t)-1 - (hawk_int16_t)(HAWK_TYPE_MAX(hawk_uint16_t) - v));
|
||||
}
|
||||
|
||||
static hawk_uint32_t unpack_uint32 (const hawk_uint8_t* binp, int endian)
|
||||
{
|
||||
hawk_uint32_t v;
|
||||
|
||||
if (endian == ENDIAN_NATIVE)
|
||||
{
|
||||
v = *binp++;
|
||||
v |= (hawk_uint32_t)(*binp++) << 8;
|
||||
v |= (hawk_uint32_t)(*binp++) << 16;
|
||||
v |= (hawk_uint32_t)(*binp++) << 24;
|
||||
}
|
||||
else
|
||||
{
|
||||
v = (hawk_uint32_t)(*binp++) << 24;
|
||||
v |= (hawk_uint32_t)(*binp++) << 16;
|
||||
v |= (hawk_uint32_t)(*binp++) << 8;
|
||||
v |= *binp++;
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
static hawk_int32_t unpack_int32 (const hawk_uint8_t* binp, int endian)
|
||||
{
|
||||
hawk_uint32_t v = unpack_uint32 (binp, endian);
|
||||
return (v <= HAWK_TYPE_MAX(hawk_int32_t))? (hawk_int32_t)v: ((hawk_int32_t)-1 - (hawk_int32_t)(HAWK_TYPE_MAX(hawk_uint32_t) - v));
|
||||
}
|
||||
|
||||
static hawk_uint64_t unpack_uint64 (const hawk_uint8_t* binp, int endian)
|
||||
{
|
||||
hawk_uint64_t v;
|
||||
|
||||
if (endian == ENDIAN_NATIVE)
|
||||
{
|
||||
v = *binp++;
|
||||
v |= (hawk_uint64_t)(*binp++) << 8;
|
||||
v |= (hawk_uint64_t)(*binp++) << 16;
|
||||
v |= (hawk_uint64_t)(*binp++) << 24;
|
||||
v |= (hawk_uint64_t)(*binp++) << 32;
|
||||
v |= (hawk_uint64_t)(*binp++) << 40;
|
||||
v |= (hawk_uint64_t)(*binp++) << 48;
|
||||
v |= (hawk_uint64_t)(*binp++) << 56;
|
||||
}
|
||||
else
|
||||
{
|
||||
v = (hawk_uint64_t)(*binp++) << 56;
|
||||
v |= (hawk_uint64_t)(*binp++) << 48;
|
||||
v |= (hawk_uint64_t)(*binp++) << 40;
|
||||
v |= (hawk_uint64_t)(*binp++) << 32;
|
||||
v |= (hawk_uint64_t)(*binp++) << 24;
|
||||
v |= (hawk_uint64_t)(*binp++) << 16;
|
||||
v |= (hawk_uint64_t)(*binp++) << 8;
|
||||
v |= *binp++;
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
static hawk_int64_t unpack_int64 (const hawk_uint8_t* binp, int endian)
|
||||
{
|
||||
hawk_uint64_t v = unpack_uint64 (binp, endian);
|
||||
return (v <= HAWK_TYPE_MAX(hawk_int64_t))? (hawk_int64_t)v: ((hawk_int64_t)-1 - (hawk_int64_t)(HAWK_TYPE_MAX(hawk_uint64_t) - v));
|
||||
}
|
||||
|
||||
static hawk_int_t unpack_data (hawk_rtx_t* rtx, const hawk_bcs_t* bin, const hawk_oocs_t* fmt, const hawk_fnc_info_t* fi, rtx_data_t* rdp)
|
||||
{
|
||||
const hawk_ooch_t* fmtp, * fmte;
|
||||
const hawk_bch_t* binp, * bine;
|
||||
const hawk_uint8_t* binp, * bine;
|
||||
hawk_oow_t rep_cnt, rep_set, rc;
|
||||
hawk_oow_t arg_idx, arg_cnt;
|
||||
int endian = ENDIAN_NATIVE;
|
||||
hawk_val_t* v;
|
||||
|
||||
|
||||
#define UNPACK_CHECK_ARG_AND_DATA(reqarg, reqsz) do { \
|
||||
if (arg_cnt - arg_idx < reqarg) return set_error_on_sys_list (rtx, &rdp->sys_list, HAWK_EARGTF, HAWK_NULL); \
|
||||
if (bine - binp < reqsz) goto oops_internal; \
|
||||
} while(0)
|
||||
/* TODO: */
|
||||
|
||||
arg_idx = 2; /* set past the format specifier */
|
||||
arg_cnt = hawk_rtx_getnargs(rtx);
|
||||
|
||||
binp = bin->ptr;
|
||||
bine = bin->ptr + bin->len;
|
||||
rep_cnt = 1;
|
||||
rep_set = 0;
|
||||
|
||||
binp = (hawk_uint8_t*)bin->ptr;
|
||||
bine = (hawk_uint8_t*)bin->ptr + bin->len;
|
||||
fmte = fmt->ptr + fmt->len;
|
||||
#if 0
|
||||
for (fmtp = fmt->ptr; fmtp < fmte; fmtp++)
|
||||
{
|
||||
switch (*fmtp)
|
||||
{
|
||||
case '=': /* native */
|
||||
endian = ENDIAN_NATIVE;
|
||||
break;
|
||||
|
||||
case '<': /* little-endian */
|
||||
endian = ENDIAN_LITTLE;
|
||||
break;
|
||||
|
||||
case '>': /* big-endian */
|
||||
case '!': /* network */
|
||||
endian = ENDIAN_BIG;
|
||||
break;
|
||||
|
||||
case 'b':
|
||||
{
|
||||
v = hawk_rtx_makeintval(rtx, *binp++);
|
||||
if (HAWK_UNLIKELY(!v)) goto oops_internal;
|
||||
if (hawk_rtx_setrefval(rtx, (hawk_val_ref_t*)hawk_rtx_getarg(rtx, arg_idx), v) <= -1) goto oops_internal;
|
||||
UNPACK_CHECK_ARG_AND_DATA (rep_cnt, rep_cnt * HAWK_SIZEOF(hawk_int8_t));
|
||||
for (rc = 0; rc < rep_cnt; rc++)
|
||||
{
|
||||
v = hawk_rtx_makeintval(rtx, (hawk_int8_t)*binp++);
|
||||
if (HAWK_UNLIKELY(!v)) goto oops_internal;
|
||||
if (hawk_rtx_setrefval(rtx, (hawk_val_ref_t*)hawk_rtx_getarg(rtx, arg_idx++), v) <= -1) goto oops_internal;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case 'B':
|
||||
{
|
||||
UNPACK_CHECK_ARG_AND_DATA (rep_cnt, rep_cnt * HAWK_SIZEOF(hawk_int8_t));
|
||||
for (rc = 0; rc < rep_cnt; rc++)
|
||||
{
|
||||
v = hawk_rtx_makeintval(rtx, *binp++);
|
||||
if (HAWK_UNLIKELY(!v)) goto oops_internal;
|
||||
if (hawk_rtx_setrefval(rtx, (hawk_val_ref_t*)hawk_rtx_getarg(rtx, arg_idx++), v) <= -1) goto oops_internal;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case 'h':
|
||||
{
|
||||
v = hawk_rtx_makeintval(rtx, *binp++);
|
||||
if (HAWK_UNLIKELY(!v)) goto oops_internal;
|
||||
if (hawk_rtx_setrefval(rtx, (hawk_val_ref_t*)hawk_rtx_getarg(rtx, arg_idx), v) <= -1) goto oops_internal;
|
||||
UNPACK_CHECK_ARG_AND_DATA (rep_cnt, rep_cnt * HAWK_SIZEOF(hawk_int16_t));
|
||||
for (rc = 0; rc < rep_cnt; rc++)
|
||||
{
|
||||
v = hawk_rtx_makeintval(rtx, unpack_int16(binp, endian));
|
||||
binp += HAWK_SIZEOF(hawk_int16_t);
|
||||
if (HAWK_UNLIKELY(!v)) goto oops_internal;
|
||||
if (hawk_rtx_setrefval(rtx, (hawk_val_ref_t*)hawk_rtx_getarg(rtx, arg_idx++), v) <= -1) goto oops_internal;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case 'H':
|
||||
{
|
||||
UNPACK_CHECK_ARG_AND_DATA (rep_cnt, rep_cnt * HAWK_SIZEOF(hawk_uint16_t));
|
||||
for (rc = 0; rc < rep_cnt; rc++)
|
||||
{
|
||||
v = hawk_rtx_makeintval(rtx, unpack_uint16(binp, endian));
|
||||
binp += HAWK_SIZEOF(hawk_uint16_t);
|
||||
if (HAWK_UNLIKELY(!v)) goto oops_internal;
|
||||
if (hawk_rtx_setrefval(rtx, (hawk_val_ref_t*)hawk_rtx_getarg(rtx, arg_idx++), v) <= -1) goto oops_internal;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case 'i':
|
||||
case 'l':
|
||||
{
|
||||
UNPACK_CHECK_ARG_AND_DATA (rep_cnt, rep_cnt * HAWK_SIZEOF(hawk_int32_t));
|
||||
for (rc = 0; rc < rep_cnt; rc++)
|
||||
{
|
||||
v = hawk_rtx_makeintval(rtx, unpack_int32(binp, endian));
|
||||
binp += HAWK_SIZEOF(hawk_int32_t);
|
||||
if (HAWK_UNLIKELY(!v)) goto oops_internal;
|
||||
if (hawk_rtx_setrefval(rtx, (hawk_val_ref_t*)hawk_rtx_getarg(rtx, arg_idx++), v) <= -1) goto oops_internal;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case 'I':
|
||||
case 'L':
|
||||
{
|
||||
UNPACK_CHECK_ARG_AND_DATA (rep_cnt, rep_cnt * HAWK_SIZEOF(hawk_uint32_t));
|
||||
for (rc = 0; rc < rep_cnt; rc++)
|
||||
{
|
||||
v = hawk_rtx_makeintval(rtx, unpack_uint32(binp, endian));
|
||||
binp += HAWK_SIZEOF(hawk_uint32_t);
|
||||
if (HAWK_UNLIKELY(!v)) goto oops_internal;
|
||||
if (hawk_rtx_setrefval(rtx, (hawk_val_ref_t*)hawk_rtx_getarg(rtx, arg_idx++), v) <= -1) goto oops_internal;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case 'q':
|
||||
{
|
||||
UNPACK_CHECK_ARG_AND_DATA (rep_cnt, rep_cnt * HAWK_SIZEOF(hawk_int64_t));
|
||||
for (rc = 0; rc < rep_cnt; rc++)
|
||||
{
|
||||
v = hawk_rtx_makeintval(rtx, unpack_int64(binp, endian));
|
||||
binp += HAWK_SIZEOF(hawk_int64_t);
|
||||
if (HAWK_UNLIKELY(!v)) goto oops_internal;
|
||||
if (hawk_rtx_setrefval(rtx, (hawk_val_ref_t*)hawk_rtx_getarg(rtx, arg_idx++), v) <= -1) goto oops_internal;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case 'Q':
|
||||
{
|
||||
UNPACK_CHECK_ARG_AND_DATA (rep_cnt, rep_cnt * HAWK_SIZEOF(hawk_uint64_t));
|
||||
for (rc = 0; rc < rep_cnt; rc++)
|
||||
{
|
||||
v = hawk_rtx_makeintval(rtx, unpack_uint64(binp, endian));
|
||||
binp += HAWK_SIZEOF(hawk_uint64_t);
|
||||
if (HAWK_UNLIKELY(!v)) goto oops_internal;
|
||||
if (hawk_rtx_setrefval(rtx, (hawk_val_ref_t*)hawk_rtx_getarg(rtx, arg_idx++), v) <= -1) goto oops_internal;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
#if 0
|
||||
case 'f':
|
||||
case 'd':
|
||||
#endif
|
||||
|
||||
case 's':
|
||||
case 'p':
|
||||
{
|
||||
UNPACK_CHECK_ARG_AND_DATA (1, rep_cnt);
|
||||
v = hawk_rtx_makembsvalwithbchars(rtx, binp, rep_cnt);
|
||||
binp += rep_cnt;
|
||||
if (HAWK_UNLIKELY(!v)) goto oops_internal;
|
||||
if (hawk_rtx_setrefval(rtx, (hawk_val_ref_t*)hawk_rtx_getarg(rtx, arg_idx++), v) <= -1) goto oops_internal;
|
||||
break;
|
||||
}
|
||||
|
||||
case 'x':
|
||||
binp += rep_cnt;
|
||||
break;
|
||||
|
||||
default:
|
||||
/* handle below outside 'switch' */
|
||||
if (hawk_is_ooch_digit(*fmtp))
|
||||
{
|
||||
if (!rep_set)
|
||||
{
|
||||
rep_cnt = 0;
|
||||
rep_set = 1;
|
||||
}
|
||||
rep_cnt = rep_cnt * 10 + (*fmtp - '0');
|
||||
}
|
||||
else if (!hawk_is_ooch_space(*fmtp))
|
||||
{
|
||||
return set_error_on_sys_list (rtx, &rdp->sys_list, HAWK_EINVAL, HAWK_T("invalid specifier - %jc"), *fmtp);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (!hawk_is_ooch_digit(*fmtp) && !hawk_is_ooch_space(*fmtp))
|
||||
{
|
||||
rep_cnt = 1;
|
||||
rep_set = 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
|
||||
oops_internal:
|
||||
return copy_error_to_sys_list (rtx, &rdp->sys_list);
|
||||
}
|
||||
|
||||
/*
|
||||
sys::pack(bin, "i 5s h", 10, "hello", -20);
|
||||
printf ("%W\n", bin);
|
||||
*/
|
||||
static int fnc_pack (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
|
||||
{
|
||||
rtx_data_t* rdp = rtx_to_data(rtx, fi);
|
||||
@ -5229,6 +5470,9 @@ static int fnc_pack (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* sys::unpack(@b"\x00\x11\x12\x13\x14\x15", "h h h", a, b, c);
|
||||
* print a, b, c;
|
||||
*/
|
||||
static int fnc_unpack (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
|
||||
{
|
||||
rtx_data_t* rdp = rtx_to_data(rtx, fi);
|
||||
@ -5241,34 +5485,19 @@ static int fnc_unpack (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
|
||||
bin.ptr = HAWK_NULL;
|
||||
|
||||
a0 = hawk_rtx_getarg(rtx, 0);
|
||||
a1 = hawk_rtx_getarg(rtx, 1);
|
||||
|
||||
bin.ptr = hawk_rtx_getvalbcstr(rtx, a0, &bin.len);
|
||||
if (HAWK_UNLIKELY(!bin.ptr)) goto fail;
|
||||
|
||||
a1 = hawk_rtx_getarg(rtx, 1);
|
||||
fmt.ptr = hawk_rtx_getvaloocstr(rtx, a1, &fmt.len);
|
||||
if (HAWK_UNLIKELY(!fmt.ptr)) goto fail;
|
||||
|
||||
/* sys::unpack(@b"\x00\x11\x12\x13\x14\x15", "h h h", a, b, c); */
|
||||
|
||||
rx = unpack_data(rtx, &bin, &fmt, fi, rdp);
|
||||
|
||||
hawk_rtx_freevaloocstr (rtx, a1, fmt.ptr); fmt.ptr = HAWK_NULL;
|
||||
hawk_rtx_freevalbcstr (rtx, a0, bin.ptr); bin.ptr = HAWK_NULL;
|
||||
|
||||
if (rx >= 0)
|
||||
{
|
||||
hawk_val_t* tmp;
|
||||
int x;
|
||||
|
||||
tmp = hawk_rtx_makembsvalwithbchars(rtx, rdp->pack.ptr, rdp->pack.len);
|
||||
if (HAWK_UNLIKELY(!tmp)) goto fail;
|
||||
|
||||
hawk_rtx_refupval (rtx, tmp);
|
||||
x = hawk_rtx_setrefval(rtx, (hawk_val_ref_t*)hawk_rtx_getarg(rtx, 0), tmp);
|
||||
hawk_rtx_refdownval (rtx, tmp);
|
||||
if (x <= -1) goto fail;
|
||||
}
|
||||
|
||||
done:
|
||||
hawk_rtx_setretval (rtx, hawk_rtx_makeintval(rtx, rx));
|
||||
return 0;
|
||||
|
Loading…
Reference in New Issue
Block a user