/*
 * Copyright 1995-2001 Sun Microsystems, Inc.  All Rights Reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Sun designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Sun in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.com if you need additional information or
 * have any questions.
 */
package sun.misc;

import java.io.PushbackInputStream;
import java.io.OutputStream;
import java.io.PrintStream;
import java.io.IOException;

/**
 * This class implements a Berkeley uu character decoder. This decoder
 * was made famous by the uudecode program.
 *
 * The basic character coding is algorithmic, taking 6 bits of binary
 * data and adding it to an ASCII ' ' (space) character. This converts
 * these six bits into a printable representation. Note that it depends
 * on the ASCII character encoding standard for english. Groups of three
 * bytes are converted into 4 characters by treating the three bytes
 * a four 6 bit groups, group 1 is byte 1's most significant six bits,
 * group 2 is byte 1's least significant two bits plus byte 2's four
 * most significant bits. etc.
 *
 * In this encoding, the buffer prefix is:
 * <pre>
 *     begin [mode] [filename]
 * </pre>
 *
 * This is followed by one or more lines of the form:
 * <pre>
 *      (len)(data)(data)(data) ...
 * </pre>
 * where (len) is the number of bytes on this line. Note that groupings
 * are always four characters, even if length is not a multiple of three
 * bytes. When less than three characters are encoded, the values of the
 * last remaining bytes is undefined and should be ignored.
 *
 * The last line of data in a uuencoded buffer is represented by a single
 * space character. This is translated by the decoding engine to a line
 * length of zero. This is immediately followed by a line which contains
 * the word 'end[newline]'
 *
 * If an error is encountered during decoding this class throws a
 * CEFormatException. The specific detail messages are:
 *
 * <pre>
 *      "UUDecoder: No begin line."
 *      "UUDecoder: Malformed begin line."
 *      "UUDecoder: Short Buffer."
 *      "UUDecoder: Bad Line Length."
 *      "UUDecoder: Missing 'end' line."
 * </pre>
 *
 * @author      Chuck McManis
 * @see         CharacterDecoder
 * @see         UUEncoder
 */
public class UUDecoder extends CharacterDecoder {

    /**
     * This string contains the name that was in the buffer being decoded.
     */
    public String bufferName;

    /**
     * Represents UNIX(tm) mode bits. Generally three octal digits
     * representing read, write, and execute permission of the owner,
     * group owner, and  others. They should be interpreted as the bit groups:
     * <pre>
     * (owner) (group) (others)
     *  rwx      rwx     rwx    (r = read, w = write, x = execute)
     *</pre>
     *
     */
    public int mode;


    /**
     * UU encoding specifies 3 bytes per atom.
     */
    protected int bytesPerAtom() {
        return (3);
    }

    /**
     * All UU lines have 45 bytes on them, for line length of 15*4+1 or 61
     * characters per line.
     */
    protected int bytesPerLine() {
        return (45);
    }

    /** This is used to decode the atoms */
    private byte decoderBuffer[] = new byte[4];

    /**
     * Decode a UU atom. Note that if l is less than 3 we don't write
     * the extra bits, however the encoder always encodes 4 character
     * groups even when they are not needed.
     */
    protected void decodeAtom(PushbackInputStream inStream, OutputStream outStream, int l)
        throws IOException {
        int i, c1, c2, c3, c4;
        int a, b, c;
        StringBuffer x = new StringBuffer();

        for (i = 0; i < 4; i++) {
            c1 = inStream.read();
            if (c1 == -1) {
                throw new CEStreamExhausted();
            }
            x.append((char)c1);
            decoderBuffer[i] = (byte) ((c1 - ' ') & 0x3f);
        }
        a = ((decoderBuffer[0] << 2) & 0xfc) | ((decoderBuffer[1] >>> 4) & 3);
        b = ((decoderBuffer[1] << 4) & 0xf0) | ((decoderBuffer[2] >>> 2) & 0xf);
        c = ((decoderBuffer[2] << 6) & 0xc0) | (decoderBuffer[3] & 0x3f);
        outStream.write((byte)(a & 0xff));
        if (l > 1) {
            outStream.write((byte)( b & 0xff));
        }
        if (l > 2) {
            outStream.write((byte)(c&0xff));
        }
    }

