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