moved hawk::pack() to sys::pack()
enhanced sys::pack() to return an error code and set the error message upon failure
This commit is contained in:
parent
237a2853d8
commit
a93b1aaf12
@ -32,7 +32,7 @@ static int fnc_int (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi);
|
||||
static int fnc_asort (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi);
|
||||
static int fnc_asorti (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi);
|
||||
|
||||
#define A_MAX HAWK_TYPE_MAX(int)
|
||||
#define A_MAX HAWK_TYPE_MAX(hawk_oow_t)
|
||||
|
||||
/* Argument Specifier
|
||||
*
|
||||
|
@ -27,38 +27,6 @@
|
||||
#include "mod-hawk.h"
|
||||
#include "hawk-prv.h"
|
||||
|
||||
|
||||
/* ----------------------------------------------------------------- */
|
||||
struct mod_ctx_t
|
||||
{
|
||||
hawk_rbt_t* rtxtab;
|
||||
};
|
||||
typedef struct mod_ctx_t mod_ctx_t;
|
||||
|
||||
/* ----------------------------------------------------------------- */
|
||||
struct rtx_data_t
|
||||
{
|
||||
struct
|
||||
{
|
||||
hawk_uint8_t __static_buf[256];
|
||||
hawk_uint8_t* ptr;
|
||||
hawk_oow_t capa;
|
||||
hawk_oow_t len;
|
||||
} pack;
|
||||
};
|
||||
typedef struct rtx_data_t rtx_data_t;
|
||||
|
||||
/* ----------------------------------------------------------------- */
|
||||
|
||||
static HAWK_INLINE rtx_data_t* rtx_to_data (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
|
||||
{
|
||||
mod_ctx_t* mctx = (mod_ctx_t*)fi->mod->ctx;
|
||||
hawk_rbt_pair_t* pair;
|
||||
pair = hawk_rbt_search(mctx->rtxtab, &rtx, HAWK_SIZEOF(rtx));
|
||||
HAWK_ASSERT (pair != HAWK_NULL);
|
||||
return (rtx_data_t*)HAWK_RBT_VPTR(pair);
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------- */
|
||||
|
||||
/*
|
||||
@ -425,353 +393,6 @@ static int fnc_typename (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
#define ENDIAN_BIG 1
|
||||
#define ENDIAN_LITTLE 2
|
||||
#if defined(HAWK_ENDIAN_BIG)
|
||||
# define ENDIAN_NATIVE ENDIAN_BIG
|
||||
#else
|
||||
# define ENDIAN_NATIVE ENDIAN_LITTLE
|
||||
#endif
|
||||
|
||||
static hawk_oow_t pack_int16_t (hawk_uint8_t* dst, hawk_uint16_t val, int endian)
|
||||
{
|
||||
if (endian == ENDIAN_NATIVE)
|
||||
{
|
||||
*dst++ = val;
|
||||
*dst++ = val >> 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
*dst++ = val >> 8;
|
||||
*dst++ = val;
|
||||
}
|
||||
|
||||
return 2;
|
||||
}
|
||||
|
||||
static hawk_oow_t pack_int32_t (hawk_uint8_t* dst, hawk_uint32_t val, int endian)
|
||||
{
|
||||
if (endian == ENDIAN_NATIVE)
|
||||
{
|
||||
*dst++ = val;
|
||||
*dst++ = val >> 8;
|
||||
*dst++ = val >> 16;
|
||||
*dst++ = val >> 24;
|
||||
}
|
||||
else
|
||||
{
|
||||
*dst++ = val >> 24;
|
||||
*dst++ = val >> 16;
|
||||
*dst++ = val >> 8;
|
||||
*dst++ = val;
|
||||
}
|
||||
|
||||
return 4;
|
||||
}
|
||||
|
||||
static hawk_oow_t pack_int64_t (hawk_uint8_t* dst, hawk_uint64_t val, int endian)
|
||||
{
|
||||
if (endian == ENDIAN_NATIVE)
|
||||
{
|
||||
*dst++ = val;
|
||||
*dst++ = val >> 8;
|
||||
*dst++ = val >> 16;
|
||||
*dst++ = val >> 24;
|
||||
*dst++ = val >> 32;
|
||||
*dst++ = val >> 40;
|
||||
*dst++ = val >> 48;
|
||||
*dst++ = val >> 56;
|
||||
}
|
||||
else
|
||||
{
|
||||
*dst++ = val >> 56;
|
||||
*dst++ = val >> 48;
|
||||
*dst++ = val >> 40;
|
||||
*dst++ = val >> 32;
|
||||
*dst++ = val >> 24;
|
||||
*dst++ = val >> 16;
|
||||
*dst++ = val >> 8;
|
||||
*dst++ = val;
|
||||
}
|
||||
|
||||
return 8;
|
||||
}
|
||||
|
||||
static int ensure_pack_buf (hawk_rtx_t* rtx, rtx_data_t* rdp, hawk_oow_t reqsz)
|
||||
{
|
||||
if (rdp->pack.len >= rdp->pack.capa - reqsz)
|
||||
{
|
||||
hawk_uint8_t* tmp;
|
||||
hawk_oow_t newcapa;
|
||||
|
||||
newcapa = HAWK_ALIGN_POW2(rdp->pack.capa + reqsz, 256);
|
||||
if (rdp->pack.ptr == rdp->pack.__static_buf)
|
||||
{
|
||||
tmp = hawk_rtx_allocmem(rtx, newcapa);
|
||||
if (HAWK_UNLIKELY(!tmp)) return -1;
|
||||
HAWK_MEMCPY (tmp, rdp->pack.__static_buf, rdp->pack.len);
|
||||
}
|
||||
else
|
||||
{
|
||||
tmp = hawk_rtx_reallocmem(rtx, rdp->pack.ptr, newcapa);
|
||||
if (HAWK_UNLIKELY(!tmp)) return -1;
|
||||
}
|
||||
|
||||
rdp->pack.ptr = tmp;
|
||||
rdp->pack.capa = newcapa;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int pack_data (hawk_rtx_t* rtx, const hawk_oocs_t* fmt, const hawk_fnc_info_t* fi, rtx_data_t* rdp)
|
||||
{
|
||||
hawk_oow_t rep_cnt, rep_set, rc;
|
||||
const hawk_ooch_t* fmtp, *fmte;
|
||||
hawk_oow_t arg_idx, arg_cnt;
|
||||
int endian = ENDIAN_NATIVE;
|
||||
|
||||
|
||||
#define PACK_CHECK_ARG_AND_BUF(reqarg, reqsz) do { \
|
||||
if (arg_cnt - arg_idx < reqarg) \
|
||||
{ \
|
||||
hawk_rtx_seterrnum (rtx, HAWK_NULL, HAWK_EARGTF); \
|
||||
return -1; \
|
||||
} \
|
||||
if (ensure_pack_buf(rtx, rdp, reqsz) <= -1) return -1; \
|
||||
} while(0)
|
||||
|
||||
rdp->pack.len = 0;
|
||||
|
||||
arg_idx = 1; /* set past the format specifier */
|
||||
arg_cnt = hawk_rtx_getnargs(rtx);
|
||||
|
||||
rep_cnt = 1;
|
||||
rep_set = 0;
|
||||
|
||||
fmte = fmt->ptr + fmt->len;
|
||||
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 */
|
||||
endian = ENDIAN_BIG;
|
||||
break;
|
||||
|
||||
case '!': /* network (= big-endian) */
|
||||
endian = ENDIAN_BIG;
|
||||
break;
|
||||
|
||||
case 'b': /* byte, char */
|
||||
{
|
||||
hawk_int_t v;
|
||||
PACK_CHECK_ARG_AND_BUF (rep_cnt, HAWK_SIZEOF(hawk_int8_t) * rep_cnt);
|
||||
for (rc = 0; rc < rep_cnt; rc++)
|
||||
{
|
||||
if (hawk_rtx_valtoint(rtx, hawk_rtx_getarg(rtx, arg_idx++), &v) <= -1) return -1;
|
||||
rdp->pack.ptr[rdp->pack.len++] = (hawk_int8_t)v;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case 'B':
|
||||
{
|
||||
hawk_int_t v;
|
||||
PACK_CHECK_ARG_AND_BUF (rep_cnt, HAWK_SIZEOF(hawk_uint8_t) * rep_cnt);
|
||||
for (rc = 0; rc < rep_cnt; rc++)
|
||||
{
|
||||
if (hawk_rtx_valtoint(rtx, hawk_rtx_getarg(rtx, arg_idx++), &v) <= -1) return -1;
|
||||
rdp->pack.ptr[rdp->pack.len++] = (hawk_uint8_t)v;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case 'h':
|
||||
{
|
||||
hawk_int_t v;
|
||||
PACK_CHECK_ARG_AND_BUF (rep_cnt, HAWK_SIZEOF(hawk_int16_t) * rep_cnt);
|
||||
for (rc = 0; rc < rep_cnt; rc++)
|
||||
{
|
||||
if (hawk_rtx_valtoint(rtx, hawk_rtx_getarg(rtx, arg_idx++), &v) <= -1) return -1;
|
||||
rdp->pack.len += pack_int16_t(&rdp->pack.ptr[rdp->pack.len], (hawk_int16_t)v, endian);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case 'H':
|
||||
{
|
||||
hawk_int_t v;
|
||||
PACK_CHECK_ARG_AND_BUF (rep_cnt, HAWK_SIZEOF(hawk_uint16_t) * rep_cnt);
|
||||
for (rc = 0; rc < rep_cnt; rc++)
|
||||
{
|
||||
if (hawk_rtx_valtoint(rtx, hawk_rtx_getarg(rtx, arg_idx++), &v) <= -1) return -1;
|
||||
rdp->pack.len += pack_int16_t(&rdp->pack.ptr[rdp->pack.len], (hawk_uint16_t)v, endian);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case 'i':
|
||||
case 'l':
|
||||
{
|
||||
hawk_int_t v;
|
||||
PACK_CHECK_ARG_AND_BUF (rep_cnt, HAWK_SIZEOF(hawk_int32_t) * rep_cnt);
|
||||
for (rc = 0; rc < rep_cnt; rc++)
|
||||
{
|
||||
if (hawk_rtx_valtoint(rtx, hawk_rtx_getarg(rtx, arg_idx++), &v) <= -1) return -1;
|
||||
rdp->pack.len += pack_int32_t(&rdp->pack.ptr[rdp->pack.len], (hawk_int32_t)v, endian);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case 'I': /* fall through */
|
||||
case 'L':
|
||||
{
|
||||
hawk_int_t v;
|
||||
PACK_CHECK_ARG_AND_BUF (rep_cnt, HAWK_SIZEOF(hawk_uint32_t) * rep_cnt);
|
||||
for (rc = 0; rc < rep_cnt; rc++)
|
||||
{
|
||||
if (hawk_rtx_valtoint(rtx, hawk_rtx_getarg(rtx, arg_idx++), &v) <= -1) return -1;
|
||||
rdp->pack.len += pack_int16_t(&rdp->pack.ptr[rdp->pack.len], (hawk_uint32_t)v, endian);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case 'q':
|
||||
{
|
||||
hawk_int_t v;
|
||||
PACK_CHECK_ARG_AND_BUF (rep_cnt, HAWK_SIZEOF(hawk_int64_t) * rep_cnt);
|
||||
for (rc = 0; rc < rep_cnt; rc++)
|
||||
{
|
||||
if (hawk_rtx_valtoint(rtx, hawk_rtx_getarg(rtx, arg_idx++), &v) <= -1) return -1;
|
||||
rdp->pack.len += pack_int64_t(rdp->pack.ptr, (hawk_int64_t)v, endian);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case 'Q':
|
||||
{
|
||||
hawk_int_t v;
|
||||
PACK_CHECK_ARG_AND_BUF (rep_cnt, HAWK_SIZEOF(hawk_uint64_t) * rep_cnt);
|
||||
for (rc = 0; rc < rep_cnt; rc++)
|
||||
{
|
||||
if (hawk_rtx_valtoint(rtx, hawk_rtx_getarg(rtx, arg_idx++), &v) <= -1) return -1;
|
||||
rdp->pack.len += pack_int64_t(rdp->pack.ptr, (hawk_uint64_t)v, endian);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
#if 0
|
||||
case 'f':
|
||||
f = va_arg(args, double);
|
||||
pack_float(&bp, f, *ep);
|
||||
break;
|
||||
|
||||
case 'd':
|
||||
d = va_arg(args, double);
|
||||
pack_double(&bp, d, *ep);
|
||||
break;
|
||||
#endif
|
||||
|
||||
|
||||
case 's':
|
||||
case 'p':
|
||||
{
|
||||
hawk_val_t* a;
|
||||
hawk_bcs_t tmp;
|
||||
|
||||
PACK_CHECK_ARG_AND_BUF (1, HAWK_SIZEOF(hawk_uint8_t) * rep_cnt);
|
||||
|
||||
a = hawk_rtx_getarg(rtx, arg_idx++);
|
||||
|
||||
tmp.ptr = hawk_rtx_getvalbcstr(rtx, a, &tmp.len);
|
||||
if (HAWK_UNLIKELY(!tmp.ptr)) return -1;
|
||||
|
||||
if (rep_cnt > tmp.len)
|
||||
{
|
||||
hawk_rtx_freevalbcstr (rtx, a, tmp.ptr);
|
||||
hawk_rtx_seterrnum (rtx, HAWK_NULL, HAWK_EINVAL);
|
||||
return -1;
|
||||
}
|
||||
for (rc = 0; rc < rep_cnt; rc++) rdp->pack.ptr[rdp->pack.len++] = tmp.ptr[rc];
|
||||
hawk_rtx_freevalbcstr (rtx, a, tmp.ptr);
|
||||
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:
|
||||
/* 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))
|
||||
{
|
||||
hawk_rtx_seterrnum (rtx, HAWK_NULL, HAWK_EINVAL);
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (!hawk_is_ooch_digit(*fmtp) && !hawk_is_ooch_space(*fmtp))
|
||||
{
|
||||
rep_cnt = 1;
|
||||
rep_set = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int fnc_pack (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
|
||||
{
|
||||
rtx_data_t* rdp = rtx_to_data(rtx, fi);
|
||||
hawk_val_t* a0;
|
||||
hawk_oocs_t fmt;
|
||||
int x;
|
||||
|
||||
a0 = hawk_rtx_getarg(rtx, 0);
|
||||
fmt.ptr = hawk_rtx_getvaloocstr(rtx, a0, &fmt.len);
|
||||
if (HAWK_UNLIKELY(!fmt.ptr)) return -1;
|
||||
|
||||
/* TODO: how to indicate failure??? */
|
||||
x = pack_data(rtx, &fmt, fi, rdp);
|
||||
hawk_rtx_freevaloocstr (rtx, a0, fmt.ptr);
|
||||
|
||||
if (x >= 0)
|
||||
{
|
||||
hawk_val_t* r;
|
||||
r = hawk_rtx_makembsvalwithbchars(rtx, rdp->pack.ptr, rdp->pack.len);
|
||||
if (HAWK_UNLIKELY(!r)) return -1;
|
||||
hawk_rtx_setretval (rtx, r);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int fnc_unpack (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
|
||||
{
|
||||
/* TODO: */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
typedef struct fnctab_t fnctab_t;
|
||||
struct fnctab_t
|
||||
{
|
||||
@ -786,7 +407,7 @@ struct inttab_t
|
||||
hawk_mod_sym_int_t info;
|
||||
};
|
||||
|
||||
#define A_MAX HAWK_TYPE_MAX(int)
|
||||
#define A_MAX HAWK_TYPE_MAX(hawk_oow_t)
|
||||
|
||||
static fnctab_t fnctab[] =
|
||||
{
|
||||
@ -804,9 +425,7 @@ static fnctab_t fnctab[] =
|
||||
{ HAWK_T("isnil"), { { 1, 1, HAWK_NULL }, fnc_isnil, 0 } },
|
||||
{ HAWK_T("map"), { { 0, A_MAX, HAWK_NULL }, fnc_map, 0 } },
|
||||
{ HAWK_T("modlibdirs"), { { 0, 0, HAWK_NULL }, fnc_modlibdirs, 0 } },
|
||||
{ HAWK_T("pack"), { { 1, A_MAX, HAWK_NULL }, fnc_pack, 0 } },
|
||||
{ HAWK_T("typename"), { { 1, 1, HAWK_NULL }, fnc_typename, 0 } },
|
||||
//{ HAWK_T("unpack"), { { 1, A_MAX, HAWK_NULL }, fnc_unpack, 0 } }
|
||||
{ HAWK_T("typename"), { { 1, 1, HAWK_NULL }, fnc_typename, 0 } }
|
||||
};
|
||||
|
||||
static inttab_t inttab[] =
|
||||
@ -856,74 +475,31 @@ static int query (hawk_mod_t* mod, hawk_t* hawk, const hawk_ooch_t* name, hawk_m
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* TODO: proper resource management */
|
||||
|
||||
static int init (hawk_mod_t* mod, hawk_rtx_t* rtx)
|
||||
{
|
||||
mod_ctx_t* mctx = (mod_ctx_t*)mod->ctx;
|
||||
rtx_data_t rd, * rdp;
|
||||
hawk_rbt_pair_t* pair;
|
||||
|
||||
HAWK_MEMSET (&rd, 0, HAWK_SIZEOF(rd));
|
||||
pair = hawk_rbt_insert(mctx->rtxtab, &rtx, HAWK_SIZEOF(rtx), &rd, HAWK_SIZEOF(rd));
|
||||
if (HAWK_UNLIKELY(!pair)) return -1;
|
||||
|
||||
rdp = (rtx_data_t*)HAWK_RBT_VPTR(pair);
|
||||
rdp->pack.ptr = rdp->pack.__static_buf;
|
||||
rdp->pack.capa = HAWK_COUNTOF(rdp->pack.__static_buf);
|
||||
rdp->pack.len = 0;
|
||||
|
||||
/* nothing to do */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void fini (hawk_mod_t* mod, hawk_rtx_t* rtx)
|
||||
{
|
||||
mod_ctx_t* mctx = (mod_ctx_t*)mod->ctx;
|
||||
hawk_rbt_pair_t* pair;
|
||||
|
||||
pair = hawk_rbt_search(mctx->rtxtab, &rtx, HAWK_SIZEOF(rtx));
|
||||
if (pair)
|
||||
{
|
||||
rtx_data_t* rdp;
|
||||
|
||||
rdp = (rtx_data_t*)HAWK_RBT_VPTR(pair);
|
||||
|
||||
if (rdp->pack.ptr != rdp->pack.__static_buf) hawk_rtx_freemem(rtx, rdp->pack.ptr);
|
||||
|
||||
hawk_rbt_delete (mctx->rtxtab, &rtx, HAWK_SIZEOF(rtx));
|
||||
}
|
||||
/* nothing to do */
|
||||
}
|
||||
|
||||
static void unload (hawk_mod_t* mod, hawk_t* hawk)
|
||||
{
|
||||
mod_ctx_t* mctx = (mod_ctx_t*)mod->ctx;
|
||||
HAWK_ASSERT (HAWK_RBT_SIZE(mctx->rtxtab) == 0);
|
||||
hawk_rbt_close (mctx->rtxtab);
|
||||
hawk_freemem (hawk, mctx);
|
||||
/* nothing to do */
|
||||
}
|
||||
|
||||
int hawk_mod_hawk (hawk_mod_t* mod, hawk_t* hawk)
|
||||
{
|
||||
hawk_rbt_t* rbt;
|
||||
|
||||
mod->query = query;
|
||||
mod->unload = unload;
|
||||
|
||||
mod->init = init;
|
||||
mod->fini = fini;
|
||||
mod->ctx = HAWK_NULL;
|
||||
|
||||
mod->ctx = hawk_callocmem(hawk, HAWK_SIZEOF(mod_ctx_t));
|
||||
if (HAWK_UNLIKELY(!mod->ctx)) return -1;
|
||||
|
||||
rbt = hawk_rbt_open(hawk_getgem(hawk), 0, 1, 1);
|
||||
if (HAWK_UNLIKELY(!rbt))
|
||||
{
|
||||
hawk_freemem (hawk, mod->ctx);
|
||||
return -1;
|
||||
}
|
||||
hawk_rbt_setstyle (rbt, hawk_get_rbt_style(HAWK_RBT_STYLE_INLINE_COPIERS));
|
||||
|
||||
((mod_ctx_t*)mod->ctx)->rtxtab = rbt;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -759,7 +759,7 @@ struct inttab_t
|
||||
hawk_mod_sym_int_t info;
|
||||
};
|
||||
|
||||
#define A_MAX HAWK_TYPE_MAX(int)
|
||||
#define A_MAX HAWK_TYPE_MAX(hawk_oow_t)
|
||||
|
||||
static fnctab_t fnctab[] =
|
||||
{
|
||||
|
@ -223,6 +223,14 @@ typedef struct sys_list_data_t sys_list_data_t;
|
||||
struct rtx_data_t
|
||||
{
|
||||
sys_list_t sys_list;
|
||||
|
||||
struct
|
||||
{
|
||||
hawk_uint8_t __static_buf[256];
|
||||
hawk_uint8_t* ptr;
|
||||
hawk_oow_t capa;
|
||||
hawk_oow_t len;
|
||||
} pack;
|
||||
};
|
||||
typedef struct rtx_data_t rtx_data_t;
|
||||
|
||||
@ -485,14 +493,18 @@ static void free_sys_node (hawk_rtx_t* rtx, sys_list_t* list, sys_node_t* node)
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
static HAWK_INLINE rtx_data_t* rtx_to_data (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
|
||||
{
|
||||
mod_ctx_t* mctx = (mod_ctx_t*)fi->mod->ctx;
|
||||
hawk_rbt_pair_t* pair;
|
||||
pair = hawk_rbt_search(mctx->rtxtab, &rtx, HAWK_SIZEOF(rtx));
|
||||
HAWK_ASSERT (pair != HAWK_NULL);
|
||||
return (rtx_data_t*)HAWK_RBT_VPTR(pair);
|
||||
}
|
||||
|
||||
static HAWK_INLINE sys_list_t* rtx_to_sys_list (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
|
||||
{
|
||||
mod_ctx_t* mctx = (mod_ctx_t*)fi->mod->ctx;
|
||||
hawk_rbt_pair_t* pair;
|
||||
|
||||
pair = hawk_rbt_search(mctx->rtxtab, &rtx, HAWK_SIZEOF(rtx));
|
||||
HAWK_ASSERT (pair != HAWK_NULL);
|
||||
return (sys_list_t*)HAWK_RBT_VPTR(pair);
|
||||
return &(rtx_to_data(rtx, fi)->sys_list);
|
||||
}
|
||||
|
||||
static HAWK_INLINE sys_node_t* get_sys_list_node (sys_list_t* sys_list, hawk_int_t id)
|
||||
@ -4826,6 +4838,362 @@ done:
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
||||
#define ENDIAN_BIG 1
|
||||
#define ENDIAN_LITTLE 2
|
||||
#if defined(HAWK_ENDIAN_BIG)
|
||||
# define ENDIAN_NATIVE ENDIAN_BIG
|
||||
#else
|
||||
# define ENDIAN_NATIVE ENDIAN_LITTLE
|
||||
#endif
|
||||
|
||||
static hawk_oow_t pack_int16_t (hawk_uint8_t* dst, hawk_uint16_t val, int endian)
|
||||
{
|
||||
if (endian == ENDIAN_NATIVE)
|
||||
{
|
||||
*dst++ = val;
|
||||
*dst++ = val >> 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
*dst++ = val >> 8;
|
||||
*dst++ = val;
|
||||
}
|
||||
|
||||
return 2;
|
||||
}
|
||||
|
||||
static hawk_oow_t pack_int32_t (hawk_uint8_t* dst, hawk_uint32_t val, int endian)
|
||||
{
|
||||
if (endian == ENDIAN_NATIVE)
|
||||
{
|
||||
*dst++ = val;
|
||||
*dst++ = val >> 8;
|
||||
*dst++ = val >> 16;
|
||||
*dst++ = val >> 24;
|
||||
}
|
||||
else
|
||||
{
|
||||
*dst++ = val >> 24;
|
||||
*dst++ = val >> 16;
|
||||
*dst++ = val >> 8;
|
||||
*dst++ = val;
|
||||
}
|
||||
|
||||
return 4;
|
||||
}
|
||||
|
||||
static hawk_oow_t pack_int64_t (hawk_uint8_t* dst, hawk_uint64_t val, int endian)
|
||||
{
|
||||
if (endian == ENDIAN_NATIVE)
|
||||
{
|
||||
*dst++ = val;
|
||||
*dst++ = val >> 8;
|
||||
*dst++ = val >> 16;
|
||||
*dst++ = val >> 24;
|
||||
*dst++ = val >> 32;
|
||||
*dst++ = val >> 40;
|
||||
*dst++ = val >> 48;
|
||||
*dst++ = val >> 56;
|
||||
}
|
||||
else
|
||||
{
|
||||
*dst++ = val >> 56;
|
||||
*dst++ = val >> 48;
|
||||
*dst++ = val >> 40;
|
||||
*dst++ = val >> 32;
|
||||
*dst++ = val >> 24;
|
||||
*dst++ = val >> 16;
|
||||
*dst++ = val >> 8;
|
||||
*dst++ = val;
|
||||
}
|
||||
|
||||
return 8;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
hawk_uint8_t* tmp;
|
||||
hawk_oow_t newcapa;
|
||||
|
||||
newcapa = HAWK_ALIGN_POW2(rdp->pack.capa + reqsz, 256);
|
||||
if (rdp->pack.ptr == rdp->pack.__static_buf)
|
||||
{
|
||||
tmp = hawk_rtx_allocmem(rtx, newcapa);
|
||||
if (HAWK_UNLIKELY(!tmp)) return -1;
|
||||
HAWK_MEMCPY (tmp, rdp->pack.__static_buf, rdp->pack.len);
|
||||
}
|
||||
else
|
||||
{
|
||||
tmp = hawk_rtx_reallocmem(rtx, rdp->pack.ptr, newcapa);
|
||||
if (HAWK_UNLIKELY(!tmp)) return -1;
|
||||
}
|
||||
|
||||
rdp->pack.ptr = tmp;
|
||||
rdp->pack.capa = newcapa;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static hawk_int_t pack_data (hawk_rtx_t* rtx, const hawk_oocs_t* fmt, const hawk_fnc_info_t* fi, rtx_data_t* rdp)
|
||||
{
|
||||
hawk_oow_t rep_cnt, rep_set, rc;
|
||||
const hawk_ooch_t* fmtp, *fmte;
|
||||
hawk_oow_t arg_idx, arg_cnt;
|
||||
int endian = ENDIAN_NATIVE;
|
||||
|
||||
#define PACK_CHECK_ARG_AND_BUF(reqarg, reqsz) do { \
|
||||
if (arg_cnt - arg_idx < reqarg) return set_error_on_sys_list (rtx, &rdp->sys_list, HAWK_EARGTF, HAWK_NULL); \
|
||||
if (ensure_pack_buf(rtx, rdp, reqsz) <= -1) goto oops_internal; \
|
||||
} while(0)
|
||||
|
||||
rdp->pack.len = 0;
|
||||
|
||||
arg_idx = 2; /* set past the format specifier */
|
||||
arg_cnt = hawk_rtx_getnargs(rtx);
|
||||
|
||||
rep_cnt = 1;
|
||||
rep_set = 0;
|
||||
|
||||
fmte = fmt->ptr + fmt->len;
|
||||
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 */
|
||||
endian = ENDIAN_BIG;
|
||||
break;
|
||||
|
||||
case '!': /* network (= big-endian) */
|
||||
endian = ENDIAN_BIG;
|
||||
break;
|
||||
|
||||
case 'b': /* byte, char */
|
||||
{
|
||||
hawk_int_t v;
|
||||
PACK_CHECK_ARG_AND_BUF (rep_cnt, HAWK_SIZEOF(hawk_int8_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.ptr[rdp->pack.len++] = (hawk_int8_t)v;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case 'B':
|
||||
{
|
||||
hawk_int_t v;
|
||||
PACK_CHECK_ARG_AND_BUF (rep_cnt, HAWK_SIZEOF(hawk_uint8_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.ptr[rdp->pack.len++] = (hawk_uint8_t)v;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case 'h':
|
||||
{
|
||||
hawk_int_t v;
|
||||
PACK_CHECK_ARG_AND_BUF (rep_cnt, HAWK_SIZEOF(hawk_int16_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_int16_t(&rdp->pack.ptr[rdp->pack.len], (hawk_int16_t)v, endian);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case 'H':
|
||||
{
|
||||
hawk_int_t v;
|
||||
PACK_CHECK_ARG_AND_BUF (rep_cnt, HAWK_SIZEOF(hawk_uint16_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_int16_t(&rdp->pack.ptr[rdp->pack.len], (hawk_uint16_t)v, endian);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case 'i':
|
||||
case 'l':
|
||||
{
|
||||
hawk_int_t v;
|
||||
PACK_CHECK_ARG_AND_BUF (rep_cnt, HAWK_SIZEOF(hawk_int32_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_int32_t(&rdp->pack.ptr[rdp->pack.len], (hawk_int32_t)v, endian);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case 'I': /* fall through */
|
||||
case 'L':
|
||||
{
|
||||
hawk_int_t v;
|
||||
PACK_CHECK_ARG_AND_BUF (rep_cnt, HAWK_SIZEOF(hawk_uint32_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_int16_t(&rdp->pack.ptr[rdp->pack.len], (hawk_uint32_t)v, endian);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case 'q':
|
||||
{
|
||||
hawk_int_t v;
|
||||
PACK_CHECK_ARG_AND_BUF (rep_cnt, HAWK_SIZEOF(hawk_int64_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_int64_t(rdp->pack.ptr, (hawk_int64_t)v, endian);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case 'Q':
|
||||
{
|
||||
hawk_int_t v;
|
||||
PACK_CHECK_ARG_AND_BUF (rep_cnt, HAWK_SIZEOF(hawk_uint64_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_int64_t(rdp->pack.ptr, (hawk_uint64_t)v, endian);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
#if 0
|
||||
case 'f':
|
||||
f = va_arg(args, double);
|
||||
pack_float(&bp, f, *ep);
|
||||
break;
|
||||
|
||||
case 'd':
|
||||
d = va_arg(args, double);
|
||||
pack_double(&bp, d, *ep);
|
||||
break;
|
||||
#endif
|
||||
|
||||
|
||||
case 's':
|
||||
case 'p':
|
||||
{
|
||||
hawk_val_t* a;
|
||||
hawk_bcs_t tmp;
|
||||
|
||||
PACK_CHECK_ARG_AND_BUF (1, HAWK_SIZEOF(hawk_uint8_t) * rep_cnt);
|
||||
|
||||
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 (rep_cnt > tmp.len)
|
||||
{
|
||||
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);
|
||||
}
|
||||
for (rc = 0; rc < rep_cnt; rc++) rdp->pack.ptr[rdp->pack.len++] = tmp.ptr[rc];
|
||||
hawk_rtx_freevalbcstr (rtx, a, tmp.ptr);
|
||||
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:
|
||||
/* 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;
|
||||
|
||||
oops_internal:
|
||||
return copy_error_to_sys_list (rtx, &rdp->sys_list);
|
||||
}
|
||||
|
||||
static int fnc_pack (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
|
||||
{
|
||||
rtx_data_t* rdp = rtx_to_data(rtx, fi);
|
||||
hawk_val_t* a0;
|
||||
hawk_oocs_t fmt;
|
||||
hawk_int_t rx = 0;
|
||||
|
||||
a0 = hawk_rtx_getarg(rtx, 1);
|
||||
fmt.ptr = hawk_rtx_getvaloocstr(rtx, a0, &fmt.len);
|
||||
if (HAWK_UNLIKELY(!fmt.ptr))
|
||||
{
|
||||
fail:
|
||||
rx = copy_error_to_sys_list (rtx, &rdp->sys_list);
|
||||
}
|
||||
else
|
||||
{
|
||||
rx = pack_data(rtx, &fmt, fi, rdp);
|
||||
hawk_rtx_freevaloocstr (rtx, a0, fmt.ptr);
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
hawk_rtx_setretval (rtx, hawk_rtx_makeintval(rtx, rx));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int fnc_unpack (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
|
||||
{
|
||||
/* TODO: */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
typedef struct fnctab_t fnctab_t;
|
||||
struct fnctab_t
|
||||
{
|
||||
@ -4840,6 +5208,8 @@ struct inttab_t
|
||||
hawk_mod_sym_int_t info;
|
||||
};
|
||||
|
||||
#define A_MAX HAWK_TYPE_MAX(hawk_oow_t)
|
||||
|
||||
static fnctab_t fnctab[] =
|
||||
{
|
||||
/* keep this table sorted for binary search in query(). */
|
||||
@ -4882,15 +5252,16 @@ static fnctab_t fnctab[] =
|
||||
{ HAWK_T("gettime"), { { 0, 0, HAWK_NULL }, fnc_gettime, 0 } },
|
||||
{ HAWK_T("getuid"), { { 0, 0, HAWK_NULL }, fnc_getuid, 0 } },
|
||||
{ HAWK_T("kill"), { { 2, 2, HAWK_NULL }, fnc_kill, 0 } },
|
||||
{ HAWK_T("listen"), { { 2, 2, HAWK_NULL }, fnc_listen, 0 } },
|
||||
{ HAWK_T("listen"), { { 2, 2, HAWK_NULL }, fnc_listen, 0 } },
|
||||
{ HAWK_T("mkdir"), { { 1, 2, HAWK_NULL }, fnc_mkdir, 0 } },
|
||||
{ HAWK_T("mktime"), { { 0, 1, HAWK_NULL }, fnc_mktime, 0 } },
|
||||
{ HAWK_T("modinmux"), { { 3, 3, HAWK_NULL }, fnc_modinmux, 0 } },
|
||||
{ HAWK_T("modinmux"), { { 3, 3, HAWK_NULL }, fnc_modinmux, 0 } },
|
||||
{ HAWK_T("open"), { { 2, 3, HAWK_NULL }, fnc_open, 0 } },
|
||||
{ HAWK_T("opendir"), { { 1, 2, HAWK_NULL }, fnc_opendir, 0 } },
|
||||
{ HAWK_T("openfd"), { { 1, 1, HAWK_NULL }, fnc_openfd, 0 } },
|
||||
{ HAWK_T("openlog"), { { 3, 3, HAWK_NULL }, fnc_openlog, 0 } },
|
||||
{ HAWK_T("openmux"), { { 0, 0, HAWK_NULL }, fnc_openmux, 0 } },
|
||||
{ HAWK_T("pack"), { { 2, A_MAX, HAWK_T("rv")}, fnc_pack, 0 } },
|
||||
{ HAWK_T("pipe"), { { 2, 3, HAWK_T("rrv") }, fnc_pipe, 0 } },
|
||||
{ HAWK_T("read"), { { 2, 4, HAWK_T("vrvv") }, fnc_read, 0 } },
|
||||
{ HAWK_T("readdir"), { { 2, 2, HAWK_T("vr") }, fnc_readdir, 0 } },
|
||||
@ -5279,19 +5650,23 @@ static int query (hawk_mod_t* mod, hawk_t* hawk, const hawk_ooch_t* name, hawk_m
|
||||
static int init (hawk_mod_t* mod, hawk_rtx_t* rtx)
|
||||
{
|
||||
mod_ctx_t* mctx = (mod_ctx_t*)mod->ctx;
|
||||
rtx_data_t data, * datap;
|
||||
rtx_data_t rd, * rdp;
|
||||
hawk_rbt_pair_t* pair;
|
||||
|
||||
mctx->log.type = SYSLOG_LOCAL;
|
||||
mctx->log.syslog_opened = 0;
|
||||
mctx->log.sck = -1;
|
||||
|
||||
HAWK_MEMSET (&data, 0, HAWK_SIZEOF(data));
|
||||
pair = hawk_rbt_insert(mctx->rtxtab, &rtx, HAWK_SIZEOF(rtx), &data, HAWK_SIZEOF(data));
|
||||
HAWK_MEMSET (&rd, 0, HAWK_SIZEOF(rd));
|
||||
pair = hawk_rbt_insert(mctx->rtxtab, &rtx, HAWK_SIZEOF(rtx), &rd, HAWK_SIZEOF(rd));
|
||||
if (HAWK_UNLIKELY(!pair)) return -1;
|
||||
|
||||
datap = (rtx_data_t*)HAWK_RBT_VPTR(pair);
|
||||
__init_sys_list (rtx, &datap->sys_list);
|
||||
rdp = (rtx_data_t*)HAWK_RBT_VPTR(pair);
|
||||
__init_sys_list (rtx, &rdp->sys_list);
|
||||
|
||||
rdp->pack.ptr = rdp->pack.__static_buf;
|
||||
rdp->pack.capa = HAWK_COUNTOF(rdp->pack.__static_buf);
|
||||
rdp->pack.len = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -5310,19 +5685,20 @@ static void fini (hawk_mod_t* mod, hawk_rtx_t* rtx)
|
||||
pair = hawk_rbt_search(mctx->rtxtab, &rtx, HAWK_SIZEOF(rtx));
|
||||
if (pair)
|
||||
{
|
||||
rtx_data_t* data;
|
||||
rtx_data_t* rdp;
|
||||
|
||||
rdp = (rtx_data_t*)HAWK_RBT_VPTR(pair);
|
||||
|
||||
data = (rtx_data_t*)HAWK_RBT_VPTR(pair);
|
||||
|
||||
if (data->sys_list.ctx.readbuf)
|
||||
if (rdp->sys_list.ctx.readbuf)
|
||||
{
|
||||
hawk_rtx_freemem (rtx, data->sys_list.ctx.readbuf);
|
||||
data->sys_list.ctx.readbuf = HAWK_NULL;
|
||||
data->sys_list.ctx.readbuf_capa = 0;
|
||||
hawk_rtx_freemem (rtx, rdp->sys_list.ctx.readbuf);
|
||||
rdp->sys_list.ctx.readbuf = HAWK_NULL;
|
||||
rdp->sys_list.ctx.readbuf_capa = 0;
|
||||
}
|
||||
|
||||
__fini_sys_list (rtx, &data->sys_list);
|
||||
if (rdp->pack.ptr != rdp->pack.__static_buf) hawk_rtx_freemem (rtx, rdp->pack.ptr);
|
||||
|
||||
__fini_sys_list (rtx, &rdp->sys_list);
|
||||
|
||||
hawk_rbt_delete (mctx->rtxtab, &rtx, HAWK_SIZEOF(rtx));
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user