From c9cfb1de26f76263c56e03e2465cc22446a68dbc Mon Sep 17 00:00:00 2001 From: Rich Megginson <rmeggins@xxxxxxxxxx> Date: Tue, 15 Nov 2011 11:25:56 -0700 Subject: [PATCH] csn_as_string - use slapi_uN_to_hex instead of sprintf This introduces the following new slapi functions slapi_u8_to_hex slapi_u16_to_hex slapi_u32_to_hex slapi_u64_to_hex which convert the given unsigned integral value to a char* hexadecimal string. Using this for csn_as_string() is 7-8 times faster than sprintf. --- ldap/servers/slapd/csn.c | 8 ++- ldap/servers/slapd/slapi-plugin.h | 88 +++++++++++++++++++++++++++++++++++ ldap/servers/slapd/util.c | 93 +++++++++++++++++++++++++++++++++++++ 3 files changed, 186 insertions(+), 3 deletions(-) diff --git a/ldap/servers/slapd/csn.c b/ldap/servers/slapd/csn.c index f77086c..0480036 100644 --- a/ldap/servers/slapd/csn.c +++ b/ldap/servers/slapd/csn.c @@ -249,9 +249,11 @@ csn_as_string(const CSN *csn, PRBool replicaIdOrder, char *ss) } else { - /* JCM - hex2char would be quicker */ - sprintf(s,"%08lx%04x%04x%04x", - csn->tstamp,csn->seqnum,csn->rid, csn->subseqnum); + char *ptr = slapi_u32_to_hex(csn->tstamp, s, 0); + ptr = slapi_u16_to_hex(csn->seqnum, ptr, 0); + ptr = slapi_u16_to_hex(csn->rid, ptr, 0); + ptr = slapi_u16_to_hex(csn->subseqnum, ptr, 0); + *ptr = 0; } return s; } diff --git a/ldap/servers/slapd/slapi-plugin.h b/ldap/servers/slapd/slapi-plugin.h index a27f8b1..446c5f7 100644 --- a/ldap/servers/slapd/slapi-plugin.h +++ b/ldap/servers/slapd/slapi-plugin.h @@ -6738,6 +6738,94 @@ typedef struct _back_info_crypt_value back_info_crypt_value; #define BACK_CRYPT_OUTBUFF_EXTLEN 16 +/** + * Convert unsigned char (8 bit) value to a hex string. Writes to the string. + * The caller must ensure enough space to write 2 bytes. If the upper parameter + * is TRUE, will use upper case A-F instead of lower case a-f for hex numbers. + * Returns the address after the last byte written to encourage usage like this: + * \code + * char *ptr = slapi_u_to_hex(val, buf, 0); + * ptr = slapi_u_to_hex(val2, ptr, 0); + * ... + * ptr = slapi_u_to_hex(valN, ptr, 0); + * *ptr = 0; + * \endcode + * + * \param val unsigned value to convert to string + * \param s string to write hex value into + * \param upper if TRUE use A-F otherwise use a-f + * \return address of next char after writing value to s + * + * \note Does not null terminate s - caller is responsible for that + */ +char *slapi_u8_to_hex(uint8_t val, char *s, uint8_t upper); + +/** + * Convert unsigned short (16 bit) value to a hex string. Writes to the string. + * The caller must ensure enough space to write 4 bytes. If the upper parameter + * is TRUE, will use upper case A-F instead of lower case a-f for hex numbers. + * Returns the address after the last byte written to encourage usage like this: + * \code + * char *ptr = slapi_u_to_hex(val, buf, 0); + * ptr = slapi_u_to_hex(val2, ptr, 0); + * ... + * ptr = slapi_u_to_hex(valN, ptr, 0); + * *ptr = 0; + * \endcode + * + * \param val unsigned value to convert to string + * \param s string to write hex value into + * \param upper if TRUE use A-F otherwise use a-f + * \return address of next char after writing value to s + * + * \note Does not null terminate s - caller is responsible for that + */ +char *slapi_u16_to_hex(uint16_t val, char *s, uint8_t upper); + +/** + * Convert unsigned int (32 bit) value to a hex string. Writes to the string. + * The caller must ensure enough space to write 4 bytes. If the upper parameter + * is TRUE, will use upper case A-F instead of lower case a-f for hex numbers. + * Returns the address after the last byte written to encourage usage like this: + * \code + * char *ptr = slapi_u_to_hex(val, buf, 0); + * ptr = slapi_u_to_hex(val2, ptr, 0); + * ... + * ptr = slapi_u_to_hex(valN, ptr, 0); + * *ptr = 0; + * \endcode + * + * \param val unsigned value to convert to string + * \param s string to write hex value into + * \param upper if TRUE use A-F otherwise use a-f + * \return address of next char after writing value to s + * + * \note Does not null terminate s - caller is responsible for that + */ +char *slapi_u32_to_hex(uint32_t val, char *s, uint8_t upper); + +/** + * Convert unsigned long long (64 bit) value to a hex string. Writes to the string. + * The caller must ensure enough space to write 4 bytes. If the upper parameter + * is TRUE, will use upper case A-F instead of lower case a-f for hex numbers. + * Returns the address after the last byte written to encourage usage like this: + * \code + * char *ptr = slapi_u_to_hex(val, buf, 0); + * ptr = slapi_u_to_hex(val2, ptr, 0); + * ... + * ptr = slapi_u_to_hex(valN, ptr, 0); + * *ptr = 0; + * \endcode + * + * \param val unsigned value to convert to string + * \param s string to write hex value into + * \param upper if TRUE use A-F otherwise use a-f + * \return address of next char after writing value to s + * + * \note Does not null terminate s - caller is responsible for that + */ +char *slapi_u64_to_hex(uint64_t val, char *s, uint8_t upper); + #ifdef __cplusplus } #endif diff --git a/ldap/servers/slapd/util.c b/ldap/servers/slapd/util.c index b91ec12..e2970b4 100644 --- a/ldap/servers/slapd/util.c +++ b/ldap/servers/slapd/util.c @@ -48,6 +48,7 @@ #include <sys/param.h> #include <unistd.h> #include <pwd.h> +#include <stdint.h> #endif #include <libgen.h> #include <pk11func.h> @@ -911,3 +912,95 @@ slapd_comp_path(char *p0, char *p1) slapi_ch_free_string(&norm_p1); return rval; } + +/* + Takes an unsigned char value and converts it to a hex string. + The string s is written, and the caller must ensure s has enough + space. For hex numbers, the upper argument says to use a-f or A-F. + The return value is the address of the next char after the last one written. +*/ +char * +slapi_u8_to_hex(uint8_t val, char *s, uint8_t upper) { + static char ldigits[] = "0123456789abcdef"; + static char udigits[] = "0123456789ABCDEF"; + char *digits; + + if (upper) { + digits = udigits; + } else { + digits = ldigits; + } + s[0] = digits[val >> 4]; + s[1] = digits[val & 0xf]; + return &s[2]; +} + +char * +slapi_u16_to_hex(uint16_t val, char *s, uint8_t upper) { + static char ldigits[] = "0123456789abcdef"; + static char udigits[] = "0123456789ABCDEF"; + char *digits; + + if (upper) { + digits = udigits; + } else { + digits = ldigits; + } + s[0] = digits[val >> 12]; + s[1] = digits[(val >> 8) & 0xf]; + s[2] = digits[(val >> 4) & 0xf]; + s[3] = digits[val & 0xf]; + return &s[4]; +} + +char * +slapi_u32_to_hex(uint32_t val, char *s, uint8_t upper) { + static char ldigits[] = "0123456789abcdef"; + static char udigits[] = "0123456789ABCDEF"; + char *digits; + + if (upper) { + digits = udigits; + } else { + digits = ldigits; + } + s[0] = digits[val >> 28]; + s[1] = digits[(val >> 24) & 0xf]; + s[2] = digits[(val >> 20) & 0xf]; + s[3] = digits[(val >> 16) & 0xf]; + s[4] = digits[(val >> 12) & 0xf]; + s[5] = digits[(val >> 8) & 0xf]; + s[6] = digits[(val >> 4) & 0xf]; + s[7] = digits[val & 0xf]; + return &s[8]; +} + +char * +slapi_u64_to_hex(uint64_t val, char *s, uint8_t upper) { + static char ldigits[] = "0123456789abcdef"; + static char udigits[] = "0123456789ABCDEF"; + char *digits; + + if (upper) { + digits = udigits; + } else { + digits = ldigits; + } + s[0] = digits[val >> 60]; + s[1] = digits[(val >> 56) & 0xf]; + s[2] = digits[(val >> 52) & 0xf]; + s[3] = digits[(val >> 48) & 0xf]; + s[4] = digits[(val >> 44) & 0xf]; + s[5] = digits[(val >> 40) & 0xf]; + s[6] = digits[(val >> 36) & 0xf]; + s[7] = digits[(val >> 32) & 0xf]; + s[8] = digits[(val >> 28) & 0xf]; + s[9] = digits[(val >> 24) & 0xf]; + s[10] = digits[(val >> 20) & 0xf]; + s[11] = digits[(val >> 16) & 0xf]; + s[12] = digits[(val >> 12) & 0xf]; + s[13] = digits[(val >> 8) & 0xf]; + s[14] = digits[(val >> 4) & 0xf]; + s[15] = digits[val & 0xf]; + return &s[16]; +} -- 1.7.1
-- 389-devel mailing list 389-devel@xxxxxxxxxxxxxxxxxxxxxxx https://admin.fedoraproject.org/mailman/listinfo/389-devel