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

  1. /*
  2.  * @(#)UCEncoder.java    1.11 95/09/06 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. import java.io.IOException;
  25.  
  26. /**
  27.  * This class implements a robust character encoder. The encoder is designed
  28.  * to convert binary data into printable characters. The characters are
  29.  * assumed to exist but they are not assumed to be ASCII, the complete set
  30.  * is 0-9, A-Z, a-z, "(", and ")".
  31.  *
  32.  * The basic encoding unit is a 3 character atom. It encodes two bytes
  33.  * of data. Bytes are encoded into a 64 character set, the characters
  34.  * were chosen specifically because they appear in all codesets.
  35.  * We don't care what their numerical equivalent is because
  36.  * we use a character array to map them. This is like UUencoding
  37.  * with the dependency on ASCII removed.
  38.  *
  39.  * The three chars that make up an atom are encoded as follows:
  40.  * <pre>
  41.  *      00xxxyyy 00axxxxx 00byyyyy
  42.  *      00 = leading zeros, all values are 0 - 63
  43.  *      xxxyyy - Top 3 bits of X, Top 3 bits of Y
  44.  *      axxxxx - a = X parity bit, xxxxx lower 5 bits of X
  45.  *      byyyyy - b = Y parity bit, yyyyy lower 5 bits of Y
  46.  * </pre>
  47.  *
  48.  * The atoms are arranged into lines suitable for inclusion into an
  49.  * email message or text file. The number of bytes that are encoded
  50.  * per line is 48 which keeps the total line length  under 80 chars)
  51.  *
  52.  * Each line has the form(
  53.  * <pre>
  54.  *  *(LLSS)(DDDD)(DDDD)(DDDD)...(CRC)
  55.  *  Where each (xxx) represents a three character atom.
  56.  *  (LLSS) - 8 bit length (high byte), and sequence number
  57.  *           modulo 256;
  58.  *  (DDDD) - Data byte atoms, if length is odd, last data 
  59.  *           atom has (DD00) (high byte data, low byte 0)
  60.  *  (CRC)  - 16 bit CRC for the line, includes length, 
  61.  *           sequence, and all data bytes. If there is a 
  62.  *           zero pad byte (odd length) it is _NOT_ 
  63.  *           included in the CRC.
  64.  * </pre>
  65.  *
  66.  * @version     1.11, 09/06/95
  67.  * @author      Chuck McManis
  68.  * @see        CharacterEncoder
  69.  * @see        UCDecoder
  70.  */
  71. public class UCEncoder extends CharacterEncoder {
  72.  
  73.     /** this clase encodes two bytes per atom */
  74.     int bytesPerAtom() {
  75.     return (2);    
  76.     }
  77.  
  78.     /** this class encodes 48 bytes per line */
  79.     int bytesPerLine() {
  80.     return (48);
  81.     }
  82.  
  83.     /* this is the UCE mapping of 0-63 to characters .. */
  84.     private final static byte map_array[] = {
  85.                 //       0   1   2   3   4   5   6   7
  86.                         '0','1','2','3','4','5','6','7', // 0
  87.                         '8','9','A','B','C','D','E','F', // 1
  88.                         'G','H','I','J','K','L','M','N', // 2
  89.                         'O','P','Q','R','S','T','U','V', // 3
  90.                         'W','X','Y','Z','a','b','c','d', // 4
  91.                         'e','f','g','h','i','j','k','l', // 5
  92.                         'm','n','o','p','q','r','s','t', // 6
  93.                         'u','v','w','x','y','z','(',')'  // 7
  94.                 };
  95.  
  96.     private int sequence;
  97.     private byte tmp[] = new byte[2];
  98.     private CRC16 crc = new CRC16();
  99.  
  100.     /**
  101.      * encodeAtom - take two bytes and encode them into the correct
  102.      * three characters. If only one byte is to be encoded, the other
  103.      * must be zero. The padding byte is not included in the CRC computation.
  104.      */  
  105.     void encodeAtom(OutputStream outStream, byte data[], int offset, int len) throws IOException 
  106.     {
  107.     int     i;
  108.     int     p1, p2; // parity bits
  109.     byte    a, b;
  110.  
  111.     a = data[offset];
  112.     if (len == 2) {
  113.         b = data[offset+1];
  114.     } else {
  115.         b = 0;
  116.     }
  117.     crc.update(a);
  118.     if (len == 2) {
  119.         crc.update(b);
  120.     }
  121.     outStream.write(map_array[((a >>> 2) & 0x38) + ((b >>> 5) & 0x7)]);
  122.     p1 = 0; p2 = 0;
  123.     for (i = 1; i < 256; i = i * 2) {
  124.         if ((a & i) != 0) {
  125.         p1++;
  126.         }
  127.         if ((b & i) != 0) {
  128.         p2++;
  129.         }
  130.     }
  131.     p1 = (p1 & 1) * 32;
  132.     p2 = (p2 & 1) * 32;
  133.     outStream.write(map_array[(a & 31) + p1]);
  134.     outStream.write(map_array[(b & 31) + p2]);
  135.     return;
  136.     }
  137.  
  138.     /**
  139.      * Each UCE encoded line starts with a prefix of '*[XXX]', where
  140.      * the sequence number and the length are encoded in the first
  141.      * atom.
  142.      */
  143.     void encodeLinePrefix(OutputStream outStream, int length) throws IOException {
  144.     outStream.write('*');
  145.     crc.value = 0;
  146.     tmp[0] = (byte) length;
  147.     tmp[1] = (byte) sequence;
  148.     sequence = (sequence + 1) & 0xff;
  149.     encodeAtom(outStream, tmp, 0, 2);
  150.     } 
  151.  
  152.  
  153.     /**
  154.      * each UCE encoded line ends with YYY and encoded version of the
  155.      * 16 bit checksum. The most significant byte of the check sum
  156.      * is always encoded FIRST.
  157.      */
  158.     void encodeLineSuffix(OutputStream outStream) throws IOException {
  159.     tmp[0] = (byte) ((crc.value >>> 8) & 0xff);
  160.     tmp[1] = (byte) (crc.value & 0xff);
  161.     encodeAtom(outStream, tmp, 0, 2);
  162.     super.pStream.println();
  163.     }
  164.  
  165.     /**
  166.      * The buffer prefix code is used to initialize the sequence number
  167.      * to zero.
  168.      */
  169.     void encodeBufferPrefix(OutputStream a) throws IOException {
  170.     sequence = 0;
  171.     super.encodeBufferPrefix(a);
  172.     }
  173. }
  174.