Move hb_codepoint_parse to hb_parse_uint
diff --git a/src/hb-algs.hh b/src/hb-algs.hh
index 6b74a25..96cc157 100644
--- a/src/hb-algs.hh
+++ b/src/hb-algs.hh
@@ -32,6 +32,7 @@
 #include "hb.hh"
 #include "hb-meta.hh"
 #include "hb-null.hh"
+#include "hb-number.hh"
 
 
 /* Encodes three unsigned integers in one 64-bit number.  If the inputs have more than 21 bits,
@@ -896,17 +897,14 @@
 static inline hb_bool_t
 hb_codepoint_parse (const char *s, unsigned int len, int base, hb_codepoint_t *out)
 {
-  /* Pain because we don't know whether s is nul-terminated. */
-  char buf[64];
-  len = hb_min (ARRAY_LENGTH (buf) - 1, len);
-  strncpy (buf, s, len);
-  buf[len] = '\0';
+  unsigned int v;
+  const char *p = s;
+  const char *end = p + len;
+  if (!hb_parse_uint (&p, p + len, &v, base))
+    return false;
 
-  char *end;
-  errno = 0;
-  unsigned long v = strtoul (buf, &end, base);
-  if (errno) return false;
-  if (*end) return false;
+  if (end != p && *p) return false;
+
   *out = v;
   return true;
 }
diff --git a/src/hb-buffer-serialize.cc b/src/hb-buffer-serialize.cc
index 518004b..a6e3bb8 100644
--- a/src/hb-buffer-serialize.cc
+++ b/src/hb-buffer-serialize.cc
@@ -25,7 +25,6 @@
  */
 
 #include "hb.hh"
-#include "hb-number.hh"
 
 #ifndef HB_NO_BUFFER_SERIALIZE
 
diff --git a/src/hb-common.cc b/src/hb-common.cc
index f5c18ec..690c96f 100644
--- a/src/hb-common.cc
+++ b/src/hb-common.cc
@@ -28,7 +28,6 @@
 
 #include "hb.hh"
 #include "hb-machinery.hh"
-#include "hb-number.hh"
 
 #include <locale.h>
 #ifdef HAVE_XLOCALE_H
diff --git a/src/hb-number.cc b/src/hb-number.cc
index d8291d9..2a35ba1 100644
--- a/src/hb-number.cc
+++ b/src/hb-number.cc
@@ -25,7 +25,6 @@
 
 #include "hb.hh"
 #include "hb-machinery.hh"
-#include "hb-number.hh"
 
 #include <locale.h>
 #ifdef HAVE_XLOCALE_H
@@ -46,14 +45,35 @@
 
   errno = 0;
   v = strtol (p, &pend, 10);
-  if (errno || p == pend)
-    return false;
+  if (unlikely (errno || p == pend)) return false;
 
   *pv = v;
   *pp += pend - p;
   return true;
 }
 
+bool
+hb_parse_uint (const char **pp, const char *end, unsigned int *pv, int base)
+{
+  char buf[32];
+  unsigned int len = hb_min (ARRAY_LENGTH (buf) - 1, (unsigned int) (end - *pp));
+  strncpy (buf, *pp, len);
+  buf[len] = '\0';
+
+  char *p = buf;
+  char *pend = p;
+  int v;
+
+  errno = 0;
+  v = strtol (p, &pend, 10);
+  if (unlikely (errno || p == pend)) return false;
+
+  *pv = v;
+  *pp += pend - p;
+  return true;
+}
+
+
 #if defined (HAVE_NEWLOCALE) && defined (HAVE_STRTOD_L)
 #define USE_XLOCALE 1
 #define HB_LOCALE_T locale_t
diff --git a/src/hb-number.hh b/src/hb-number.hh
index 54679a7..41a1d7d 100644
--- a/src/hb-number.hh
+++ b/src/hb-number.hh
@@ -30,6 +30,9 @@
 hb_parse_int (const char **pp, const char *end, int *pv);
 
 HB_INTERNAL bool
+hb_parse_uint (const char **pp, const char *end, unsigned int *pv, int base=10);
+
+HB_INTERNAL bool
 hb_parse_float (const char **pp, const char *end, float *pv);
 
 #endif /* HB_NUMBER_HH */
diff --git a/src/hb.hh b/src/hb.hh
index 3a824fd..f094287 100644
--- a/src/hb.hh
+++ b/src/hb.hh
@@ -594,9 +594,10 @@
  * them directly.*/
 #include "hb-meta.hh"
 #include "hb-mutex.hh"
+#include "hb-number.hh"
 #include "hb-atomic.hh"	// Requires: hb-meta
 #include "hb-null.hh"	// Requires: hb-meta
-#include "hb-algs.hh"	// Requires: hb-meta hb-null
+#include "hb-algs.hh"	// Requires: hb-meta hb-null hb-number
 #include "hb-iter.hh"	// Requires: hb-algs hb-meta
 #include "hb-debug.hh"	// Requires: hb-algs hb-atomic
 #include "hb-array.hh"	// Requires: hb-algs hb-iter hb-null