added some code for sys::unpack()
This commit is contained in:
		| @ -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; | ||||
|  | ||||
		Reference in New Issue
	
	Block a user