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

  1. /*
  2.  * @(#)BASE64Decoder.java    1.12 95/12/20 Chuck McManis
  3.  *
  4.  * Copyright (c) 1995 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. package sun.misc;
  20.  
  21. import java.io.OutputStream;
  22. import java.io.InputStream;
  23. import java.io.PrintStream;
  24.  
  25. /**
  26.  * This class implements a BASE64 Character decoder as specified in RFC1521.
  27.  *
  28.  * This RFC is part of the MIME specification which is published by the 
  29.  * Internet Engineering Task Force (IETF). Unlike some other encoding 
  30.  * schemes there is nothing in this encoding that tells the decoder 
  31.  * where a buffer starts or stops, so to use it you will need to isolate 
  32.  * your encoded data into a single chunk and then feed them this decoder. 
  33.  * The simplest way to do that is to read all of the encoded data into a 
  34.  * string and then use:
  35.  * <pre>
  36.  *    byte    mydata[];
  37.  *    BASE64Decoder base64 = new BASE64Decoder();
  38.  *
  39.  *    mydata = base64.decodeBuffer(bufferString);
  40.  * </pre>
  41.  * This will decode the String in <i>bufferString</i> and give you an array 
  42.  * of bytes in the array <i>myData</i>. 
  43.  *
  44.  * On errors, this class throws a CEFormatException with the following detail
  45.  * strings:
  46.  * <pre>
  47.  *    "BASE64Decoder: Not enough bytes for an atom."
  48.  * </pre>
  49.  *
  50.  * @version    1.12, 12/20/95
  51.  * @author    Chuck McManis
  52.  * @see        CharacterEncoder
  53.  * @see        BASE64Decoder
  54.  */
  55.  
  56. public class BASE64Decoder extends CharacterDecoder {
  57.     
  58.     /** This class has 4 bytes per atom */
  59.     int bytesPerAtom() {
  60.     return (4);
  61.     }
  62.  
  63.     /** Any multiple of 4 will do, 72 might be common */
  64.     int bytesPerLine() {
  65.     return (72);
  66.     }
  67.  
  68.     /**
  69.      * This character array provides the character to value map
  70.      * based on RFC1521.
  71.      */
  72.     private final static char pem_array[] = {
  73.     //       0   1   2   3   4   5   6   7
  74.         'A','B','C','D','E','F','G','H', // 0
  75.         'I','J','K','L','M','N','O','P', // 1
  76.         'Q','R','S','T','U','V','W','X', // 2
  77.         'Y','Z','a','b','c','d','e','f', // 3
  78.         'g','h','i','j','k','l','m','n', // 4
  79.         'o','p','q','r','s','t','u','v', // 5
  80.         'w','x','y','z','0','1','2','3', // 6
  81.         '4','5','6','7','8','9','+','/'  // 7
  82.     };
  83.  
  84.     private final static byte pem_convert_array[] = new byte[256];
  85.  
  86.     static {
  87.     for (int i = 0; i < 255; i++) {
  88.         pem_convert_array[i] = -1;
  89.     }
  90.     for (int i = 0; i < pem_array.length; i++) {
  91.         pem_convert_array[pem_array[i]] = (byte) i;
  92.     }
  93.     }
  94.  
  95.     byte decode_buffer[] = new byte[4];
  96.  
  97.     /**
  98.      * Decode one BASE64 atom into 1, 2, or 3 bytes of data.
  99.      */
  100.     void decodeAtom(InputStream inStream, OutputStream outStream, int rem) 
  101.     throws java.io.IOException
  102.     {
  103.     int    i;
  104.     byte    a = -1, b = -1, c = -1, d = -1;
  105.  
  106.     if (rem < 2) {
  107.         throw new CEFormatException("BASE64Decoder: Not enough bytes for an atom.");
  108.     }
  109.     do {
  110.         i = inStream.read();
  111.         if (i == -1) {
  112.         throw new CEStreamExhausted();
  113.         }
  114.     } while (i == '\n' || i == '\r');
  115.     decode_buffer[0] = (byte) i;
  116.  
  117.     i = readFully(inStream, decode_buffer, 1, rem-1);
  118.     if (i == -1) {
  119.         throw new CEStreamExhausted();
  120.     }
  121.  
  122.     if (rem > 3 && decode_buffer[3] == '=') {
  123.         rem = 3;
  124.     }
  125.     if (rem > 2 && decode_buffer[2] == '=') {
  126.         rem = 2;
  127.     }
  128.     switch (rem) {
  129.     case 4:
  130.         d = pem_convert_array[decode_buffer[3] & 0xff];
  131.         // NOBREAK
  132.     case 3:
  133.         c = pem_convert_array[decode_buffer[2] & 0xff];
  134.         // NOBREAK
  135.     case 2:
  136.         b = pem_convert_array[decode_buffer[1] & 0xff];
  137.         a = pem_convert_array[decode_buffer[0] & 0xff];
  138.         break;
  139.     }
  140.  
  141.     switch (rem) {
  142.     case 2:
  143.         outStream.write( (byte)(((a << 2) & 0xfc) | ((b >>> 4) & 3)) );
  144.         break;
  145.     case 3:
  146.         outStream.write( (byte) (((a << 2) & 0xfc) | ((b >>> 4) & 3)) );
  147.         outStream.write( (byte) (((b << 4) & 0xf0) | ((c >>> 2) & 0xf)) );
  148.         break;
  149.     case 4:
  150.         outStream.write( (byte) (((a << 2) & 0xfc) | ((b >>> 4) & 3)) );
  151.         outStream.write( (byte) (((b << 4) & 0xf0) | ((c >>> 2) & 0xf)) );
  152.         outStream.write( (byte) (((c << 6) & 0xc0) | (d  & 0x3f)) );
  153.         break;
  154.     }
  155.     return;
  156.     }
  157. }
  158.