All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jakob Kemi <jakob.kemi@telia.com>
To: Linus Torvalds <torvalds@transmeta.com>
Cc: <linux-kernel@vger.kernel.org>
Subject: Re: [PATCH] hex <-> int conve
Date: Tue, 19 Feb 2002 19:47:40 +0100	[thread overview]
Message-ID: <02021919474003.00447@jakob> (raw)

On Tuesday 19 February 2002 19.02, Linus Torvalds wrote:
> On Tue, 19 Feb 2002, Jakob Kemi wrote:
> > I also added three other hex-functions that can replace a lot of
> > duplicated code.
> >
> > int  hexint_nibble (char x);		// hex digit to int.
> > int  hexint_byte   (const char *src);	// hex digit-pair to int.
> > char inthex_nibble (int x);		// int to hex digit.
> > void inthex_byte   (int x, char* dest);	// int to hex digit pair.
>
> Is there any reason to do all of this?
>
> I suspect 99% of all users can (and probably should) be replaced with
> "sscanf()" instead. Which does a lot more, of course, and is not the
> fastest thing out there due to that, but anybody who does hex->int
> conversion inside some critical loop is just crazy.

We needed the code when parsing non-null terminated UUID strings in the LDM
partition database (Dynamic Disks). And sscanf wouldn't work for us. Consider:

char a[3] = {'a','b'};
char b[3] = {'a','-'};
int x;
sscanf(a, "%x", &x);  // undefined, could crash since a isn't null-terminated

is probably solved by specifying width, but then consider:

sscanf(b, "%2x", &x); // would happily return 1 and fill x with 10

hexint_byte() would detect the error however.

Due to the amount of UUID's we have to parse the speed difference when using
sscanf() would also be noticeable. I suspect others have different reasons for
implementing their own hex->int functions.

Regards,
	Jakob Kemi

(Included is a smaller patch with less inlining.)


diff -urN -X dontdiff linux-2.5.5-pre1-vanilla/include/linux/hexint.h linux-2.5.5-pre1/include/linux/hexint.h
--- linux-2.5.5-pre1-vanilla/include/linux/hexint.h	Thu Jan  1 01:00:00 1970
+++ linux-2.5.5-pre1/include/linux/hexint.h	Tue Feb 19 19:14:35 2002
@@ -0,0 +1,66 @@
+/*
+ *  include/linux/hexint.h - hex<->int conversions.
+ *
+ *  Copyleft (C) 2002, Jakob Kemi <jakob.kemi@telia.com>
+ */
+
+#ifndef _LINUX_HEXINT_H
+#define _LINUX_HEXINT_H
+
+#ifdef __KERNEL__
+
+/**
+ * hexint_nibble - Convert a hex digit to an int.
+ * @x: digit to convert.
+ *
+ * Return:
+ *     converted value (0-15) on success.
+ *     -1 on failure.
+ */
+extern int hexint_nibble(char x);
+
+/**
+ * __hexint_nibble - Inlined version of hexint_nibble without error-checking.
+ */
+static __inline__ int __hexint_nibble(char x)
+{
+	const unsigned int y = x - '0';
+
+	if (y <= 9) return y;
+	return (y - 7) & 0x5f;
+}
+
+/**
+ * hexint_byte - Convert a hex digit pair to an int.
+ * @src: Pointer to source data.
+ *
+ * Return:
+ *     converted value (0-255) on success.
+ *     -1 on failure.
+ */
+extern int hexint_byte(const char *src);
+
+/**
+ * inthex_nibble - Convert an int to a hex digit.
+ */
+static __inline__ char inthex_nibble(int x)
+{
+	const char* digits = "0123456789abcdef";
+
+	return digits[x & 0x0f];
+}
+
+/**
+ * inthex_byte - Convert an int to a hex digit pair.
+ */
+static __inline__ void inthex_byte(int x, char* dest)
+{
+	const char* digits = "0123456789abcdef";
+
+	dest[0] = digits[(x & 0xf0) >> 4];
+	dest[1] = digits[x & 0x0f];
+}
+
+#endif /* __KERNEL__ */
+
+#endif
diff -urN -X dontdiff linux-2.5.5-pre1-vanilla/lib/Makefile linux-2.5.5-pre1/lib/Makefile
--- linux-2.5.5-pre1-vanilla/lib/Makefile	Sun Feb  3 14:04:47 2002
+++ linux-2.5.5-pre1/lib/Makefile	Tue Feb 19 15:55:37 2002
@@ -10,7 +10,7 @@
 
 export-objs := cmdline.o dec_and_lock.o rwsem-spinlock.o rwsem.o crc32.o
 
-obj-y := errno.o ctype.o string.o vsprintf.o brlock.o cmdline.o bust_spinlocks.o rbtree.o
+obj-y := errno.o ctype.o string.o vsprintf.o brlock.o cmdline.o bust_spinlocks.o rbtree.o hexint.o
 
 obj-$(CONFIG_RWSEM_GENERIC_SPINLOCK) += rwsem-spinlock.o
 obj-$(CONFIG_RWSEM_XCHGADD_ALGORITHM) += rwsem.o
diff -urN -X dontdiff linux-2.5.5-pre1-vanilla/lib/hexint.c linux-2.5.5-pre1/lib/hexint.c
--- linux-2.5.5-pre1-vanilla/lib/hexint.c	Thu Jan  1 01:00:00 1970
+++ linux-2.5.5-pre1/lib/hexint.c	Tue Feb 19 19:12:37 2002
@@ -0,0 +1,50 @@
+/*
+ *  linux/lib/hexint.c - hex<->int conversions.
+ *
+ *  Copyleft (C) 2002, Jakob Kemi <jakob.kemi@telia.com>
+ */
+
+/**
+ * hexint_nibble - Convert a hex digit to an int.
+ * @x: digit to convert.
+ *
+ * Return:
+ *     converted value (0-15) on success.
+ *     -1 on failure.
+ */
+int hexint_nibble(char x)
+{
+	unsigned int y;		/* unsigned for correct wrapping */
+
+	if ((y = x - '0') <= '9'-'0') return y;
+	if ((y = x - 'a') <= 'f'-'a') return y+10;
+	if ((y = x - 'A') <= 'F'-'A') return y+10;
+	return -1;
+}
+
+/**
+ * hexint_byte - Convert an hex digit pair to an int.
+ * @src: Pointer to source data.
+ *
+ * Return:
+ *     converted value (0-255) on success.
+ *     -1 on failure.
+ */
+int hexint_byte(const char *src)
+{
+	unsigned int y; /* unsigned for correct wrapping. */
+	int h;
+
+	/* high part. */
+	if      ((y = src[0] - '0') <= '9'-'0') h = y;
+	else if ((y = src[0] - 'a') <= 'f'-'a') h = y+10;
+	else if ((y = src[0] - 'A') <= 'F'-'A') h = y+10;
+	else return -1;
+	h <<= 4;
+
+	/* low part. */
+	if ((y = src[1] - '0') <= '9'-'0') return h | y;
+	if ((y = src[1] - 'a') <= 'f'-'a') return h | (y+10);
+	if ((y = src[1] - 'A') <= 'F'-'A') return h | (y+10);
+	return -1;
+}


             reply	other threads:[~2002-02-19 18:49 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2002-02-19 18:47 Jakob Kemi [this message]
2002-02-19 19:56 ` [PATCH] hex <-> int conve Andreas Dilger
2002-02-20  0:12   ` Jakob Kemi
2002-02-20  0:37     ` Alexander Viro

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=02021919474003.00447@jakob \
    --to=jakob.kemi@telia.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=torvalds@transmeta.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.