added qse_bytetombs()/qse_bytetowcs()

implemeting %k for formatted output to hex-dump a given string
This commit is contained in:
hyung-hwan 2019-03-15 08:10:13 +00:00
parent 5cf583d8c4
commit 88b39ee0af
3 changed files with 156 additions and 8 deletions

View File

@ -2463,10 +2463,33 @@ QSE_EXPORT int qse_wcshextobin (
qse_size_t buflen 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) #if defined(QSE_CHAR_IS_MCHAR)
# define qse_strhextobin qse_mbshextobin # define qse_strhextobin qse_mbshextobin
# define qse_bytetostr qse_bytetombs
#else #else
# define qse_strhextobin qse_wcshextobin # define qse_strhextobin qse_wcshextobin
# define qse_bytetostr qse_bytetowcs
#endif #endif
QSE_EXPORT qse_size_t qse_mbsdel ( QSE_EXPORT qse_size_t qse_mbsdel (

View File

@ -109,6 +109,7 @@ int fmtout (const char_t* fmt, fmtout_t* data, va_list ap)
char_t ach, padc, * sp; char_t ach, padc, * sp;
ochar_t oach, * osp; ochar_t oach, * osp;
qse_size_t oslen, slen; qse_size_t oslen, slen;
qse_byte_t* bytep;
int lm_flag, lm_dflag, flagc, numlen; int lm_flag, lm_dflag, flagc, numlen;
qse_uintmax_t num = 0; qse_uintmax_t num = 0;
int stop = 0; int stop = 0;
@ -368,7 +369,6 @@ reswitch:
goto reswitch; goto reswitch;
} }
/* end of length modifiers */ /* end of length modifiers */
case T('n'): case T('n'):
@ -538,10 +538,18 @@ reswitch:
/* get the length */ /* get the length */
for (oslen = 0; osp[oslen]; oslen++); for (oslen = 0; osp[oslen]; oslen++);
if (data->conv (osp, &oslen, QSE_NULL, &slen, data->ctx) <= -1) if (ch == T('K'))
{ {
/* conversion error */ oslen = 1;
goto oops; slen = 2;
}
else
{
if (data->conv (osp, &oslen, QSE_NULL, &slen, data->ctx) <= -1)
{
/* conversion error */
goto oops;
}
} }
/* slen hold the length after conversion */ /* slen hold the length after conversion */
@ -568,8 +576,17 @@ reswitch:
#endif #endif
conv_len = QSE_COUNTOF(conv_buf); conv_len = QSE_COUNTOF(conv_buf);
/* this must not fail since the dry-run above was successful */ if (ch == T('K'))
data->conv (&osp[tot_len], &src_len, conv_buf, &conv_len, data->ctx); {
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; tot_len += src_len;
/* stop outputting if a converted character can't be printed /* stop outputting if a converted character can't be printed
@ -591,6 +608,42 @@ reswitch:
} }
break; 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('E'): case T('E'):
case T('f'): case T('f'):
@ -652,7 +705,7 @@ reswitch:
#if (QSE_SIZEOF___FLOAT128 > 0) && defined(HAVE_QUADMATH_SNPRINTF) #if (QSE_SIZEOF___FLOAT128 > 0) && defined(HAVE_QUADMATH_SNPRINTF)
else if (lm_flag & (LF_QD | LF_Q)) else if (lm_flag & (LF_QD | LF_Q))
{ {
v_qd = va_arg (ap, __float128); v_qd = va_arg(ap, __float128);
dtype = LF_QD; dtype = LF_QD;
} }
#endif #endif

View File

@ -420,3 +420,75 @@ int qse_wcshextobin (const qse_wchar_t* hex, qse_size_t hexlen, qse_uint8_t* buf
return 0; 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;
}