[Stefan Fuhrmann] > --- subversion/libsvn_subr/checksum.c (revision 937673) > +++ subversion/libsvn_subr/checksum.c (working copy) > @@ -206,12 +206,39 @@ > > for (i = 0; i < len; i++) > { > - if ((! isxdigit(hex[i * 2])) || (! isxdigit(hex[i * 2 + 1]))) > + char c1 = hex[i * 2]; > + char c2 = hex[i * 2 + 1];
Hmmmm. On the one hand, your open-coding of isxdigit will be less efficient than the original, which uses a table lookup. On the other hand, replacing isalpha is probably for the best, since isalpha is locale-sensitive. I'd rather see the whole thing become a single table lookup. Untested patch appended. Peter [[[ * subversion/libsvn_subr/checksum.c (svn_checksum_parse_hex): Use a single table lookup in place of isxdigit, isalpha, and (foo - 'a' + 10) gymnastics. UNTESTED. ]]] --- subversion/libsvn_subr/checksum.c +++ subversion/libsvn_subr/checksum.c @@ -192,6 +192,16 @@ int len; int i; unsigned char is_zeros = '\0'; + static const unsigned char xdigitval[256] = + { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 2, 3, 4, 5, 6, 7, 8, 9,10, 0, 0, 0, 0, 0, 0, /* 0-9 */ + 0,11,12,13,14,15,16, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* A-F */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0,11,12,13,14,15,16, /* a-f */ + }; if (hex == NULL) { @@ -206,13 +216,12 @@ for (i = 0; i < len; i++) { - if ((! isxdigit(hex[i * 2])) || (! isxdigit(hex[i * 2 + 1]))) + unsigned char x1 = xdigitval((unsigned char)hex[i * 2]); + unsigned char x2 = xdigitval((unsigned char)hex[i * 2 + 1]); + if (!x1-- || !x2--) return svn_error_create(SVN_ERR_BAD_CHECKSUM_PARSE, NULL, NULL); - ((unsigned char *)(*checksum)->digest)[i] = - (( isalpha(hex[i*2]) ? hex[i*2] - 'a' + 10 : hex[i*2] - '0') << 4) | - ( isalpha(hex[i*2+1]) ? hex[i*2+1] - 'a' + 10 : hex[i*2+1] - '0'); - is_zeros |= (*checksum)->digest[i]; + is_zeros |= ((unsigned char *)(*checksum)->digest)[i] = x1 << 4 | x2; } if (is_zeros == '\0')