So who would have thought that Hexadecimal to ASCII encoding methods would turn into an entire series. So here is the fourth (I think) installment of ever-so-illusive algorithm from A. C. Hynes, implemented yet again in C:
typedef enum {
H2AERR_OK,
H2AERR_BUFFER_TOO_SMALL,
H2AERR_INVALID_HEX,
} h2a_err_t;
h2a_err_t hex2asc( char * to, const char * from, size_t size )
{
int c = 0;
h2a_err_t rtn = H2AERR_OK;
if ( ! size )
return H2AERR_BUFFER_TOO_SMALL;
H2A_START:
if ( ! --size ) {
rtn = H2AERR_BUFFER_TOO_SMALL;
goto H2A_ACCEPT;
}
c = *from++;
switch ( c ) {
case 0:
goto H2A_ACCEPT;
case '%':
goto H2A_PCNT_0;
default:
*to++ = c;
goto H2A_START;
}
H2A_PCNT_0:
if ( ! --size ) {
rtn = H2AERR_BUFFER_TOO_SMALL;
goto H2A_ACCEPT;
}
c = *from++;
if ( isxdigit( c ) )
goto H2A_PCNT_1;
rtn = H2AERR_INVALID_HEX;
goto H2A_ACCEPT;
H2A_PCNT_1:
if ( ! --size ) {
rtn = H2AERR_BUFFER_TOO_SMALL;
goto H2A_ACCEPT;
}
c = *from++;
if ( isxdigit( c ) ) {
*to++ = strtol( from - 2, NULL, 16 );
goto H2A_START;
}
rtn = H2AERR_INVALID_HEX;
goto H2A_ACCEPT;
H2A_ACCEPT:
*to = 0;
return rtn;
}