    /**
     * For uuencoded buffers, the data begins with a line of the form:
     *          begin MODE FILENAME
     * This line always starts in column 1.
     */
    protected void decodeBufferPrefix(PushbackInputStream inStream, OutputStream outStream) throws IOException {
        int     c;
        StringBuffer q = new StringBuffer(32);
        String r;
        boolean sawNewLine;

        /*
         * This works by ripping through the buffer until it finds a 'begin'
         * line or the end of the buffer.
         */
        sawNewLine = true;
        while (true) {
            c = inStream.read();
            if (c == -1) {
                throw new CEFormatException("UUDecoder: No begin line.");
            }
            if ((c == 'b')  && sawNewLine){
                c = inStream.read();
                if (c == 'e') {
                    break;
                }
            }
            sawNewLine = (c == '\n') || (c == '\r');
        }

        /*
         * Now we think its begin, (we've seen ^be) so verify it here.
         */
        while ((c != '\n') && (c != '\r')) {
            c = inStream.read();
            if (c == -1) {
                throw new CEFormatException("UUDecoder: No begin line.");
            }
            if ((c != '\n') && (c != '\r')) {
                q.append((char)c);
            }
        }
        r = q.toString();
        if (r.indexOf(' ') != 3) {
                throw new CEFormatException("UUDecoder: Malformed begin line.");
        }
        mode = Integer.parseInt(r.substring(4,7));
        bufferName = r.substring(r.indexOf(' ',6)+1);
        /*
         * Check for \n after \r
         */
        if (c == '\r') {
            c = inStream.read ();
            if ((c != '\n') && (c != -1))
                inStream.unread (c);
        }
    }

    /**
     * In uuencoded buffers, encoded lines start with a character that
     * represents the number of bytes encoded in this line. The last
     * line of input is always a line that starts with a single space
     * character, which would be a zero length line.
     */
    protected int decodeLinePrefix(PushbackInputStream inStream, OutputStream outStream) throws IOException {
        int     c;

        c = inStream.read();
        if (c == ' ') {
            c = inStream.read(); /* discard the (first)trailing CR or LF  */
            c = inStream.read(); /* check for a second one  */
            if ((c != '\n') && (c != -1))
                inStream.unread (c);
            throw new CEStreamExhausted();
        } else if (c == -1) {
            throw new CEFormatException("UUDecoder: Short Buffer.");
        }

        c = (c - ' ') & 0x3f;
        if (c > bytesPerLine()) {
            throw new CEFormatException("UUDecoder: Bad Line Length.");
        }
        return (c);
    }


    /**
     * Find the end of the line for the next operation.
     * The following sequences are recognized as end-of-line
     * CR, CR LF, or LF
     */
    protected void decodeLineSuffix(PushbackInputStream inStream, OutputStream outStream) throws IOException {
        int c;
        while (true) {
            c = inStream.read();
            if (c == -1) {
                throw new CEStreamExhausted();
            }
            if (c == '\n') {
                break;
            }
            if (c == '\r') {
                c = inStream.read();
                if ((c != '\n') && (c != -1)) {
                    inStream.unread (c);
                }
                break;
            }
        }
    }

    /**
     * UUencoded files have a buffer suffix which consists of the word
     * end. This line should immediately follow the line with a single
     * space in it.
     */
    protected void decodeBufferSuffix(PushbackInputStream inStream, OutputStream outStream) throws IOException  {
        int     c;

        c = inStream.read(decoderBuffer);
        if ((decoderBuffer[0] != 'e') || (decoderBuffer[1] != 'n') ||
            (decoderBuffer[2] != 'd')) {
            throw new CEFormatException("UUDecoder: Missing 'end' line.");
        }
    }

}
