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;
|
break;
|
||||||
|
|
||||||
case '>': /* big-endian */
|
case '>': /* big-endian */
|
||||||
endian = ENDIAN_BIG;
|
case '!': /* network */
|
||||||
break;
|
|
||||||
|
|
||||||
case '!': /* network (= big-endian) */
|
|
||||||
endian = ENDIAN_BIG;
|
endian = ENDIAN_BIG;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -5148,49 +5145,293 @@ oops_internal:
|
|||||||
return copy_error_to_sys_list (rtx, &rdp->sys_list);
|
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)
|
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_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;
|
hawk_oow_t arg_idx, arg_cnt;
|
||||||
|
int endian = ENDIAN_NATIVE;
|
||||||
hawk_val_t* v;
|
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: */
|
/* TODO: */
|
||||||
|
|
||||||
arg_idx = 2; /* set past the format specifier */
|
arg_idx = 2; /* set past the format specifier */
|
||||||
arg_cnt = hawk_rtx_getnargs(rtx);
|
arg_cnt = hawk_rtx_getnargs(rtx);
|
||||||
|
|
||||||
binp = bin->ptr;
|
rep_cnt = 1;
|
||||||
bine = bin->ptr + bin->len;
|
rep_set = 0;
|
||||||
|
|
||||||
|
binp = (hawk_uint8_t*)bin->ptr;
|
||||||
|
bine = (hawk_uint8_t*)bin->ptr + bin->len;
|
||||||
fmte = fmt->ptr + fmt->len;
|
fmte = fmt->ptr + fmt->len;
|
||||||
#if 0
|
|
||||||
for (fmtp = fmt->ptr; fmtp < fmte; fmtp++)
|
for (fmtp = fmt->ptr; fmtp < fmte; fmtp++)
|
||||||
{
|
{
|
||||||
switch (*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':
|
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, (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++);
|
v = hawk_rtx_makeintval(rtx, *binp++);
|
||||||
if (HAWK_UNLIKELY(!v)) goto oops_internal;
|
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;
|
if (hawk_rtx_setrefval(rtx, (hawk_val_ref_t*)hawk_rtx_getarg(rtx, arg_idx++), v) <= -1) goto oops_internal;
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case 'h':
|
case 'h':
|
||||||
{
|
{
|
||||||
v = hawk_rtx_makeintval(rtx, *binp++);
|
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_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;
|
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
|
#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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
oops_internal:
|
oops_internal:
|
||||||
return copy_error_to_sys_list (rtx, &rdp->sys_list);
|
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)
|
static int fnc_pack (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
|
||||||
{
|
{
|
||||||
rtx_data_t* rdp = rtx_to_data(rtx, 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;
|
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)
|
static int fnc_unpack (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
|
||||||
{
|
{
|
||||||
rtx_data_t* rdp = rtx_to_data(rtx, 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;
|
bin.ptr = HAWK_NULL;
|
||||||
|
|
||||||
a0 = hawk_rtx_getarg(rtx, 0);
|
a0 = hawk_rtx_getarg(rtx, 0);
|
||||||
|
a1 = hawk_rtx_getarg(rtx, 1);
|
||||||
|
|
||||||
bin.ptr = hawk_rtx_getvalbcstr(rtx, a0, &bin.len);
|
bin.ptr = hawk_rtx_getvalbcstr(rtx, a0, &bin.len);
|
||||||
if (HAWK_UNLIKELY(!bin.ptr)) goto fail;
|
if (HAWK_UNLIKELY(!bin.ptr)) goto fail;
|
||||||
|
|
||||||
a1 = hawk_rtx_getarg(rtx, 1);
|
|
||||||
fmt.ptr = hawk_rtx_getvaloocstr(rtx, a1, &fmt.len);
|
fmt.ptr = hawk_rtx_getvaloocstr(rtx, a1, &fmt.len);
|
||||||
if (HAWK_UNLIKELY(!fmt.ptr)) goto fail;
|
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);
|
rx = unpack_data(rtx, &bin, &fmt, fi, rdp);
|
||||||
|
|
||||||
hawk_rtx_freevaloocstr (rtx, a1, fmt.ptr); fmt.ptr = HAWK_NULL;
|
hawk_rtx_freevaloocstr (rtx, a1, fmt.ptr); fmt.ptr = HAWK_NULL;
|
||||||
hawk_rtx_freevalbcstr (rtx, a0, bin.ptr); bin.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:
|
done:
|
||||||
hawk_rtx_setretval (rtx, hawk_rtx_makeintval(rtx, rx));
|
hawk_rtx_setretval (rtx, hawk_rtx_makeintval(rtx, rx));
|
||||||
return 0;
|
return 0;
|
||||||
|
Loading…
Reference in New Issue
Block a user