/*
 *  Copyright (C)  2000-2001 Marc Wandschneider <mw@kiltdown.org>
 *
 *  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 <sanity.h>

#include <stdio.h>
#include <ctype.h>

#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 <mode> <filename>"
 *        !! 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 <mode> <filename>" 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");
}
    


syntax highlighted by Code2HTML, v. 0.9.1