summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorDouglas Bagnall <douglas.bagnall@catalyst.net.nz>2018-02-16 17:53:15 +1300
committerDouglas Bagnall <dbagnall@samba.org>2018-02-22 01:04:18 +0100
commit6ef6ddce5a64c55729c2e3d423757f504b0ab15e (patch)
treec4196990dd5fd42ee3db23e05d279d888133f6cb /lib
parent33ef0e57a4f08eae5ea06f482374fbc0a1014de6 (diff)
downloadsamba-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.c100
-rw-r--r--lib/util/util_str_hex.h10
-rw-r--r--lib/util/wscript_build7
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)