diff options
author | Douglas Bagnall <douglas.bagnall@catalyst.net.nz> | 2018-02-16 17:53:15 +1300 |
---|---|---|
committer | Douglas Bagnall <dbagnall@samba.org> | 2018-02-22 01:04:18 +0100 |
commit | 6ef6ddce5a64c55729c2e3d423757f504b0ab15e (patch) | |
tree | c4196990dd5fd42ee3db23e05d279d888133f6cb /lib | |
parent | 33ef0e57a4f08eae5ea06f482374fbc0a1014de6 (diff) | |
download | samba-6ef6ddce5a64c55729c2e3d423757f504b0ab15e.tar.gz |
shift read_hex_bytes() and parse_guid_string() into lib/util
read_hex_bytes() is going to be used in lib/util/rfc1738.c.
parse_guid_string() is shifted for two reasons: Firstly, it is called
very often in some operations, sometimes constituting a few percent of
the CPU load, and it makes several calls to read_hex_bytes(). We want
the compiler to be able to inline those calls if it thinks that is
wise. Secondly, there are other places that could do with fast GUID
parsing.
Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
Diffstat (limited to 'lib')
-rw-r--r-- | lib/util/util_str_hex.c | 100 | ||||
-rw-r--r-- | lib/util/util_str_hex.h | 10 | ||||
-rw-r--r-- | lib/util/wscript_build | 7 |
3 files changed, 116 insertions, 1 deletions
diff --git a/lib/util/util_str_hex.c b/lib/util/util_str_hex.c new file mode 100644 index 00000000000..148735bd5f3 --- /dev/null +++ b/lib/util/util_str_hex.c @@ -0,0 +1,100 @@ +#include "replace.h" +#include "libcli/util/ntstatus.h" +#include "util_str_hex.h" + +NTSTATUS read_hex_bytes(const char *s, uint hexchars, uint64_t *dest) +{ + uint64_t x = 0; + uint i; + char c; + + if ((hexchars & 1) || hexchars > 16) { + return NT_STATUS_INVALID_PARAMETER; + } + + for (i = 0; i < hexchars; i++) { + x <<= 4; + c = s[i]; + if (c >= '0' && c <= '9') { + x += c - '0'; + } + else if (c >= 'a' && c <= 'f') { + x += c - 'a' + 10; + } + else if (c >= 'A' && c <= 'F') { + x += c - 'A' + 10; + } + else { + /* BAD character (including '\0') */ + return NT_STATUS_INVALID_PARAMETER; + } + } + *dest = x; + return NT_STATUS_OK; +} + + +NTSTATUS parse_guid_string(const char *s, + uint32_t *time_low, + uint32_t *time_mid, + uint32_t *time_hi_and_version, + uint32_t *clock_seq, + uint32_t *node) +{ + uint64_t tmp; + NTSTATUS status; + int i; + /* "e12b56b6-0a95-11d1-adbb-00c04fd8d5cd" + | | | | | + | | | | \ node[6] + | | | \_____ clock_seq[2] + | | \__________ time_hi_and_version + | \_______________ time_mid + \_____________________ time_low + */ + status = read_hex_bytes(s, 8, &tmp); + if (!NT_STATUS_IS_OK(status) || s[8] != '-') { + return NT_STATUS_INVALID_PARAMETER; + } + *time_low = tmp; + s += 9; + + status = read_hex_bytes(s, 4, &tmp); + if (!NT_STATUS_IS_OK(status) || s[4] != '-') { + return NT_STATUS_INVALID_PARAMETER; + } + *time_mid = tmp; + s += 5; + + status = read_hex_bytes(s, 4, &tmp); + if (!NT_STATUS_IS_OK(status) || s[4] != '-') { + return NT_STATUS_INVALID_PARAMETER; + } + *time_hi_and_version = tmp; + s += 5; + + for (i = 0; i < 2; i++) { + status = read_hex_bytes(s, 2, &tmp); + if (!NT_STATUS_IS_OK(status)) { + return NT_STATUS_INVALID_PARAMETER; + } + clock_seq[i] = tmp; + s += 2; + } + if (s[0] != '-') { + return NT_STATUS_INVALID_PARAMETER; + } + + s++; + + for (i = 0; i < 6; i++) { + status = read_hex_bytes(s, 2, &tmp); + if (!NT_STATUS_IS_OK(status)) { + return NT_STATUS_INVALID_PARAMETER; + } + node[i] = tmp; + s += 2; + } + + return NT_STATUS_OK; +} diff --git a/lib/util/util_str_hex.h b/lib/util/util_str_hex.h new file mode 100644 index 00000000000..2d0ba65636b --- /dev/null +++ b/lib/util/util_str_hex.h @@ -0,0 +1,10 @@ +#include "../libcli/util/ntstatus.h" + +NTSTATUS read_hex_bytes(const char *s, uint hexchars, uint64_t *dest); + +NTSTATUS parse_guid_string(const char *s, + uint32_t *time_low, + uint32_t *time_mid, + uint32_t *time_hi_and_version, + uint32_t *clock_seq, + uint32_t *node); diff --git a/lib/util/wscript_build b/lib/util/wscript_build index 30face34381..8dbe1636e3b 100644 --- a/lib/util/wscript_build +++ b/lib/util/wscript_build @@ -123,7 +123,7 @@ else: util_str.c util_str_common.c ms_fnmatch.c server_id.c dprintf.c tevent_debug.c memcache.c unix_match.c tfork.c''', - deps='samba-util-core DYNCONFIG close-low-fd tini tiniparser genrand', + deps='samba-util-core DYNCONFIG close-low-fd tini tiniparser genrand util_str_hex', public_deps='talloc tevent execinfo pthread LIBCRYPTO charset util_setid systemd systemd-daemon', public_headers='debug.h attr.h byteorder.h data_blob.h memory.h safe_string.h time.h talloc_stack.h string_wrappers.h idtree.h idtree_random.h blocking.h signal.h substitute.h fault.h genrand.h tfork.h', header_path= [ ('dlinklist.h samba_util.h', '.'), ('*', 'util') ], @@ -211,3 +211,8 @@ else: source='util_str_escape.c', deps='talloc', local_include=False) + + bld.SAMBA_SUBSYSTEM('util_str_hex', + source='util_str_hex.c', + deps='talloc', + local_include=False) |