]> www.infradead.org Git - users/sagi/libnvme.git/commitdiff
libnvme: Add base64 functions
authorHannes Reinecke <hare@suse.de>
Thu, 16 Nov 2023 06:28:56 +0000 (07:28 +0100)
committerHannes Reinecke <hare@suse.de>
Fri, 17 Nov 2023 07:32:36 +0000 (08:32 +0100)
Copied over from nvme-cli.

Signed-off-by: Hannes Reinecke <hare@suse.de>
src/meson.build
src/nvme/base64.c [new file with mode: 0644]
src/nvme/base64.h [new file with mode: 0644]

index e8b667c23ea804b08e3adae7632e20ea6d17e2d5..92e39d44e57f20d02e6d6d4c6a52851743c4b895 100644 (file)
@@ -15,6 +15,7 @@ sources = [
     'nvme/log.c',
     'nvme/tree.c',
     'nvme/util.c',
+    'nvme/base64.c'
 ]
 
 mi_sources = [
diff --git a/src/nvme/base64.c b/src/nvme/base64.c
new file mode 100644 (file)
index 0000000..5fae829
--- /dev/null
@@ -0,0 +1,94 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * base64.c - RFC4648-compliant base64 encoding
+ *
+ * Copyright (c) 2020 SUSE LLC
+ *
+ * Author: Hannes Reinecke <hare@suse.de>
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/types.h>
+
+static const char base64_table[65] =
+       "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+
+/**
+ * base64_encode() - base64-encode some bytes
+ * @src: the bytes to encode
+ * @srclen: number of bytes to encode
+ * @dst: (output) the base64-encoded string.  Not NUL-terminated.
+ *
+ * Encodes the input string using characters from the set [A-Za-z0-9+,].
+ * The encoded string is roughly 4/3 times the size of the input string.
+ *
+ * Return: length of the encoded string
+ */
+int base64_encode(const unsigned char *src, int srclen, char *dst)
+{
+       int i, bits = 0;
+       u_int32_t ac = 0;
+       char *cp = dst;
+
+       for (i = 0; i < srclen; i++) {
+               ac = (ac << 8) | src[i];
+               bits += 8;
+               do {
+                       bits -= 6;
+                       *cp++ = base64_table[(ac >> bits) & 0x3f];
+               } while (bits >= 6);
+       }
+       if (bits) {
+               *cp++ = base64_table[(ac << (6 - bits)) & 0x3f];
+               bits -= 6;
+       }
+       while (bits < 0) {
+               *cp++ = '=';
+               bits += 2;
+       }
+
+       return cp - dst;
+}
+
+/**
+ * base64_decode() - base64-decode some bytes
+ * @src: the base64-encoded string to decode
+ * @len: number of bytes to decode
+ * @dst: (output) the decoded bytes.
+ *
+ * Decodes the base64-encoded bytes @src according to RFC 4648.
+ *
+ * Return: number of decoded bytes
+ */
+int base64_decode(const char *src, int srclen, unsigned char *dst)
+{
+       u_int32_t ac = 0;
+       int i, bits = 0;
+       unsigned char *bp = dst;
+
+       for (i = 0; i < srclen; i++) {
+               const char *p = strchr(base64_table, src[i]);
+
+               if (src[i] == '=') {
+                       ac = (ac << 6);
+                       bits += 6;
+                       if (bits >= 8)
+                               bits -= 8;
+                       continue;
+               }
+               if (!p || !src[i])
+                       return -EINVAL;
+               ac = (ac << 6) | (p - base64_table);
+               bits += 6;
+               if (bits >= 8) {
+                       bits -= 8;
+                       *bp++ = (unsigned char)(ac >> bits);
+               }
+       }
+       if (ac && ((1 << bits) - 1))
+               return -EAGAIN;
+
+       return bp - dst;
+}
diff --git a/src/nvme/base64.h b/src/nvme/base64.h
new file mode 100644 (file)
index 0000000..c0f62e2
--- /dev/null
@@ -0,0 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+#ifndef _BASE64_H
+#define _BASE64_H
+
+int base64_encode(const unsigned char *src, int len, char *dst);
+int base64_decode(const char *src, int len, unsigned char *dst);
+
+#endif /* _BASE64_H */