fix our copyright files
[invirt/packages/invirt-vnc-client.git] / code / ZlibInStream.java
1 /* Copyright (C) 2002-2005 RealVNC Ltd.  All Rights Reserved.
2  * 
3  * This is free software; you can redistribute it and/or modify
4  * it under the terms of the GNU General Public License as published by
5  * the Free Software Foundation; either version 2 of the License, or
6  * (at your option) any later version.
7  * 
8  * This software is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11  * GNU General Public License for more details.
12  * 
13  * You should have received a copy of the GNU General Public License
14  * along with this software; if not, write to the Free Software
15  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
16  * USA.
17  */
18
19 //
20 // A ZlibInStream reads from a zlib.io.InputStream
21 //
22
23 public class ZlibInStream extends InStream {
24
25   static final int defaultBufSize = 16384;
26
27   public ZlibInStream(int bufSize_) {
28     bufSize = bufSize_;
29     b = new byte[bufSize];
30     ptr = end = ptrOffset = 0;
31     inflater = new java.util.zip.Inflater();
32   }
33
34   public ZlibInStream() { this(defaultBufSize); }
35
36   public void setUnderlying(InStream is, int bytesIn_) {
37     underlying = is;
38     bytesIn = bytesIn_;
39     ptr = end = 0;
40   }
41
42   public void reset() throws Exception {
43     ptr = end = 0;
44     if (underlying == null) return;
45
46     while (bytesIn > 0) {
47       decompress();
48       end = 0; // throw away any data
49     }
50     underlying = null;
51   }
52
53   public int pos() { return ptrOffset + ptr; }
54
55   protected int overrun(int itemSize, int nItems) throws Exception {
56     if (itemSize > bufSize)
57       throw new Exception("ZlibInStream overrun: max itemSize exceeded");
58     if (underlying == null)
59       throw new Exception("ZlibInStream overrun: no underlying stream");
60
61     if (end - ptr != 0)
62       System.arraycopy(b, ptr, b, 0, end - ptr);
63
64     ptrOffset += ptr;
65     end -= ptr;
66     ptr = 0;
67
68     while (end < itemSize) {
69       decompress();
70     }
71
72     if (itemSize * nItems > end)
73       nItems = end / itemSize;
74
75     return nItems;
76   }
77
78   // decompress() calls the decompressor once.  Note that this won't
79   // necessarily generate any output data - it may just consume some input
80   // data.  Returns false if wait is false and we would block on the underlying
81   // stream.
82
83   private void decompress() throws Exception {
84     try {
85       underlying.check(1);
86       int avail_in = underlying.getend() - underlying.getptr();
87       if (avail_in > bytesIn)
88         avail_in = bytesIn;
89
90       if (inflater.needsInput()) {
91         inflater.setInput(underlying.getbuf(), underlying.getptr(), avail_in);
92       }
93
94       int n = inflater.inflate(b, end, bufSize - end); 
95
96       end += n;
97       if (inflater.needsInput()) {
98         bytesIn -= avail_in;
99         underlying.setptr(underlying.getptr() + avail_in);
100       }
101     } catch (java.util.zip.DataFormatException e) {
102       throw new Exception("ZlibInStream: inflate failed");
103     }
104   }
105
106   private InStream underlying;
107   private int bufSize;
108   private int ptrOffset;
109   private java.util.zip.Inflater inflater;
110   private int bytesIn;
111 }