mirror of
https://github.com/servalproject/serval-dna.git
synced 2025-01-18 02:39:44 +00:00
Add strn_fromhex(), improve hexvalue()
Implement fromhex() and fromhexstr() using strn_fromhex()
This commit is contained in:
parent
9d1c3e0cba
commit
34bbfb9b30
71
str.c
71
str.c
@ -43,32 +43,67 @@ char *tohex(char *dstHex, const unsigned char *srcBinary, size_t bytes)
|
||||
}
|
||||
|
||||
/* Convert nbinary*2 ASCII hex characters [0-9A-Fa-f] to nbinary bytes of data. Can be used to
|
||||
perform the conversion in-place, eg, fromhex(buf, (char*)buf, n); Returns -1 if a non-hex-digit
|
||||
character is encountered, otherwise returns the number of binary bytes produced (= nbinary).
|
||||
@author Andrew Bettison <andrew@servalproject.com>
|
||||
* perform the conversion in-place, eg, fromhex(buf, (char*)buf, n); Returns -1 if a non-hex-digit
|
||||
* character is encountered, otherwise returns the number of binary bytes produced (= nbinary).
|
||||
*
|
||||
* @author Andrew Bettison <andrew@servalproject.com>
|
||||
*/
|
||||
size_t fromhex(unsigned char *dstBinary, const char *srcHex, size_t nbinary)
|
||||
{
|
||||
size_t count = 0;
|
||||
while (count != nbinary) {
|
||||
unsigned char high = hexvalue(*srcHex++);
|
||||
if (high & 0xf0) return -1;
|
||||
unsigned char low = hexvalue(*srcHex++);
|
||||
if (low & 0xf0) return -1;
|
||||
dstBinary[count++] = (high << 4) + low;
|
||||
}
|
||||
return count;
|
||||
if (strn_fromhex(dstBinary, nbinary, srcHex, NULL) == nbinary)
|
||||
return nbinary;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Convert nbinary*2 ASCII hex characters [0-9A-Fa-f] followed by a nul '\0' character to nbinary bytes of data. Can be used to
|
||||
perform the conversion in-place, eg, fromhex(buf, (char*)buf, n); Returns -1 if a non-hex-digit
|
||||
character is encountered or the character immediately following the last hex digit is not a nul,
|
||||
otherwise returns zero.
|
||||
@author Andrew Bettison <andrew@servalproject.com>
|
||||
/* Convert nbinary*2 ASCII hex characters [0-9A-Fa-f] followed by a nul '\0' character to nbinary
|
||||
* bytes of data. Can be used to perform the conversion in-place, eg, fromhex(buf, (char*)buf, n);
|
||||
* Returns -1 if a non-hex-digit character is encountered or the character immediately following the
|
||||
* last hex digit is not a nul, otherwise returns zero.
|
||||
*
|
||||
* @author Andrew Bettison <andrew@servalproject.com>
|
||||
*/
|
||||
int fromhexstr(unsigned char *dstBinary, const char *srcHex, size_t nbinary)
|
||||
{
|
||||
return (fromhex(dstBinary, srcHex, nbinary) == nbinary && srcHex[nbinary * 2] == '\0') ? 0 : -1;
|
||||
const char *p;
|
||||
if (strn_fromhex(dstBinary, nbinary, srcHex, &p) == nbinary && *p == '\0')
|
||||
return 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Decode pairs of ASCII hex characters [0-9A-Fa-f] into binary data with an optional upper limit on
|
||||
* the number of binary bytes produced (destination buffer size). Returns the number of binary
|
||||
* bytes decoded. If 'afterHex' is not NULL, then sets *afterHex to point to the source character
|
||||
* immediately following the last hex digit consumed.
|
||||
*
|
||||
* Can be used to perform a conversion in-place, eg:
|
||||
*
|
||||
* strn_fromhex((unsigned char *)buf, n, (const char *)buf, NULL);
|
||||
*
|
||||
* Can also be used to count hex digits without converting, eg:
|
||||
*
|
||||
* strn_fromhex(NULL, -1, buf, NULL);
|
||||
*
|
||||
* @author Andrew Bettison <andrew@servalproject.com>
|
||||
*/
|
||||
size_t strn_fromhex(unsigned char *dstBinary, ssize_t dstlen, const char *srcHex, const char **afterHex)
|
||||
{
|
||||
unsigned char *dstorig = dstBinary;
|
||||
unsigned char *dstend = dstBinary + dstlen;
|
||||
while (dstlen == -1 || dstBinary < dstend) {
|
||||
int high = hexvalue(srcHex[0]);
|
||||
if (high == -1)
|
||||
break;
|
||||
int low = hexvalue(srcHex[1]);
|
||||
if (low == -1)
|
||||
break;
|
||||
if (dstorig != NULL)
|
||||
*dstBinary = (high << 4) + low;
|
||||
++dstBinary;
|
||||
srcHex += 2;
|
||||
}
|
||||
if (afterHex)
|
||||
*afterHex = srcHex;
|
||||
return dstBinary - dstorig;
|
||||
}
|
||||
|
||||
/* Does this whole buffer contain the same value? */
|
||||
|
27
str.h
27
str.h
@ -64,19 +64,36 @@ extern const char hexdigit[16];
|
||||
char *tohex(char *dstHex, const unsigned char *srcBinary, size_t bytes);
|
||||
size_t fromhex(unsigned char *dstBinary, const char *srcHex, size_t nbinary);
|
||||
int fromhexstr(unsigned char *dstBinary, const char *srcHex, size_t nbinary);
|
||||
int is_all_matching(const unsigned char *ptr, size_t len, unsigned char value);
|
||||
char *str_toupper_inplace(char *s);
|
||||
size_t strn_fromhex(unsigned char *dstBinary, ssize_t dstlen, const char *src, const char **afterp);
|
||||
|
||||
#define alloca_tohex(buf,len) tohex((char *)alloca((len)*2+1), (buf), (len))
|
||||
|
||||
__STR_INLINE int hexvalue(char c)
|
||||
{
|
||||
if (c >= '0' && c <= '9') return c - '0';
|
||||
if (c >= 'A' && c <= 'F') return c - 'A' + 10;
|
||||
if (c >= 'a' && c <= 'f') return c - 'a' + 10;
|
||||
switch (c) {
|
||||
case '0': return 0;
|
||||
case '1': return 1;
|
||||
case '2': return 2;
|
||||
case '3': return 3;
|
||||
case '4': return 4;
|
||||
case '5': return 5;
|
||||
case '6': return 6;
|
||||
case '7': return 7;
|
||||
case '8': return 8;
|
||||
case '9': return 9;
|
||||
case 'a': case 'A': return 10;
|
||||
case 'b': case 'B': return 11;
|
||||
case 'c': case 'C': return 12;
|
||||
case 'd': case 'D': return 13;
|
||||
case 'e': case 'E': return 14;
|
||||
case 'f': case 'F': return 15;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int is_all_matching(const unsigned char *ptr, size_t len, unsigned char value);
|
||||
char *str_toupper_inplace(char *s);
|
||||
|
||||
char *toprint(char *dstStr, ssize_t dstBufSiz, const char *srcBuf, size_t srcBytes, const char quotes[2]);
|
||||
char *toprint_str(char *dstStr, ssize_t dstBufSiz, const char *srcStr, const char quotes[2]);
|
||||
size_t toprint_len(const char *srcBuf, size_t srcBytes, const char quotes[2]);
|
||||
|
Loading…
Reference in New Issue
Block a user