changeset 830:ce155547bca2

First round of uuencode cleanup: generate table, tweak help text, remove unnecessary output buffers, simplify base64 functions..
author Rob Landley <rob@landley.net>
date Sun, 24 Mar 2013 22:35:32 -0500
parents 792d510b8fef
children 4b9b7c9a194f
files toys/pending/uuencode.c
diffstat 1 files changed, 50 insertions(+), 53 deletions(-) [+]
line wrap: on
line diff
--- a/toys/pending/uuencode.c	Sun Mar 24 17:20:47 2013 -0500
+++ b/toys/pending/uuencode.c	Sun Mar 24 22:35:32 2013 -0500
@@ -12,37 +12,29 @@
   help
     usage: uuencode [-m] [file] encode-filename
 
-    Uuencode or (with -m option) base64-encode stdin or [file], 
-    with encode-filename in the output, which is sent to stdout.
+    Uuencode stdin (or file) to stdout, with encode-filename in the output.
+
+    -m	base64-encode
 */
 
 #define FOR_uuencode
 #include "toys.h"
 
-
-
-static void uuencode_b64_3bytes(char *out, const char *in, int bytes)
+// Convert 3 bytes of input to 4 bytes of output
+static void uuencode_b64_3bytes(const char *in, int bytes)
 {
-  static const char *table = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
-                             "abcdefghijklmnopqrstuvwxyz"
-                             "0123456789+/";
-  unsigned int i,x=0;
-  for (i = 0; i < bytes; i++) {
-    x |= (in[i] & 0x0ff) << (8*(2-i));
-  }
-  out[0] = table[(x>>(3*6)) & 0x3f];
-  out[1] = table[(x>>(2*6)) & 0x3f];
-  out[2] = table[(x>>(1*6)) & 0x3f];
-  out[3] = table[(x>>(0*6)) & 0x3f];
-  if (bytes <= 1) out[2] = '=';
-  if (bytes <= 2) out[3] = '=';
+  unsigned int i, x;
+
+  for (i = x = 0; i<4; i++) {
+    if (i < bytes) x |= (in[i] & 0x0ff) << (8*(2-i));
+    xputc(i > bytes ? '=' : toybuf[(x>>((3-i)*6)) & 0x3f]);
+  } 
 }
 
-static void uuencode_b64_line(char *out, const char *in, int len)
+static void uuencode_b64_line(const char *in, int len)
 {
   while (len > 0) {
-    uuencode_b64_3bytes(out,in,len < 3 ? len : 3);
-    xprintf("%c%c%c%c",out[0],out[1],out[2],out[3]);
+    uuencode_b64_3bytes(in, len < 3 ? len : 3);
     in += 3;
     len -= 3;
   };
@@ -52,39 +44,33 @@
 static void uuencode_b64(int fd, const char *name)
 {
   int len;
-  char *inbuf = toybuf;
-  char *outbuf = toybuf+64;
+  char buf[(76/4)*3];
+
   xprintf("begin-base64 744 %s\n",name);
   do {
-    len = xread(fd,inbuf,48);
-    if (len > 0) uuencode_b64_line(outbuf,inbuf,len);
+    len = xread(fd, buf, sizeof(buf));
+    
+    uuencode_b64_line(buf, len);
   } while (len > 0);
   xprintf("====\n");
 }
 
 
-static void uuencode_uu_3bytes(char *out, const char *in)
+static void uuencode_uu_3bytes(const char *in)
 {
-  unsigned int i,x=0;
-  for (i = 0; i <= 2; i++) {
-    x |= (in[i] & 0x0ff) << (8*(2-i));
-  }
-  for (i = 0; i <= 3; i++) {
-    out[i] = 32 + ((x >> (6*(3-i))) & 0x3f);
-  }
+  unsigned int i, x = 0;
+
+  for (i = 0; i <= 2; i++) x |= (in[i] & 0x0ff) << (8*(2-i));
+  for (i = 0; i <= 3; i++) xputc(32 + ((x >> (6*(3-i))) & 0x3f));
 }
 
-static void uuencode_uu_line(char *out, const char *in, int len)
+static void uuencode_uu_line(char *in, int len)
 {
-  int i;
-  if (len == 0) {
-    xprintf("`\n");
-    return;
-  }
-  xprintf("%c",len+32);
-  for (i = 0; i < len; i += 3) {
-    uuencode_uu_3bytes(out,in+i);
-    xprintf("%c%c%c%c",out[0],out[1],out[2],out[3]);
+  if (len > 0) {
+    int i;
+
+    xputc(len+32);
+    for (i = 0; i < len; i += 3) uuencode_uu_3bytes(in+i);
   }
   xprintf("\n");
 }
@@ -92,25 +78,36 @@
 static void uuencode_uu(int fd, const char *name)
 {
   int len;
-  char *inbuf = toybuf;
-  char *outbuf = toybuf+64;
+  char buf[45];
+
   xprintf("begin 744 %s\n",name);
   do {
-    len = xread(fd,inbuf,45);
-    uuencode_uu_line(outbuf,inbuf,len);
+    len = xread(fd, buf, 45);
+    uuencode_uu_line(buf, len);
   } while (len > 0);
   xprintf("end\n");
 }
 
 void uuencode_main(void)
 {
-  char *encode_filename = toys.optargs[0];
-  int fd = 0; /* STDIN */
+  char *p, *name = toys.optargs[0];
+  int i, fd = 0;
+
+  // base64 table
+
+  p = toybuf;
+  for (i = 'A'; i != ':'; i++) {
+    if (i == 'Z'+1) i = 'a';
+    if (i == 'z'+1) i = '0';
+    *(p++) = i;
+  }
+  *(p++) = '+';
+  *(p++) = '/';
 
   if (toys.optc == 2) {
-    fd = xopen(toys.optargs[0],O_RDONLY); // dies if error
-    encode_filename = toys.optargs[1];
+    fd = xopen(toys.optargs[0], O_RDONLY); // dies if error
+    name = toys.optargs[1];
   }
-  if (toys.optflags & FLAG_m) uuencode_b64(fd,encode_filename);
-  else uuencode_uu(fd,encode_filename);
+  if (toys.optflags & FLAG_m) uuencode_b64(fd, name);
+  else uuencode_uu(fd, name);
 }