coreutils

General Software Utilities
git clone http://git.omkov.net/coreutils
Log | Tree | Refs | README | LICENCE | Download

AuthorJamozed <[email protected]>
Date2021-02-22 03:00:20
Commitbb4ca8532d314f3f5d163256cab5dc88a9465eca
Parenta3ab15f487b316c6907b74cfcb8239d4ef2191fd

base64: Use lib/base64 b64encode for encoding

Diffstat

M src/base64.c | 61 ++++++++++++++++++++-----------------------------------------

1 files changed, 20 insertions, 41 deletions

diff --git a/src/base64.c b/src/base64.c
index 4b42fd8..ebc1239 100644
--- a/src/base64.c
+++ b/src/base64.c
@@ -1,4 +1,4 @@
-// base64.c, version 1.0.0
+// base64.c, version 1.0.1
 // OMKOV coreutils base64
 // Copyright (C) 2021, Jakob Wakeling
 // All rights reserved.
@@ -43,7 +43,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE.
 #include <stdint.h>
 #include <stdio.h>
 
-#define VERSION "1.0.0"
+#define VERSION "1.0.1"
 
 static struct lop lops[] = {
 	{ "help",    ARG_NUL, 256 },
@@ -51,14 +51,13 @@ static struct lop lops[] = {
 	{ NULL, 0, 0 }
 };
 
-static const uint8_t B64E[];
-
 static bool dflag;
 
 static inline int base64(const char *file);
 static void encodeBase64(FILE *fi);
 static void decodeBase64(FILE *fi);
 
+static void wwrite(const uint8_t *p, size_t l, size_t c, size_t *cl, FILE *fi);
 static inline size_t fgetb64(uint8_t *buf, size_t len, FILE *fi);
 
 static void hlp(void);
@@ -90,53 +89,36 @@ static inline int base64(const char *file) {
 	if (file == NULL) { fi = stdin; }
 	else if (!(fi = fopen(file, "r"))) { return 1; }
 
-	if (dflag) { decodeBase64(fi); }
-	else { encodeBase64(fi); }
+	if (dflag) { decodeBase64(fi); } else { encodeBase64(fi); }
 
 	if (fi != stdin) { fclose(fi); } return 0;
 }
 
 /* Encode base64 using fixed size buffers */
 static void encodeBase64(FILE *fi) {
-	uint8_t ibuf[BUFSIZ * 6]; int l = 0;
-	uint8_t obuf[BUFSIZ * 8 + (BUFSIZ * 8 / 76)];
-	
-	for (size_t c; (c = fread(ibuf, 1, sizeof (ibuf), fi)) != 0;) {
-		register uint8_t *i = ibuf, *o = obuf;
-		
-		for (; c >= 3; c -= 3) {
-			*o++ = B64E[i[0] >> 2];
-			*o++ = B64E[((i[0] & 0x03) << 4) | (i[1] >> 4)];
-			*o++ = B64E[((i[1] & 0x0F) << 2) | (i[2] >> 6)];
-			*o++ = B64E[i[2] & 0x3F]; i += 3;
-			 
-			l += 4; if (l == 76) { *o++ = '\n'; l = 0; }
-		}
-		
-		if (c) {
-			*o++ = B64E[i[0] >> 2];
-			
-			if (c == 1) {
-				*o++ = B64E[(i[0] & 0x03) << 4]; *o++ = '=';
-			}
-			else {
-				*o++ = B64E[((i[0] & 0x03) << 4) | (i[1] >> 4)];
-				*o++ = B64E[(i[1] & 0x0F) << 2];
-			} *o++ = '='; l += 4;
-		}
-		
-		fwrite(obuf, 1, o - obuf, stdout);
-	}
+	uint8_t ibuf[BUFSIZ * 12]; uint8_t obuf[BUFSIZ * 16]; size_t cl = 0;
 
-	if (l) { fputc('\n', stdout); } return;
+	for (register size_t c; (c = fread(ibuf, 1, sizeof (ibuf), fi));) {
+		c = b64encode(obuf, ibuf, c); wwrite(obuf, c, 76, &cl, stdout);
+	} fputc('\n', stdout); return;
 }
 
 /* Decode base64 using fixed size buffers */
 static void decodeBase64(FILE *fi) {
-	uint8_t ibuf[BUFSIZ * 8]; uint8_t obuf[BUFSIZ * 6];
+	uint8_t ibuf[BUFSIZ * 16]; uint8_t obuf[BUFSIZ * 12];
 
-	for (size_t c; (c = fgetb64(ibuf, sizeof (ibuf), fi)) != 0;) {
+	for (register size_t c; (c = fgetb64(ibuf, sizeof (ibuf), fi));) {
 		c = b64decode(obuf, ibuf, c); fwrite(obuf, 1, c, stdout);
+	} return;
+}
+
+/* Write string with wrapping */
+static void wwrite(const uint8_t *p, size_t l, size_t c, size_t *cl, FILE *fi) {
+	for (size_t w = 0; w < l;) {
+		size_t cr = c - *cl < l - w ? c - *cl : l - w;
+		
+		if (!cr) { fputc('\n', fi); *cl = 0; }
+		else { fwrite(p + w, 1, cr, fi); w += cr; *cl += cr; }
 	}
 }
 
@@ -167,6 +149,3 @@ static void ver(void) {
 	puts("OMKOV Permissive Licence (https://www.omkov.net/OLPE)");
 	return;
 }
-
-static const uint8_t B64E[] =
-	"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";