[coreboot-gerrit] Change in coreboot[master]: src/include/hexutil.h: Add converters for working with hex strings

Raul Rangel (Code Review) gerrit at coreboot.org
Wed Mar 28 18:16:41 CEST 2018


Raul Rangel has uploaded this change for review. ( https://review.coreboot.org/25411


Change subject: src/include/hexutil.h: Add converters for working with hex strings
......................................................................

src/include/hexutil.h: Add converters for working with hex strings

These utilities will be used as part of fixing SMBIOS generation for
soc/amd.

I have a bunch of unit tests for these functions outside of this commit. Is
there somewhere I can commit them?

BUG=b:65403853
TEST=tested on grunt

Change-Id: Ifcabf09be4dc053f8b6e132b4014380cdb5c521b
Signed-off-by: Raul E Rangel <rrangel at chromium.org>
---
A src/include/hexutil.h
M src/lib/Makefile.inc
A src/lib/hexutil.c
3 files changed, 137 insertions(+), 0 deletions(-)



  git pull ssh://review.coreboot.org:29418/coreboot refs/changes/11/25411/1

diff --git a/src/include/hexutil.h b/src/include/hexutil.h
new file mode 100644
index 0000000..847d39c
--- /dev/null
+++ b/src/include/hexutil.h
@@ -0,0 +1,55 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2018 Google LLC.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef HEXUTIL_H
+#define HEXUTIL_H
+
+#include <stddef.h>
+#include <stdint.h>
+
+/**
+ * Decodes a hex character [0-9A-Za-z] into a byte.
+ *
+ * Invalid characters are mapped to 0.
+ * */
+uint8_t decode_hex_character(char hex);
+
+/**
+ * Decodes a hex string into a byte array.
+ *
+ * Examples:
+ *  * "01AF" => {0x01, 0xAF}
+ *  * "1AF" => {0x01, 0xAF}
+ *  * "1AF" => {0x00, 0x00, 0x01, 0xAF} w/ 4 byte dest buffer.
+ *
+ * @param src_size size of the src buffer
+ * @param dest_size must be at least (strlen(src) + 1) / 2 in size. If the
+ * buffer is bigger than required the most significant bytes are cleared.
+ */
+void decode_hex_string(const char *src, size_t src_size, uint8_t *dest,
+		       size_t dest_size);
+
+/**
+ * Encodes a byte array into a hex string.
+ *
+ * e.g., {0x01, 0x02} => "0102"
+ *
+ * @param dest_size must be at least (src_size * 2 + 1). If it is smaller, the
+ * least significant bytes will be truncated.
+ * @return number of characters written excluding the null terminator.
+ */
+size_t encode_as_hex_string(const uint8_t *src, size_t src_size, char *dest,
+			  size_t dest_size);
+#endif
diff --git a/src/lib/Makefile.inc b/src/lib/Makefile.inc
index 960b5cb..3ae77a6 100644
--- a/src/lib/Makefile.inc
+++ b/src/lib/Makefile.inc
@@ -133,6 +133,7 @@
 ramstage-$(CONFIG_GENERIC_GPIO_LIB) += gpio.c
 ramstage-$(CONFIG_GENERIC_UDELAY) += timer.c
 ramstage-y += b64_decode.c
+ramstage-y += hexutil.c
 ramstage-$(CONFIG_ACPI_NHLT) += nhlt.c
 
 romstage-y += cbmem_common.c
diff --git a/src/lib/hexutil.c b/src/lib/hexutil.c
new file mode 100644
index 0000000..a41a94a
--- /dev/null
+++ b/src/lib/hexutil.c
@@ -0,0 +1,81 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2018 Google LLC.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <hexutil.h>
+#include <string.h>
+
+uint8_t decode_hex_character(char hex)
+{
+	if (isdigit(hex))
+		return hex - '0';
+	else if (isxdigit(hex) && isupper(hex))
+		return hex - 'A' + 10;
+	else if (isxdigit(hex) && islower(hex))
+		return hex - 'a' + 10;
+	else
+		return 0;
+}
+
+void decode_hex_string(const char *src, size_t src_size, uint8_t *dest,
+		       size_t dest_size)
+{
+	const size_t src_len = strnlen(src, src_size);
+
+	for (size_t dest_idx = 0; dest_idx < dest_size; ++dest_idx) {
+		int src_idx = (src_len - 1) - dest_idx * 2;
+
+		uint8_t byte = 0;
+
+		if (src_idx >= 0) {
+			char low = src[src_idx];
+			byte |= decode_hex_character(low);
+		}
+
+		if (src_idx >= 1) {
+			char high = src[src_idx - 1];
+			byte |= decode_hex_character(high) << 4;
+		}
+
+		dest[(dest_size - 1) - dest_idx] = byte;
+	}
+}
+
+size_t encode_as_hex_string(const uint8_t *src, size_t src_size, char *dest,
+			  size_t dest_size)
+{
+	size_t cnt = 0;
+
+	if (src_size == 0 && dest_size > 0)
+		dest[0] = '\0';
+
+	for (size_t src_idx = 0; src_idx < src_size; ++src_idx) {
+		size_t dest_offset = src_idx * 2;
+
+		if (dest_offset + 3 <= dest_size) {
+			snprintf(dest + dest_offset, 3, "%02hhx", src[src_idx]);
+			cnt += 2;
+		} else if (dest_offset + 2 <= dest_size) {
+			snprintf(dest + dest_offset, 2, "%hhx",
+				 src[src_idx] >> 4);
+			cnt += 1;
+		} else if (dest_offset < dest_size) {
+			dest[dest_offset] = '\0';
+
+			break;
+		}
+	}
+
+	return cnt;
+}

-- 
To view, visit https://review.coreboot.org/25411
To unsubscribe, or for help writing mail filters, visit https://review.coreboot.org/settings

Gerrit-Project: coreboot
Gerrit-Branch: master
Gerrit-MessageType: newchange
Gerrit-Change-Id: Ifcabf09be4dc053f8b6e132b4014380cdb5c521b
Gerrit-Change-Number: 25411
Gerrit-PatchSet: 1
Gerrit-Owner: Raul Rangel <rrangel at chromium.org>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.coreboot.org/pipermail/coreboot-gerrit/attachments/20180328/d780abad/attachment-0001.html>


More information about the coreboot-gerrit mailing list