001: /*
002: * Copyright (c) 1998, 1999 Sun Microsystems, Inc. All Rights Reserved.
003: *
004: * Sun grants you ("Licensee") a non-exclusive, royalty free, license to use,
005: * modify and redistribute this software in source and binary code form,
006: * provided that i) this copyright notice and license appear on all copies of
007: * the software; and ii) Licensee does not utilize the software in a manner
008: * which is disparaging to Sun.
009: *
010: * This software is provided "AS IS," without a warranty of any kind. ALL
011: * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY
012: * IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
013: * NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE
014: * LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
015: * OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS
016: * LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT,
017: * INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
018: * CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF
019: * OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
020: * POSSIBILITY OF SUCH DAMAGES.
021: *
022: * This software is not designed or intended for use in on-line control of
023: * aircraft, air traffic, aircraft navigation or aircraft communications; or in
024: * the design, construction, operation or maintenance of any nuclear
025: * facility. Licensee represents and warrants that it will not use or
026: * redistribute the Software for such purposes.
027: */
028: package org.jboss.test.jrmp.ejb;
029:
030: import java.io.*;
031: import java.net.*;
032:
033: class CompressionInputStream extends FilterInputStream implements
034: CompressionConstants {
035: /*
036: * Constructor calls constructor of superclass
037: */
038: public CompressionInputStream(InputStream in) {
039: super (in);
040: }
041:
042: /*
043: * Buffer of unpacked 6-bit codes
044: * from last 32 bits read.
045: */
046: int buf[] = new int[5];
047:
048: /*
049: * Position of next code to read in buffer (5 signifies end).
050: */
051: int bufPos = 5;
052:
053: /*
054: * Reads in format code and decompresses character accordingly.
055: */
056:
057: public int read() throws IOException {
058: try {
059: int code;
060:
061: // Read in and ignore empty bytes (NOP's) as long as they
062: // arrive.
063: do {
064: code = readCode();
065: } while (code == NOP);
066:
067: if (code >= BASE) {
068: // Retrieve index of character in codeTable if the
069: // code is in the correct range.
070: return codeTable.charAt(code - BASE);
071: } else if (code == RAW) {
072: // read in the lower 4 bits and the higher 4 bits,
073: // and return the reconstructed character
074: int high = readCode();
075: int low = readCode();
076: return (high << 4) | low;
077: } else
078: throw new IOException("unknown compression code: "
079: + code);
080: } catch (EOFException e) {
081: // Return the end of file code
082: return -1;
083: }
084: }
085:
086: /*
087: * This method reads up to len bytes from the input stream.
088: * Returns if read blocks before len bytes are read.
089: */
090: public int read(byte b[], int off, int len) throws IOException {
091:
092: if (len <= 0) {
093: return 0;
094: }
095:
096: int c = read();
097: if (c == -1) {
098: return -1;
099: }
100: b[off] = (byte) c;
101:
102: int i = 1;
103: // Try to read up to len bytes or until no
104: // more bytes can be read without blocking.
105: try {
106: for (; (i < len) && (in.available() > 0); i++) {
107: c = read();
108: if (c == -1) {
109: break;
110: }
111: if (b != null) {
112: b[off + i] = (byte) c;
113: }
114: }
115: } catch (IOException ee) {
116: }
117: return i;
118: }
119:
120: /*
121: * If there is no more data to decode left in buf, read the
122: * next four bytes from the wire. Then store each group of 6
123: * bits in an element of buf. Return one element of buf.
124: */
125: private int readCode() throws IOException {
126: // As soon as all the data in buf has been read
127: // (when bufPos == 5) read in another four bytes.
128: if (bufPos == 5) {
129: int b1 = in.read();
130: int b2 = in.read();
131: int b3 = in.read();
132: int b4 = in.read();
133:
134: // make sure none of the bytes signify the
135: // end of the data in the stream
136: if ((b1 | b2 | b3 | b4) < 0) {
137: throw new EOFException();
138: }
139: // Assign each group of 6 bits to an element of
140: // buf
141: int pack = (b1 << 24) | (b2 << 16) | (b3 << 8) | b4;
142: buf[0] = (pack >>> 24) & 0x3F;
143: buf[1] = (pack >>> 18) & 0x3F;
144: buf[2] = (pack >>> 12) & 0x3F;
145: buf[3] = (pack >>> 6) & 0x3F;
146: buf[4] = (pack >>> 0) & 0x3F;
147: bufPos = 0;
148: }
149: return buf[bufPos++];
150: }
151: }
|