added qse_bytetombs()/qse_bytetowcs()
implemeting %k for formatted output to hex-dump a given string
This commit is contained in:
		@ -2463,10 +2463,33 @@ QSE_EXPORT int qse_wcshextobin (
 | 
			
		||||
	qse_size_t         buflen
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#define QSE_BYTETOSTR_RADIXMASK (0xFF)
 | 
			
		||||
#define QSE_BYTETOSTR_LOWERCASE (1 << 8)
 | 
			
		||||
 | 
			
		||||
qse_size_t qse_bytetombs (
 | 
			
		||||
	qse_byte_t   byte,  
 | 
			
		||||
	qse_mchar_t* buf,
 | 
			
		||||
	qse_size_t   size,
 | 
			
		||||
	int          flagged_radix,
 | 
			
		||||
	qse_mchar_t  fill
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
qse_size_t qse_bytetowcs (
 | 
			
		||||
	qse_byte_t   byte,  
 | 
			
		||||
	qse_wchar_t* buf,
 | 
			
		||||
	qse_size_t   size,
 | 
			
		||||
	int          flagged_radix,
 | 
			
		||||
	qse_wchar_t  fill
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#if defined(QSE_CHAR_IS_MCHAR)
 | 
			
		||||
#	define qse_strhextobin qse_mbshextobin
 | 
			
		||||
#	define qse_bytetostr qse_bytetombs
 | 
			
		||||
#else
 | 
			
		||||
#	define qse_strhextobin qse_wcshextobin
 | 
			
		||||
#	define qse_bytetostr qse_bytetowcs
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
QSE_EXPORT qse_size_t qse_mbsdel (
 | 
			
		||||
 | 
			
		||||
@ -109,6 +109,7 @@ int fmtout (const char_t* fmt, fmtout_t* data, va_list ap)
 | 
			
		||||
	char_t ach, padc, * sp;
 | 
			
		||||
	ochar_t oach, * osp;
 | 
			
		||||
	qse_size_t oslen, slen;
 | 
			
		||||
	qse_byte_t* bytep;
 | 
			
		||||
	int lm_flag, lm_dflag, flagc, numlen;
 | 
			
		||||
	qse_uintmax_t num = 0;
 | 
			
		||||
	int stop = 0;
 | 
			
		||||
@ -367,8 +368,7 @@ reswitch:
 | 
			
		||||
			flagc |= FLAGC_LENMOD;
 | 
			
		||||
			goto reswitch;
 | 
			
		||||
		}
 | 
			
		||||
			
 | 
			
		||||
			
 | 
			
		||||
 | 
			
		||||
		/* end of length modifiers */
 | 
			
		||||
 | 
			
		||||
		case T('n'):
 | 
			
		||||
@ -538,10 +538,18 @@ reswitch:
 | 
			
		||||
			/* get the length */
 | 
			
		||||
			for (oslen = 0; osp[oslen]; oslen++);
 | 
			
		||||
 | 
			
		||||
			if (data->conv (osp, &oslen, QSE_NULL, &slen, data->ctx) <= -1)
 | 
			
		||||
			if (ch == T('K'))
 | 
			
		||||
			{
 | 
			
		||||
				/* conversion error */
 | 
			
		||||
				goto oops;
 | 
			
		||||
				oslen = 1;
 | 
			
		||||
				slen = 2;
 | 
			
		||||
			}
 | 
			
		||||
			else
 | 
			
		||||
			{
 | 
			
		||||
				if (data->conv (osp, &oslen, QSE_NULL, &slen, data->ctx) <= -1)
 | 
			
		||||
				{
 | 
			
		||||
					/* conversion error */
 | 
			
		||||
					goto oops;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			/* slen hold the length after conversion */
 | 
			
		||||
@ -568,8 +576,17 @@ reswitch:
 | 
			
		||||
				#endif
 | 
			
		||||
					conv_len = QSE_COUNTOF(conv_buf);
 | 
			
		||||
 | 
			
		||||
					/* this must not fail since the dry-run above was successful */
 | 
			
		||||
					data->conv (&osp[tot_len], &src_len, conv_buf, &conv_len, data->ctx);
 | 
			
		||||
					if (ch == T('K'))
 | 
			
		||||
					{
 | 
			
		||||
						src_len = 1;
 | 
			
		||||
						conv_len = 2;
 | 
			
		||||
						qse_bytetombs(osp[tot_len], conv_buf, 2, 16, '0');
 | 
			
		||||
					}
 | 
			
		||||
					else
 | 
			
		||||
					{
 | 
			
		||||
						/* this must not fail since the dry-run above was successful */
 | 
			
		||||
						data->conv (&osp[tot_len], &src_len, conv_buf, &conv_len, data->ctx);
 | 
			
		||||
					}
 | 
			
		||||
					tot_len += src_len;
 | 
			
		||||
 | 
			
		||||
					/* stop outputting if a converted character can't be printed 
 | 
			
		||||
@ -591,6 +608,42 @@ reswitch:
 | 
			
		||||
			}
 | 
			
		||||
			break;
 | 
			
		||||
 | 
			
		||||
		case T('k'):
 | 
			
		||||
			/* zerpad must not take effect for 's'. H & L doesn't take effect on 'k' */
 | 
			
		||||
			if (flagc & FLAGC_ZEROPAD) padc = T(' ');
 | 
			
		||||
 | 
			
		||||
			bytep = va_arg (ap, qse_byte_t*);
 | 
			
		||||
			if (bytep == QSE_NULL) p = T("(null)");
 | 
			
		||||
 | 
			
		||||
			if (flagc & FLAGC_DOT)
 | 
			
		||||
			{
 | 
			
		||||
				for (n = 0; n < precision && bytep[n]; n++);
 | 
			
		||||
			}
 | 
			
		||||
			else
 | 
			
		||||
			{
 | 
			
		||||
				for (n = 0; bytep[n]; n++);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			width -= (n * 2);
 | 
			
		||||
 | 
			
		||||
			if (!(flagc & FLAGC_LEFTADJ) && width > 0)
 | 
			
		||||
			{
 | 
			
		||||
				while (width--) PUT_CHAR(padc);
 | 
			
		||||
			}
 | 
			
		||||
			while (n--) 
 | 
			
		||||
			{
 | 
			
		||||
				qse_mchar_t xbuf[3];
 | 
			
		||||
				qse_bytetombs (*bytep, xbuf, QSE_COUNTOF(xbuf), 16, QSE_MT('0'));
 | 
			
		||||
				PUT_CHAR(xbuf[0]);
 | 
			
		||||
				PUT_CHAR(xbuf[1]);
 | 
			
		||||
				bytep++;
 | 
			
		||||
			}
 | 
			
		||||
			if ((flagc & FLAGC_LEFTADJ) && width > 0)
 | 
			
		||||
			{
 | 
			
		||||
				while (width--) PUT_CHAR(padc);
 | 
			
		||||
			}
 | 
			
		||||
			break;
 | 
			
		||||
 | 
			
		||||
		case T('e'):
 | 
			
		||||
		case T('E'):
 | 
			
		||||
		case T('f'):
 | 
			
		||||
@ -652,7 +705,7 @@ reswitch:
 | 
			
		||||
		#if (QSE_SIZEOF___FLOAT128 > 0) && defined(HAVE_QUADMATH_SNPRINTF)
 | 
			
		||||
			else if (lm_flag & (LF_QD | LF_Q))
 | 
			
		||||
			{
 | 
			
		||||
				v_qd = va_arg (ap, __float128);	
 | 
			
		||||
				v_qd = va_arg(ap, __float128);
 | 
			
		||||
				dtype = LF_QD;
 | 
			
		||||
			}
 | 
			
		||||
		#endif
 | 
			
		||||
 | 
			
		||||
@ -420,3 +420,75 @@ int qse_wcshextobin (const qse_wchar_t* hex, qse_size_t hexlen, qse_uint8_t* buf
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*---------------------------------------------------------------
 | 
			
		||||
 * Byte to string conversion
 | 
			
		||||
 *---------------------------------------------------------------*/
 | 
			
		||||
qse_size_t qse_bytetombs (qse_byte_t byte, qse_mchar_t* buf, qse_size_t size, int flagged_radix, qse_mchar_t fill)
 | 
			
		||||
{
 | 
			
		||||
	qse_mchar_t tmp[(QSE_SIZEOF(qse_byte_t) * 8)];
 | 
			
		||||
	qse_mchar_t* p = tmp, * bp = buf, * be = buf + size - 1;
 | 
			
		||||
	int radix;
 | 
			
		||||
	qse_mchar_t radix_char;
 | 
			
		||||
 | 
			
		||||
	radix = (flagged_radix & QSE_BYTETOSTR_RADIXMASK);
 | 
			
		||||
	radix_char = (flagged_radix & QSE_BYTETOSTR_LOWERCASE)? QSE_MT('a'): QSE_MT('A');
 | 
			
		||||
	if (radix < 2 || radix > 36 || size <= 0) return 0;
 | 
			
		||||
 | 
			
		||||
	do 
 | 
			
		||||
	{
 | 
			
		||||
		qse_byte_t digit = byte % radix;	
 | 
			
		||||
		if (digit < 10) *p++ = digit + QSE_MT('0');
 | 
			
		||||
		else *p++ = digit + radix_char - 10;
 | 
			
		||||
		byte /= radix;
 | 
			
		||||
	}
 | 
			
		||||
	while (byte > 0);
 | 
			
		||||
 | 
			
		||||
	if (fill != QSE_MT('\0')) 
 | 
			
		||||
	{
 | 
			
		||||
		while (size - 1 > p - tmp) 
 | 
			
		||||
		{
 | 
			
		||||
			*bp++ = fill;
 | 
			
		||||
			size--;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	while (p > tmp && bp < be) *bp++ = *--p;
 | 
			
		||||
	*bp = QSE_MT('\0');
 | 
			
		||||
	return bp - buf;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
qse_size_t qse_bytetowcs (qse_byte_t byte, qse_wchar_t* buf, qse_size_t size, int flagged_radix, qse_wchar_t fill)
 | 
			
		||||
{
 | 
			
		||||
	qse_wchar_t tmp[(QSE_SIZEOF(qse_byte_t) * 8)];
 | 
			
		||||
	qse_wchar_t* p = tmp, * bp = buf, * be = buf + size - 1;
 | 
			
		||||
	int radix;
 | 
			
		||||
	qse_wchar_t radix_char;
 | 
			
		||||
 | 
			
		||||
	radix = (flagged_radix & QSE_BYTETOSTR_RADIXMASK);
 | 
			
		||||
	radix_char = (flagged_radix & QSE_BYTETOSTR_LOWERCASE)? QSE_WT('a'): QSE_WT('A');
 | 
			
		||||
	if (radix < 2 || radix > 36 || size <= 0) return 0;
 | 
			
		||||
 | 
			
		||||
	do 
 | 
			
		||||
	{
 | 
			
		||||
		qse_byte_t digit = byte % radix;	
 | 
			
		||||
		if (digit < 10) *p++ = digit + QSE_WT('0');
 | 
			
		||||
		else *p++ = digit + radix_char - 10;
 | 
			
		||||
		byte /= radix;
 | 
			
		||||
	}
 | 
			
		||||
	while (byte > 0);
 | 
			
		||||
 | 
			
		||||
	if (fill != QSE_WT('\0')) 
 | 
			
		||||
	{
 | 
			
		||||
		while (size - 1 > p - tmp) 
 | 
			
		||||
		{
 | 
			
		||||
			*bp++ = fill;
 | 
			
		||||
			size--;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	while (p > tmp && bp < be) *bp++ = *--p;
 | 
			
		||||
	*bp = QSE_WT('\0');
 | 
			
		||||
	return bp - buf;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user