2 // Copyright (C) 2001 Mike Krueger
4 // This file was translated from java, it was part of the GNU Classpath
5 // Copyright (C) 2001 Free Software Foundation, Inc.
7 // This program is free software; you can redistribute it and/or
8 // modify it under the terms of the GNU General Public License
9 // as published by the Free Software Foundation; either version 2
10 // of the License, or (at your option) any later version.
12 // This program is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 // GNU General Public License for more details.
17 // You should have received a copy of the GNU General Public License
18 // along with this program; if not, write to the Free Software
19 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21 // Linking this library statically or dynamically with other modules is
22 // making a combined work based on this library. Thus, the terms and
23 // conditions of the GNU General Public License cover the whole
26 // As a special exception, the copyright holders of this library give you
27 // permission to link this library with independent modules to produce an
28 // executable, regardless of the license terms of these independent
29 // modules, and to copy and distribute the resulting executable under
30 // terms of your choice, provided that you also meet, for each linked
31 // independent module, the terms and conditions of the license of that
32 // module. An independent module is a module which is not derived from
33 // or based on this library. If you modify this library, you may extend
34 // this exception to your version of the library, but you are not
35 // obligated to do so. If you do not wish to do so, delete this
36 // exception statement from your version.
40 namespace ICSharpCode
.SharpZipLib
.Zip
.Compression
.Streams
44 /// Contains the output from the Inflation process.
45 /// We need to have a window so that we can refer backwards into the output stream
48 /// author of the original java version : John Leuner
50 public class OutputWindow
52 private static int WINDOW_SIZE
= 1 << 15;
53 private static int WINDOW_MASK
= WINDOW_SIZE
- 1;
55 private byte[] window
= new byte[WINDOW_SIZE
]; //The window is 2^15 bytes
56 private int windowEnd
= 0;
57 private int windowFilled
= 0;
59 public void Write(int abyte
)
61 if (windowFilled
++ == WINDOW_SIZE
) {
62 throw new InvalidOperationException("Window full");
64 window
[windowEnd
++] = (byte) abyte
;
65 windowEnd
&= WINDOW_MASK
;
69 private void SlowRepeat(int repStart
, int len
, int dist
)
72 window
[windowEnd
++] = window
[repStart
++];
73 windowEnd
&= WINDOW_MASK
;
74 repStart
&= WINDOW_MASK
;
78 public void Repeat(int len
, int dist
)
80 if ((windowFilled
+= len
) > WINDOW_SIZE
) {
81 throw new InvalidOperationException("Window full");
84 int rep_start
= (windowEnd
- dist
) & WINDOW_MASK
;
85 int border
= WINDOW_SIZE
- len
;
86 if (rep_start
<= border
&& windowEnd
< border
) {
88 System
.Array
.Copy(window
, rep_start
, window
, windowEnd
, len
);
91 /* We have to copy manually, since the repeat pattern overlaps.
94 window
[windowEnd
++] = window
[rep_start
++];
98 SlowRepeat(rep_start
, len
, dist
);
102 public int CopyStored(StreamManipulator input
, int len
)
104 len
= Math
.Min(Math
.Min(len
, WINDOW_SIZE
- windowFilled
), input
.AvailableBytes
);
107 int tailLen
= WINDOW_SIZE
- windowEnd
;
109 copied
= input
.CopyBytes(window
, windowEnd
, tailLen
);
110 if (copied
== tailLen
) {
111 copied
+= input
.CopyBytes(window
, 0, len
- tailLen
);
114 copied
= input
.CopyBytes(window
, windowEnd
, len
);
117 windowEnd
= (windowEnd
+ copied
) & WINDOW_MASK
;
118 windowFilled
+= copied
;
122 public void CopyDict(byte[] dict
, int offset
, int len
)
124 if (windowFilled
> 0) {
125 throw new InvalidOperationException();
128 if (len
> WINDOW_SIZE
) {
129 offset
+= len
- WINDOW_SIZE
;
132 System
.Array
.Copy(dict
, offset
, window
, 0, len
);
133 windowEnd
= len
& WINDOW_MASK
;
136 public int GetFreeSpace()
138 return WINDOW_SIZE
- windowFilled
;
141 public int GetAvailable()
146 public int CopyOutput(byte[] output
, int offset
, int len
)
148 int copy_end
= windowEnd
;
149 if (len
> windowFilled
) {
152 copy_end
= (windowEnd
- windowFilled
+ len
) & WINDOW_MASK
;
156 int tailLen
= len
- copy_end
;
159 System
.Array
.Copy(window
, WINDOW_SIZE
- tailLen
, output
, offset
, tailLen
);
163 System
.Array
.Copy(window
, copy_end
- len
, output
, offset
, len
);
164 windowFilled
-= copied
;
165 if (windowFilled
< 0) {
166 throw new InvalidOperationException();
173 windowFilled
= windowEnd
= 0;