#include <hallo.h> * Manoj Srivastava [Wed, Aug 24 2005, 06:22:01PM]: > be getting about 11MB/s, which should be enough for the use case > mime-codecs was designed for. > > If you feel that we need faster tools, perhaps mime-codecs can > be split out from VM and reimplemented in Perl.
Such comment is pointless and the performance did suck simply because of not doing any buffering at all. The patch (attached) solves the problem. If you can wait a bit, I will add buffering to -decode tool too. Eduard. -- Ambassador Londo Mollari: Physics tells us that for every action, there is an equal and opposite reaction. They hate us, we hate them, they hate us back. And so, here we are, victims of mathematics! -- Quotes from Babylon 5 --
--- vm-7.19.orig/base64-encode.c +++ vm-7.19/base64-encode.c @@ -7,6 +7,9 @@ */ #include <stdio.h> +#include <stdint.h> +#include <string.h> +#include <unistd.h> #ifdef _WIN32 #ifndef WIN32 @@ -20,56 +23,69 @@ #endif unsigned char alphabet[64] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; +#define BUFLEN 54*500 // multiple of 54 (a text line) fits best int main() { - int cols, bits, c, char_count; - #ifdef WIN32 _setmode( _fileno(stdin), _O_BINARY); #endif - char_count = 0; - bits = 0; - cols = 0; - while ((c = getchar()) != EOF) { - if (c > 255) { - fprintf(stderr, "encountered char > 255 (decimal %d)", c); - exit(1); - } - bits += c; - char_count++; - if (char_count == 3) { - putchar(alphabet[bits >> 18]); - putchar(alphabet[(bits >> 12) & 0x3f]); - putchar(alphabet[(bits >> 6) & 0x3f]); - putchar(alphabet[bits & 0x3f]); - cols += 4; - if (cols == 72) { - putchar('\n'); - cols = 0; - } - bits = 0; - char_count = 0; - } else { - bits <<= 8; - } - } - if (char_count != 0) { - bits <<= 16 - (8 * char_count); - putchar(alphabet[bits >> 18]); - putchar(alphabet[(bits >> 12) & 0x3f]); - if (char_count == 1) { - putchar('='); - putchar('='); - } else { - putchar(alphabet[(bits >> 6) & 0x3f]); - putchar('='); - } - if (cols > 0) - putchar('\n'); - } + char buf[BUFLEN]; + char outbuf[4*BUFLEN]; // enough even for the case somebody is cheating, inserting single bytes + int len; + while(!feof(stdin)) { + int cols, bits, char_count; + unsigned char c; + + char_count = 0; + bits = 0; + cols = 0; + + char *out=outbuf; + int pos=0, gap=0; + len=fread(buf, sizeof(char), BUFLEN, stdin); + if(!len) continue; + + for(;pos<len;pos++) { + c=buf[pos]; + bits += c; + char_count++; + if (char_count == 3) { + *out++ = (alphabet[bits >> 18]); + *out++ = (alphabet[(bits >> 12) & 0x3f]); + *out++ = (alphabet[(bits >> 6) & 0x3f]); + *out++ = (alphabet[bits & 0x3f]); + cols += 4; + if (cols == 72) { + *out++ = '\n'; + cols = 0; + } + bits = 0; + char_count = 0; + } else { + bits <<= 8; + } + } + // handle the incomplete chunk + if (char_count != 0) { + bits <<= 16 - (8 * char_count); + *out++ = (alphabet[bits >> 18]); + *out++ = (alphabet[(bits >> 12) & 0x3f]); + if (char_count == 1) { + *out++ = '='; + *out++ = '='; + } else { + *out++ = (alphabet[(bits >> 6) & 0x3f]); + *out++ = '='; + } + } + if (cols > 0) + *out++ = '\n'; + int outlen=(out-outbuf); + fwrite(outbuf, sizeof(char), outlen, stdout); + } - exit(0); + return 0; }