---
include/osmocom/core/utils.h | 2 ++
src/utils.c | 48 ++++++++++++++++++++++++++++++++++++------
2 files changed, 44 insertions(+), 6 deletions(-)
diff --git a/include/osmocom/core/utils.h b/include/osmocom/core/utils.h
index 03861d7..05cb2a4 100644
--- a/include/osmocom/core/utils.h
+++ b/include/osmocom/core/utils.h
@@ -15,6 +15,7 @@
#define OSMO_MIN(a, b) ((a) >= (b) ? (b) : (a))
#include <stdint.h>
+#include <stdbool.h>
/*! \brief A mapping between human-readable string and numeric value */
struct value_string {
@@ -30,6 +31,7 @@ char osmo_bcd2char(uint8_t bcd);
/* only works for numbers in ascci */
uint8_t osmo_char2bcd(char c);
+int osmo_hexparse_adv(const char *str, uint8_t *b, int max_len, bool allow_odd);
int osmo_hexparse(const char *str, uint8_t *b, int max_len);
char *osmo_ubit_dump(const uint8_t *bits, unsigned int len);
diff --git a/src/utils.c b/src/utils.c
index c36979c..8c1849e 100644
--- a/src/utils.c
+++ b/src/utils.c
@@ -3,7 +3,7 @@
#include <stdint.h>
#include <errno.h>
#include <stdio.h>
-
+#include <stdbool.h>
#include <osmocom/core/utils.h>
/*! \addtogroup utils
@@ -73,24 +73,60 @@ uint8_t osmo_char2bcd(char c)
return c - 0x30;
}
-/*! \brief Parse a string ocntaining hexadecimal digits
+/*! \brief Parse a string ocntaining hexadecimal digits, optionally prefixed with 0x
* \param[in] str string containing ASCII encoded hexadecimal digits
* \param[out] b output buffer
* \param[in] max_len maximum space in output buffer
*/
int osmo_hexparse(const char *str, uint8_t *b, int max_len)
+{
+ return osmo_hexparse_adv(str, b, max_len, false);
+}
+/*! \brief Parse a string ocntaining hexadecimal digits, optionally prefixed with 0x
+ * \param[in] str string containing ASCII encoded hexadecimal digits
+ * \param[out] b output buffer
+ * \param[in] max_len maximum space in output buffer
+ * \param[in] allow_odd allow odd length (prefix with 0 on the left side)
+ */
+int osmo_hexparse_adv(const char *str, uint8_t *b, int max_len, bool allow_odd)
{
- int i, l, v;
+ int v;
+ size_t i, l = strlen(str);
+ const char * src;
+
+ if (l > 2) { /* remove 0x prefix if any */
+ if ('0' == str[0] && 'x' == str[1]) {
+ l -= 2;
+ str += 2;
+ }
+ }
+
+ if (allow_odd) {
+ if (l & 1) i = l + 1;
+ else i = l;
+ char hs[i]; /* enough space to store additional leading 0 if str length is odd */
+
+ if (l & 1) {
+ memcpy(hs + 1, str, l);
+ hs[0] = '0';
+ } else {
+ memcpy(hs, str, l);
+ }
+ src = hs;
+ } else {
+ if (l & 1)
+ return -1;
+ src = str;
+ }
- l = strlen(str);
- if ((l&1) || ((l>>1) > max_len))
+ if ((l>>1) > max_len)
return -1;
memset(b, 0x00, max_len);
for (i=0; i<l; i++) {
- char c = str[i];
+ char c = src[i];
if (c >= '0' && c <= '9')
v = c - '0';
else if (c >= 'a' && c <= 'f')
--
1.7.10.4
--------------070900070504060905060402--
Show replies by date