/* * Copyright (C) 2000-2001 Marc Wandschneider * * 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. * * For more information look at the file COPYRIGHT in this package * */ /** *=-------------------------------------------------------------------------= * uuencode.cc *=-------------------------------------------------------------------------= * This file contains routines to encode and decode character/byte streams * using the UUencoding/decoding specifications. Note that this spec- * ification is pretty loosely defined, and as such, there might be problems * on various different machines. We will try to use the version that works * with the most data. * * Author: Marc Wandschneider (mw@lanfear.com) * Version: 0.01 -- 2/17/2000 */ #include #include #include #define MAX_LINE_SIZE 1024 #define ENCODE_CHAR(c) ((c) ? (((c) & 0x3f) + 0x20) : '`') /** *=-------------------------------------------------------------------------= * uuDecode *=-------------------------------------------------------------------------= * take then given character stream and reconstruct the file for it using * the loosely defined UUencoding mechanism * * Parameters: * ICharReadStream * - [in] character stream to read from * IByteWriteStream * - [in] byte stream to write to * * Output: * int - 0 -- success!! * 1 -- failed, but wrote something out * -1 -- downright failed * * Notes: * !! We assume that the caller has searched for the header line: * "begin " * !! We will look for the "end" as part of our processing. */ int uuDecode ( ICharReadStream *readStream, IByteWriteStream *writeStream ) { } /** *=-------------------------------------------------------------------------= * uuEncode *=-------------------------------------------------------------------------= * take the given BYTE stream and encode the data using the vaguely and * loosely defined UUENCODEing scheme. We are basing our version off that * found in the BSD UNIX variants. It seems to work with all the data we've * tried so far ... * * Parameters: * IByteReadStream - [in] byte stream to encode * ICharWriteStream - [in] character stream to write to * * Output: * BOOL - TRUE means success * * Notes: * This routine assumes that the "begin " portion of * the output has been written by the caller, in light of the fact that * we are given a stream supposedly already representing a file! */ BOOL uuEncode ( IByteReadStream *readStream, ICharWriteStream *writeStream ) { BYTE byteBuf[45]; int cread, count, result; char charBuf[62]; // 1 char for count, 60 for data, 1 for '0' char *p, holdChar; /** * arg checking */ if (!readStream || !writeStream) return FALSE; while ((cread = readStream->readData(sizeof(byteBuf), byteBuf)) != -1) { if (cread == 0) break; /** * first write out the number of characters on this line */ p = charBuf; *(p++) = cread + 0x20; /** * next, convert the data and write it out. * the variable 'count' tracks position in the BYTE buf * the variable 'x' tracks position in the char buf. */ for (count = 0; count < cread; count += 3) { switch (cread - count) { /** * can write out a full three bytes */ default: holdChar = ((byteBuf[count] >> 2) & 0x3f); *(p++) = ENCODE_CHAR(holdChar); holdChar = (((byteBuf[count] << 4) | ((byteBuf[count + 1] >> 4) & 0xf)) & 0x3f); *(p++) = ENCODE_CHAR(holdChar); holdChar = (((byteBuf[count + 1] << 2) | ((byteBuf[count + 2] >> 6) & 0x3)) & 0x3f); *(p++) = ENCODE_CHAR(holdChar); holdChar = (byteBuf[count + 2] & 0x3f); *(p++) = ENCODE_CHAR(holdChar); break; case 2: holdChar = ((byteBuf[count] >> 2) & 0x3f); *(p++) = ENCODE_CHAR(holdChar); holdChar = (((byteBuf[count] << 4) | ((byteBuf[count + 1] >> 4) & 0xf)) & 0x3f); *(p++) = ENCODE_CHAR(holdChar); holdChar = (((byteBuf[count + 1] << 2) | ((byteBuf[count + 2] >> 6) & 0x3)) & 0x3f); *(p++) = ENCODE_CHAR(holdChar); break; case 1: holdChar = ((byteBuf[count] >> 2) & 0x3f); *(p++) = ENCODE_CHAR(holdChar); holdChar = (((byteBuf[count] << 4) | ((byteBuf[count + 1] >> 4) & 0xf)) & 0x3f); *(p++) = ENCODE_CHAR(holdChar); break; } } *(p) = '\0'; /** * now write out the appropriate number of characters */ result = writeStream->writeLine(charBuf); if (!result) return FALSE; } /** * finally, write out the empty line marker and "end" */ result = writeStream->writeLine("`"); if (!result) return FALSE; return writeStream->writeLine("end"); }