home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 1995 November / PCWK1195.iso / inne / win95 / sieciowe / hotja32.lzh / hotjava / classsrc / java / util / characterdecoder.java < prev    next >
Text File  |  1995-08-11  |  6KB  |  179 lines

  1. /*
  2.  * @(#)CharacterDecoder.java    1.2 95/03/29 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 java.util;
  21.  
  22. import java.io.OutputStream;
  23. import java.io.OutputStreamBuffer;
  24. import java.io.InputStream;
  25. import java.io.InputStreamBuffer;
  26.  
  27. /**
  28.  * This class defines the decoding half of character encoders.
  29.  * A character decoder is an algorithim for transforming 8 bit
  30.  * binary data that has been encoded into text by a character
  31.  * encoder, back into original binary form.
  32.  * 
  33.  * The character encoders, in general, have been structured 
  34.  * around a central theme that binary data can be encoded into
  35.  * text that has the form:
  36.  *
  37.  * <pre>
  38.  *    [Buffer Prefix]
  39.  *    [Line Prefix][encoded data atoms][Line Suffix]
  40.  *    [Buffer Suffix]
  41.  * </pre>
  42.  *
  43.  * Of course in the simplest encoding schemes, the buffer has no
  44.  * distinct prefix of suffix, however all have some fixed relationship
  45.  * between the text in an 'atom' and the binary data itself.
  46.  *
  47.  * In the CharacterEncoder and CharacterDecoder classes, one complete
  48.  * chunk of data is referred to as a <i>buffer</i>. Encoded buffers 
  49.  * are all text, and decoded buffers (sometimes just referred to as 
  50.  * buffers) are binary octets.
  51.  *
  52.  * To create a custom decoder, you must, at a minimum,  overide three
  53.  * abstract methods in this class.
  54.  * <DL>
  55.  * <DD>bytesPerAtom which tells the decoder how many bytes to 
  56.  * expect from decodeAtom
  57.  * <DD>decodeAtom which decodes the bytes sent to it as text.
  58.  * <DD>bytesPerLine which tells the encoder the maximum number of
  59.  * bytes per line.
  60.  * </DL>
  61.  *
  62.  * In general, the character decoders return error in the form of a
  63.  * CEFormatException. The syntax of the detail string is
  64.  * <pre>
  65.  *    DecoderClassName: Error message.
  66.  * </pre>
  67.  *
  68.  * Several useful decoders have already been written and are 
  69.  * referenced in the See Also list below.
  70.  *
  71.  * @version    29 Mar 1995, 1.2
  72.  * @author    Chuck McManis
  73.  * @see        CEFormatException
  74.  * @see        CharacterEncoder
  75.  * @see        UCDecoder
  76.  * @see        UUDecoder
  77.  * @see        BASE64Decoder
  78.  */
  79.  
  80. public class CharacterDecoder {
  81.  
  82.     /** Return the number of bytes per atom of decoding */
  83.     abstract int bytesPerAtom();
  84.  
  85.     /** Return the maximum number of bytes that can be encoded per line */
  86.     abstract int bytesPerLine();
  87.  
  88.     /** decode the beginning of the buffer, by default this is a NOP. */
  89.     void decodeBufferPrefix(InputStream aStream, OutputStream bStream) { }
  90.  
  91.     /** decode the buffer suffix, again by default it is a NOP. */
  92.     void decodeBufferSuffix(InputStream aStream, OutputStream bStream) { }
  93.  
  94.     /**
  95.      * This method should return, if it knows, the number of bytes
  96.      * that will be decoded. Many formats such as uuencoding provide
  97.      * this information. By default we return the maximum bytes that
  98.      * could have been encoded on the line.
  99.      */
  100.     int decodeLinePrefix(InputStream aStream, OutputStream bStream) {
  101.     return (bytesPerLine());
  102.     }
  103.  
  104.     /**
  105.      * This method post processes the line, if there are error detection
  106.      * or correction codes in a line, they are generally processed by
  107.      * this method. The simplest version of this method looks for the
  108.      * (newline) character. 
  109.      */
  110.     void decodeLineSuffix(InputStream aStream, OutputStream bStream) { }
  111.  
  112.     /**
  113.      * This method does an actual decode. It takes the decoded bytes and
  114.      * writes them to the OuputStream. The integer <i>l</i> tells the
  115.      * method how many bytes are required. This is always <= bytesPerAtom().
  116.      */
  117.     void decodeAtom(InputStream aStream, OutputStream bStream, int l) { 
  118.     throw new CEStreamExhausted();
  119.     }
  120.  
  121.     /**
  122.      * Decode the text from the InputStream and write the decoded
  123.      * octets to the OutputStream. This method runs until the stream
  124.      * is exhausted.
  125.      * @exception CEFormatException An error has occured while decoding
  126.      * @exception CEStreamExhausted The input stream is unexpectedly out of data
  127.      */
  128.     public void decodeBuffer(InputStream aStream, OutputStream bStream) {
  129.     int    i;
  130.  
  131.     decodeBufferPrefix(aStream, bStream);
  132.     while (true) {
  133.         int length;
  134.  
  135.         try {
  136.             length = decodeLinePrefix(aStream, bStream);
  137.         for (i = 0; (i+bytesPerAtom()) < length; i += bytesPerAtom()) {
  138.             decodeAtom(aStream, bStream, bytesPerAtom());
  139.             }
  140.         if ((i + bytesPerAtom()) == length) {
  141.             decodeAtom(aStream, bStream, bytesPerAtom());
  142.         } else {
  143.             decodeAtom(aStream, bStream, (i + bytesPerAtom()) - length);
  144.             }
  145.             decodeLineSuffix(aStream, bStream);
  146.         } catch (CEStreamExhausted e) {
  147.         break;
  148.         }
  149.     }
  150.     decodeBufferSuffix(aStream, bStream);
  151.     }
  152.  
  153.     /**
  154.      * Alternate decode interface that takes a String containing the encoded
  155.      * buffer and returns a byte array containing the data.
  156.      * @exception CEFormatException An error has occured while decoding
  157.      */
  158.     public byte decodeBuffer(String inputString)[] {
  159.     byte    inputBuffer[] = new byte[inputString.length()];
  160.     InputStreamBuffer inStream;
  161.     OutputStreamBuffer outStream;
  162.  
  163.     inputString.getBytes(0, inputString.length(), inputBuffer, 0);
  164.     inStream = new InputStreamBuffer(inputBuffer);
  165.     outStream = new OutputStreamBuffer();
  166.     decodeBuffer(inStream, outStream);
  167.     return (outStream.toByteArray());
  168.     }
  169.  
  170.     /**
  171.      * Decode the contents of the inputstream into a buffer.
  172.      */
  173.     public byte decodeBuffer(InputStream in)[] {
  174.     OutputStreamBuffer outStream = new OutputStreamBuffer();
  175.     decodeBuffer(in, outStream);
  176.     return (outStream.toByteArray());
  177.     }
  178. }
  179.