@ -97,22 +97,26 @@ EXPORT_SYMBOL(bin2hex);
*
* example output buffer :
* 40 41 42 43 44 45 46 47 48 49 4 a 4 b 4 c 4 d 4 e 4f @ ABCDEFGHIJKLMNO
*
* Return :
* The amount of bytes placed in the buffer without terminating NUL . If the
* output was truncated , then the return value is the number of bytes
* ( excluding the terminating NUL ) which would have been written to the final
* string if enough space had been available .
*/
void hex_dump_to_buffer ( const void * buf , size_t len , int rowsize ,
int groupsize , char * linebuf , size_t linebuflen ,
bool ascii )
int hex_dump_to_buffer ( const void * buf , size_t len , int rowsize , int groupsize ,
char * linebuf , size_t linebuflen , bool ascii )
{
const u8 * ptr = buf ;
int ngroups ;
u8 ch ;
int j , lx = 0 ;
int ascii_column ;
int ret ;
if ( rowsize ! = 16 & & rowsize ! = 32 )
rowsize = 16 ;
if ( ! len )
goto nil ;
if ( len > rowsize ) /* limit to one line at a time */
len = rowsize ;
if ( ! is_power_of_2 ( groupsize ) | | groupsize > 8 )
@ -122,27 +126,50 @@ void hex_dump_to_buffer(const void *buf, size_t len, int rowsize,
ngroups = len / groupsize ;
ascii_column = rowsize * 2 + rowsize / groupsize + 1 ;
if ( ! linebuflen )
goto overflow1 ;
if ( ! len )
goto nil ;
if ( groupsize = = 8 ) {
const u64 * ptr8 = buf ;
for ( j = 0 ; j < ngroups ; j + + )
lx + = scnprintf ( linebuf + lx , linebuflen - lx ,
" %s%16.16llx " , j ? " " : " " ,
( unsigned long long ) * ( ptr8 + j ) ) ;
for ( j = 0 ; j < ngroups ; j + + ) {
ret = snprintf ( linebuf + lx , linebuflen - lx ,
" %s%16.16llx " , j ? " " : " " ,
( unsigned long long ) * ( ptr8 + j ) ) ;
if ( ret > = linebuflen - lx )
goto overflow1 ;
lx + = ret ;
}
} else if ( groupsize = = 4 ) {
const u32 * ptr4 = buf ;
for ( j = 0 ; j < ngroups ; j + + )
lx + = scnprintf ( linebuf + lx , linebuflen - lx ,
" %s%8.8x " , j ? " " : " " , * ( ptr4 + j ) ) ;
for ( j = 0 ; j < ngroups ; j + + ) {
ret = snprintf ( linebuf + lx , linebuflen - lx ,
" %s%8.8x " , j ? " " : " " ,
* ( ptr4 + j ) ) ;
if ( ret > = linebuflen - lx )
goto overflow1 ;
lx + = ret ;
}
} else if ( groupsize = = 2 ) {
const u16 * ptr2 = buf ;
for ( j = 0 ; j < ngroups ; j + + )
lx + = scnprintf ( linebuf + lx , linebuflen - lx ,
" %s%4.4x " , j ? " " : " " , * ( ptr2 + j ) ) ;
for ( j = 0 ; j < ngroups ; j + + ) {
ret = snprintf ( linebuf + lx , linebuflen - lx ,
" %s%4.4x " , j ? " " : " " ,
* ( ptr2 + j ) ) ;
if ( ret > = linebuflen - lx )
goto overflow1 ;
lx + = ret ;
}
} else {
for ( j = 0 ; ( j < len ) & & ( lx + 3 ) < = linebuflen ; j + + ) {
for ( j = 0 ; j < len ; j + + ) {
if ( linebuflen < lx + 3 )
goto overflow2 ;
ch = ptr [ j ] ;
linebuf [ lx + + ] = hex_asc_hi ( ch ) ;
linebuf [ lx + + ] = hex_asc_lo ( ch ) ;
@ -154,14 +181,24 @@ void hex_dump_to_buffer(const void *buf, size_t len, int rowsize,
if ( ! ascii )
goto nil ;
while ( lx < ( linebuflen - 1 ) & & lx < ascii_column )
while ( lx < ascii_column ) {
if ( linebuflen < lx + 2 )
goto overflow2 ;
linebuf [ lx + + ] = ' ' ;
for ( j = 0 ; ( j < len ) & & ( lx + 2 ) < linebuflen ; j + + ) {
}
for ( j = 0 ; j < len ; j + + ) {
if ( linebuflen < lx + 2 )
goto overflow2 ;
ch = ptr [ j ] ;
linebuf [ lx + + ] = ( isascii ( ch ) & & isprint ( ch ) ) ? ch : ' . ' ;
}
nil :
linebuf [ lx ] = ' \0 ' ;
return lx ;
overflow2 :
linebuf [ lx + + ] = ' \0 ' ;
overflow1 :
return ascii ? ascii_column + len : ( groupsize * 2 + 1 ) * ngroups - 1 ;
}
EXPORT_SYMBOL ( hex_dump_to_buffer ) ;