added c, n, N to sys::pack() and sys::unpack()

This commit is contained in:
hyung-hwan 2020-12-14 15:25:07 +00:00
parent 55e1003715
commit 130d24544f
2 changed files with 183 additions and 22 deletions

View File

@ -4846,7 +4846,7 @@ done:
# define ENDIAN_NATIVE ENDIAN_LITTLE # define ENDIAN_NATIVE ENDIAN_LITTLE
#endif #endif
static hawk_oow_t pack_int16_t (hawk_uint8_t* dst, hawk_uint16_t val, int endian) static hawk_oow_t pack_uint16_t (hawk_uint8_t* dst, hawk_uint16_t val, int endian)
{ {
if (endian == ENDIAN_NATIVE) if (endian == ENDIAN_NATIVE)
{ {
@ -4862,7 +4862,7 @@ static hawk_oow_t pack_int16_t (hawk_uint8_t* dst, hawk_uint16_t val, int endian
return 2; return 2;
} }
static hawk_oow_t pack_int32_t (hawk_uint8_t* dst, hawk_uint32_t val, int endian) static hawk_oow_t pack_uint32_t (hawk_uint8_t* dst, hawk_uint32_t val, int endian)
{ {
if (endian == ENDIAN_NATIVE) if (endian == ENDIAN_NATIVE)
{ {
@ -4882,7 +4882,7 @@ static hawk_oow_t pack_int32_t (hawk_uint8_t* dst, hawk_uint32_t val, int endian
return 4; return 4;
} }
static hawk_oow_t pack_int64_t (hawk_uint8_t* dst, hawk_uint64_t val, int endian) static hawk_oow_t pack_uint64_t (hawk_uint8_t* dst, hawk_uint64_t val, int endian)
{ {
if (endian == ENDIAN_NATIVE) if (endian == ENDIAN_NATIVE)
{ {
@ -4910,6 +4910,21 @@ static hawk_oow_t pack_int64_t (hawk_uint8_t* dst, hawk_uint64_t val, int endian
return 8; return 8;
} }
static hawk_oow_t pack_uintptr_t (hawk_uint8_t* dst, hawk_oow_t val, int endian)
{
hawk_oow_t i;
if (endian == ENDIAN_NATIVE)
{
for (i = 0; i < HAWK_SIZEOF(hawk_oow_t); i++) *dst++ = val >> (i * 8);
}
else
{
for (i = HAWK_SIZEOF(hawk_oow_t); i > 0; ) *dst++ = val >> ((--i) * 8);
}
return HAWK_SIZEOF(hawk_oow_t);
}
static int ensure_pack_buf (hawk_rtx_t* rtx, rtx_data_t* rdp, hawk_oow_t reqsz) static int ensure_pack_buf (hawk_rtx_t* rtx, rtx_data_t* rdp, hawk_oow_t reqsz)
{ {
if (reqsz > rdp->pack.capa - rdp->pack.len) if (reqsz > rdp->pack.capa - rdp->pack.len)
@ -4962,19 +4977,29 @@ static hawk_int_t pack_data (hawk_rtx_t* rtx, const hawk_oocs_t* fmt, const hawk
{ {
switch (*fmtp) switch (*fmtp)
{ {
case '=': /* native */ #if 0
case '@': /* native size, native alignment */
break;
#endif
case '=': /* native endian, no alignment */
endian = ENDIAN_NATIVE; endian = ENDIAN_NATIVE;
break; break;
case '<': /* little-endian */ case '<': /* little-endian, no alignment */
endian = ENDIAN_LITTLE; endian = ENDIAN_LITTLE;
break; break;
case '>': /* big-endian */ case '>': /* big-endian, no alignment */
case '!': /* network */ case '!': /* network, no alignment */
endian = ENDIAN_BIG; endian = ENDIAN_BIG;
break; break;
case 'x': /* zero-padding */
PACK_CHECK_ARG_AND_BUF (0, rep_cnt * HAWK_SIZEOF(hawk_uint8_t));
for (rc = 0; rc < rep_cnt; rc++) rdp->pack.ptr[rdp->pack.len++] = 0;
break;
case 'b': /* byte, char */ case 'b': /* byte, char */
{ {
hawk_int_t v; hawk_int_t v;
@ -5006,7 +5031,7 @@ static hawk_int_t pack_data (hawk_rtx_t* rtx, const hawk_oocs_t* fmt, const hawk
for (rc = 0; rc < rep_cnt; rc++) for (rc = 0; rc < rep_cnt; rc++)
{ {
if (hawk_rtx_valtoint(rtx, hawk_rtx_getarg(rtx, arg_idx++), &v) <= -1) goto oops_internal; if (hawk_rtx_valtoint(rtx, hawk_rtx_getarg(rtx, arg_idx++), &v) <= -1) goto oops_internal;
rdp->pack.len += pack_int16_t(&rdp->pack.ptr[rdp->pack.len], (hawk_int16_t)v, endian); rdp->pack.len += pack_uint16_t(&rdp->pack.ptr[rdp->pack.len], (hawk_int16_t)v, endian);
} }
break; break;
} }
@ -5018,7 +5043,7 @@ static hawk_int_t pack_data (hawk_rtx_t* rtx, const hawk_oocs_t* fmt, const hawk
for (rc = 0; rc < rep_cnt; rc++) for (rc = 0; rc < rep_cnt; rc++)
{ {
if (hawk_rtx_valtoint(rtx, hawk_rtx_getarg(rtx, arg_idx++), &v) <= -1) goto oops_internal; if (hawk_rtx_valtoint(rtx, hawk_rtx_getarg(rtx, arg_idx++), &v) <= -1) goto oops_internal;
rdp->pack.len += pack_int16_t(&rdp->pack.ptr[rdp->pack.len], (hawk_uint16_t)v, endian); rdp->pack.len += pack_uint16_t(&rdp->pack.ptr[rdp->pack.len], (hawk_uint16_t)v, endian);
} }
break; break;
} }
@ -5031,7 +5056,7 @@ static hawk_int_t pack_data (hawk_rtx_t* rtx, const hawk_oocs_t* fmt, const hawk
for (rc = 0; rc < rep_cnt; rc++) for (rc = 0; rc < rep_cnt; rc++)
{ {
if (hawk_rtx_valtoint(rtx, hawk_rtx_getarg(rtx, arg_idx++), &v) <= -1) goto oops_internal; if (hawk_rtx_valtoint(rtx, hawk_rtx_getarg(rtx, arg_idx++), &v) <= -1) goto oops_internal;
rdp->pack.len += pack_int32_t(&rdp->pack.ptr[rdp->pack.len], (hawk_int32_t)v, endian); rdp->pack.len += pack_uint32_t(&rdp->pack.ptr[rdp->pack.len], (hawk_int32_t)v, endian);
} }
break; break;
} }
@ -5044,7 +5069,7 @@ static hawk_int_t pack_data (hawk_rtx_t* rtx, const hawk_oocs_t* fmt, const hawk
for (rc = 0; rc < rep_cnt; rc++) for (rc = 0; rc < rep_cnt; rc++)
{ {
if (hawk_rtx_valtoint(rtx, hawk_rtx_getarg(rtx, arg_idx++), &v) <= -1) goto oops_internal; if (hawk_rtx_valtoint(rtx, hawk_rtx_getarg(rtx, arg_idx++), &v) <= -1) goto oops_internal;
rdp->pack.len += pack_int16_t(&rdp->pack.ptr[rdp->pack.len], (hawk_uint32_t)v, endian); rdp->pack.len += pack_uint16_t(&rdp->pack.ptr[rdp->pack.len], (hawk_uint32_t)v, endian);
} }
break; break;
} }
@ -5056,7 +5081,7 @@ static hawk_int_t pack_data (hawk_rtx_t* rtx, const hawk_oocs_t* fmt, const hawk
for (rc = 0; rc < rep_cnt; rc++) for (rc = 0; rc < rep_cnt; rc++)
{ {
if (hawk_rtx_valtoint(rtx, hawk_rtx_getarg(rtx, arg_idx++), &v) <= -1) goto oops_internal; if (hawk_rtx_valtoint(rtx, hawk_rtx_getarg(rtx, arg_idx++), &v) <= -1) goto oops_internal;
rdp->pack.len += pack_int64_t(rdp->pack.ptr, (hawk_int64_t)v, endian); rdp->pack.len += pack_uint64_t(rdp->pack.ptr, (hawk_int64_t)v, endian);
} }
break; break;
} }
@ -5068,11 +5093,36 @@ static hawk_int_t pack_data (hawk_rtx_t* rtx, const hawk_oocs_t* fmt, const hawk
for (rc = 0; rc < rep_cnt; rc++) for (rc = 0; rc < rep_cnt; rc++)
{ {
if (hawk_rtx_valtoint(rtx, hawk_rtx_getarg(rtx, arg_idx++), &v) <= -1) goto oops_internal; if (hawk_rtx_valtoint(rtx, hawk_rtx_getarg(rtx, arg_idx++), &v) <= -1) goto oops_internal;
rdp->pack.len += pack_int64_t(rdp->pack.ptr, (hawk_uint64_t)v, endian); rdp->pack.len += pack_uint64_t(rdp->pack.ptr, (hawk_uint64_t)v, endian);
} }
break; break;
} }
case 'n':
{
hawk_int_t v;
PACK_CHECK_ARG_AND_BUF (rep_cnt, HAWK_SIZEOF(hawk_intptr_t) * rep_cnt);
for (rc = 0; rc < rep_cnt; rc++)
{
if (hawk_rtx_valtoint(rtx, hawk_rtx_getarg(rtx, arg_idx++), &v) <= -1) goto oops_internal;
rdp->pack.len += pack_uintptr_t(rdp->pack.ptr, (hawk_intptr_t)v, endian);
}
break;
}
case 'N':
{
hawk_int_t v;
PACK_CHECK_ARG_AND_BUF (rep_cnt, HAWK_SIZEOF(hawk_uintptr_t) * rep_cnt);
for (rc = 0; rc < rep_cnt; rc++)
{
if (hawk_rtx_valtoint(rtx, hawk_rtx_getarg(rtx, arg_idx++), &v) <= -1) goto oops_internal;
rdp->pack.len += pack_uintptr_t(rdp->pack.ptr, (hawk_uintptr_t)v, endian);
}
break;
}
#if 0 #if 0
case 'f': case 'f':
f = va_arg(args, double); f = va_arg(args, double);
@ -5085,6 +5135,31 @@ static hawk_int_t pack_data (hawk_rtx_t* rtx, const hawk_oocs_t* fmt, const hawk
break; break;
#endif #endif
case 'c':
{
hawk_val_t* a;
hawk_bcs_t tmp;
PACK_CHECK_ARG_AND_BUF (rep_cnt, HAWK_SIZEOF(hawk_uint8_t) * rep_cnt);
for (rc = 0; rc < rep_cnt; rc++)
{
a = hawk_rtx_getarg(rtx, arg_idx++);
tmp.ptr = hawk_rtx_getvalbcstr(rtx, a, &tmp.len);
if (HAWK_UNLIKELY(!tmp.ptr)) goto oops_internal;
if (tmp.len < 1)
{
hawk_rtx_freevalbcstr (rtx, a, tmp.ptr);
return set_error_on_sys_list (rtx, &rdp->sys_list, HAWK_EINVAL, HAWK_T("data too short for '%jc'"), *fmtp);
}
rdp->pack.ptr[rdp->pack.len++] = tmp.ptr[0];
hawk_rtx_freevalbcstr (rtx, a, tmp.ptr);
}
break;
}
case 's': case 's':
case 'p': case 'p':
@ -5109,11 +5184,6 @@ static hawk_int_t pack_data (hawk_rtx_t* rtx, const hawk_oocs_t* fmt, const hawk
break; break;
} }
case 'x': /* zero-padding */
PACK_CHECK_ARG_AND_BUF (0, rep_cnt * HAWK_SIZEOF(hawk_uint8_t));
for (rc = 0; rc < rep_cnt; rc++) rdp->pack.ptr[rdp->pack.len++] = 0;
break;
default: default:
/* handle below outside 'switch' */ /* handle below outside 'switch' */
if (hawk_is_ooch_digit(*fmtp)) if (hawk_is_ooch_digit(*fmtp))
@ -5230,6 +5300,29 @@ static hawk_int64_t unpack_int64 (const hawk_uint8_t* binp, int 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)); 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_uintptr_t unpack_uintptr (const hawk_uint8_t* binp, int endian)
{
hawk_uintptr_t v = 0;
hawk_oow_t i;
if (endian == ENDIAN_NATIVE)
{
for (i = 0; i < HAWK_SIZEOF(hawk_uintptr_t); i++) v |= (hawk_uintptr_t)(*binp++) << (i * 8);
}
else
{
for (i = HAWK_SIZEOF(hawk_uintptr_t); i > 0; ) v |= (hawk_uintptr_t)(*binp++) << ((--i) * 8);
}
return v;
}
static hawk_intptr_t unpack_intptr (const hawk_uint8_t* binp, int endian)
{
hawk_uintptr_t v = unpack_uintptr(binp, endian);
return (v <= HAWK_TYPE_MAX(hawk_intptr_t))? (hawk_intptr_t)v: ((hawk_intptr_t)-1 - (hawk_intptr_t)(HAWK_TYPE_MAX(hawk_uintptr_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;
@ -5272,6 +5365,11 @@ static hawk_int_t unpack_data (hawk_rtx_t* rtx, const hawk_bcs_t* bin, const haw
endian = ENDIAN_BIG; endian = ENDIAN_BIG;
break; break;
case 'x':
binp += rep_cnt;
break;
case 'b': case 'b':
{ {
UNPACK_CHECK_ARG_AND_DATA (rep_cnt, rep_cnt * HAWK_SIZEOF(hawk_int8_t)); UNPACK_CHECK_ARG_AND_DATA (rep_cnt, rep_cnt * HAWK_SIZEOF(hawk_int8_t));
@ -5377,11 +5475,51 @@ static hawk_int_t unpack_data (hawk_rtx_t* rtx, const hawk_bcs_t* bin, const haw
break; break;
} }
case 'n':
{
UNPACK_CHECK_ARG_AND_DATA (rep_cnt, rep_cnt * HAWK_SIZEOF(hawk_intptr_t));
for (rc = 0; rc < rep_cnt; rc++)
{
v = hawk_rtx_makeintval(rtx, unpack_intptr(binp, endian));
binp += HAWK_SIZEOF(hawk_intptr_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 'N':
{
UNPACK_CHECK_ARG_AND_DATA (rep_cnt, rep_cnt * HAWK_SIZEOF(hawk_uintptr_t));
for (rc = 0; rc < rep_cnt; rc++)
{
v = hawk_rtx_makeintval(rtx, unpack_uintptr(binp, endian));
binp += HAWK_SIZEOF(hawk_uintptr_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 #if 0
case 'f': case 'f':
case 'd': case 'd':
#endif #endif
case 'c':
{
UNPACK_CHECK_ARG_AND_DATA (rep_cnt, rep_cnt * HAWK_SIZEOF(hawk_uint8_t));
for (rc = 0; rc < rep_cnt; rc++)
{
v = hawk_rtx_makebchrval(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 's': case 's':
case 'p': case 'p':
{ {
@ -5393,10 +5531,6 @@ static hawk_int_t unpack_data (hawk_rtx_t* rtx, const hawk_bcs_t* bin, const haw
break; break;
} }
case 'x':
binp += rep_cnt;
break;
default: default:
/* handle below outside 'switch' */ /* handle below outside 'switch' */
if (hawk_is_ooch_digit(*fmtp)) if (hawk_is_ooch_digit(*fmtp))

View File

@ -552,6 +552,33 @@ function main()
ensure (str::trim(@b" hello world ", str::TRIM_PAC_SPACES) === @b"hello world", 1, @SCRIPTNAME, @SCRIPTLINE); ensure (str::trim(@b" hello world ", str::TRIM_PAC_SPACES) === @b"hello world", 1, @SCRIPTNAME, @SCRIPTLINE);
} }
{
@local a, b, c, d;
sys::pack(a, ">hhl", 1, 2, 3);
ensure (a === @b"\x00\x01\x00\x02\x00\x00\x00\x03", 1, @SCRIPTNAME, @SCRIPTLINE);
sys::pack(a, ">ci", @b'*', 0x12131415);
ensure (a === @b"*\x12\x13\x14\x15", 1, @SCRIPTNAME, @SCRIPTLINE);
sys::pack(a, ">ic", 0x12131415, @b"*+-");
ensure (a === @b"\x12\x13\x14\x15*", 1, @SCRIPTNAME, @SCRIPTLINE);
sys::pack(a, "3c", @b"*+-", 't', "pack");
ensure (a === @b"*tp", 1, @SCRIPTNAME, @SCRIPTLINE);
sys::unpack (@b"raymond \x32\x12\x08\x01\x08", "<10sHHb", a, b, c, d);
ensure (a === @b"raymond ", 1, @SCRIPTNAME, @SCRIPTLINE);
ensure (b === 4658, 1, @SCRIPTNAME, @SCRIPTLINE);
ensure (c === 264, 1, @SCRIPTNAME, @SCRIPTLINE);
ensure (d === 8, 1, @SCRIPTNAME, @SCRIPTLINE);
sys::unpack (@b"raymond", "3c", a, b, c);
ensure (a === @b'r' , 1, @SCRIPTNAME, @SCRIPTLINE);
ensure (b === @b'a' , 1, @SCRIPTNAME, @SCRIPTLINE);
ensure (c === @b'y' , 1, @SCRIPTNAME, @SCRIPTLINE);
}
print "SUCCESS"; print "SUCCESS";
} }