home *** CD-ROM | disk | FTP | other *** search
/ CD Actual 25 / CDROM25.iso / Share / prog / VJ11 / VJTRIAL.EXE / IE30Java.exe / classd.exe / sun / misc / CharacterDecoder.java < prev    next >
Encoding:
Java Source  |  1997-01-27  |  7.0 KB  |  199 lines

  1. /*
  2.  * @(#)CharacterDecoder.java    1.9 95/10/08 Chuck McManis
  3.  *
  4.  * Copyright (c) 1994 Sun Microsystems, Inc. All Rights Reserved.
  5.  *
  6.  * Permission to use, copy, modify, and distribute this software
  7.  * and its documentation for NON-COMMERCIAL purposes and without
  8.  * fee is hereby granted provided that this copyright notice
  9.  * appears in all copies. Please refer to the file "copyright.html"
  10.  * for further important copyright and licensing information.
  11.  *
  12.  * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF
  13.  * THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
  14.  * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
  15.  * PARTICULAR PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR
  16.  * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
  17.  * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.
  18.  */
  19.  
  20. package sun.misc;
  21.  
  22. import java.io.OutputStream;
  23. import java.io.ByteArrayOutputStream;
  24. import java.io.InputStream;
  25. import java.io.ByteArrayInputStream;
  26. import java.io.IOException;
  27.  
  28. /**
  29.  * This class defines the decoding half of character encoders.
  30.  * A character decoder is an algorithim for transforming 8 bit
  31.  * binary data that has been encoded into text by a character
  32.  * encoder, back into original binary form.
  33.  * 
  34.  * The character encoders, in general, have been structured 
  35.  * around a central theme that binary data can be encoded into
  36.  * text that has the form:
  37.  *
  38.  * <pre>
  39.  *    [Buffer Prefix]
  40.  *    [Line Prefix][encoded data atoms][Line Suffix]
  41.  *    [Buffer Suffix]
  42.  * </pre>
  43.  *
  44.  * Of course in the simplest encoding schemes, the buffer has no
  45.  * distinct prefix of suffix, however all have some fixed relationship
  46.  * between the text in an 'atom' and the binary data itself.
  47.  *
  48.  * In the CharacterEncoder and CharacterDecoder classes, one complete
  49.  * chunk of data is referred to as a <i>buffer</i>. Encoded buffers 
  50.  * are all text, and decoded buffers (sometimes just referred to as 
  51.  * buffers) are binary octets.
  52.  *
  53.  * To create a custom decoder, you must, at a minimum,  overide three
  54.  * abstract methods in this class.
  55.  * <DL>
  56.  * <DD>bytesPerAtom which tells the decoder how many bytes to 
  57.  * expect from decodeAtom
  58.  * <DD>decodeAtom which decodes the bytes sent to it as text.
  59.  * <DD>bytesPerLine which tells the encoder the maximum number of
  60.  * bytes per line.
  61.  * </DL>
  62.  *
  63.  * In general, the character decoders return error in the form of a
  64.  * CEFormatException. The syntax of the detail string is
  65.  * <pre>
  66.  *    DecoderClassName: Error message.
  67.  * </pre>
  68.  *
  69.  * Several useful decoders have already been written and are 
  70.  * referenced in the See Also list below.
  71.  *
  72.  * @version    10/08/95, 1.9
  73.  * @author    Chuck McManis
  74.  * @see        CEFormatException
  75.  * @see        CharacterEncoder
  76.  * @see        UCDecoder
  77.  * @see        UUDecoder
  78.  * @see        BASE64Decoder
  79.  */
  80.  
  81. public abstract class CharacterDecoder {
  82.  
  83.     /** Return the number of bytes per atom of decoding */
  84.     abstract int bytesPerAtom();
  85.  
  86.     /** Return the maximum number of bytes that can be encoded per line */
  87.     abstract int bytesPerLine();
  88.  
  89.     /** decode the beginning of the buffer, by default this is a NOP. */
  90.     void decodeBufferPrefix(InputStream aStream, OutputStream bStream) throws IOException { }
  91.  
  92.     /** decode the buffer suffix, again by default it is a NOP. */
  93.     void decodeBufferSuffix(InputStream aStream, OutputStream bStream) throws IOException { }
  94.  
  95.     /**
  96.      * This method should return, if it knows, the number of bytes
  97.      * that will be decoded. Many formats such as uuencoding provide
  98.      * this information. By default we return the maximum bytes that
  99.      * could have been encoded on the line.
  100.      */
  101.     int decodeLinePrefix(InputStream aStream, OutputStream bStream) throws IOException {
  102.     return (bytesPerLine());
  103.     }
  104.  
  105.     /**
  106.      * This method post processes the line, if there are error detection
  107.      * or correction codes in a line, they are generally processed by
  108.      * this method. The simplest version of this method looks for the
  109.      * (newline) character. 
  110.      */
  111.     void decodeLineSuffix(InputStream aStream, OutputStream bStream) throws IOException { }
  112.  
  113.     /**
  114.      * This method does an actual decode. It takes the decoded bytes and
  115.      * writes them to the OuputStream. The integer <i>l</i> tells the
  116.      * method how many bytes are required. This is always <= bytesPerAtom().
  117.      */
  118.     void decodeAtom(InputStream aStream, OutputStream bStream, int l) throws IOException { 
  119.     throw new CEStreamExhausted();
  120.     }
  121.  
  122.     /**
  123.      * This method works around the bizarre semantics of BufferedInputStream's
  124.      * read method.
  125.      */
  126.     protected int readFully(InputStream in, byte buffer[], int offset, int len) 
  127.     throws java.io.IOException {
  128.     for (int i = 0; i < len; i++) {
  129.         int q = in.read();
  130.         if (q == -1)
  131.         return ((i == 0) ? -1 : i);
  132.         buffer[i+offset] = (byte)q;
  133.     }
  134.     return len;
  135.     }
  136.  
  137.     /**
  138.      * Decode the text from the InputStream and write the decoded
  139.      * octets to the OutputStream. This method runs until the stream
  140.      * is exhausted.
  141.      * @exception CEFormatException An error has occured while decoding
  142.      * @exception CEStreamExhausted The input stream is unexpectedly out of data
  143.      */
  144.     public void decodeBuffer(InputStream aStream, OutputStream bStream) throws IOException {
  145.     int    i;
  146.     int    totalBytes = 0;
  147.  
  148.     decodeBufferPrefix(aStream, bStream);
  149.     while (true) {
  150.         int length;
  151.  
  152.         try {
  153.             length = decodeLinePrefix(aStream, bStream);
  154.         for (i = 0; (i+bytesPerAtom()) < length; i += bytesPerAtom()) {
  155.             decodeAtom(aStream, bStream, bytesPerAtom());
  156.             totalBytes += bytesPerAtom();
  157.             }
  158.         if ((i + bytesPerAtom()) == length) {
  159.             decodeAtom(aStream, bStream, bytesPerAtom());
  160.             totalBytes += bytesPerAtom();
  161.         } else {
  162.             decodeAtom(aStream, bStream, length - i);
  163.             totalBytes += (length - i);
  164.             }
  165.             decodeLineSuffix(aStream, bStream);
  166.         } catch (CEStreamExhausted e) {
  167.         break;
  168.         }
  169.     }
  170.     decodeBufferSuffix(aStream, bStream);
  171.     }
  172.  
  173.     /**
  174.      * Alternate decode interface that takes a String containing the encoded
  175.      * buffer and returns a byte array containing the data.
  176.      * @exception CEFormatException An error has occured while decoding
  177.      */
  178.     public byte decodeBuffer(String inputString)[] throws IOException {
  179.     byte    inputBuffer[] = new byte[inputString.length()];
  180.     ByteArrayInputStream inStream;
  181.     ByteArrayOutputStream outStream;
  182.  
  183.     inputString.getBytes(0, inputString.length(), inputBuffer, 0);
  184.     inStream = new ByteArrayInputStream(inputBuffer);
  185.     outStream = new ByteArrayOutputStream();
  186.     decodeBuffer(inStream, outStream);
  187.     return (outStream.toByteArray());
  188.     }
  189.  
  190.     /**
  191.      * Decode the contents of the inputstream into a buffer.
  192.      */
  193.     public byte decodeBuffer(InputStream in)[] throws IOException {
  194.     ByteArrayOutputStream outStream = new ByteArrayOutputStream();
  195.     decodeBuffer(in, outStream);
  196.     return (outStream.toByteArray());
  197.     }
  198. }
  199.