0
|
1 /*
|
|
2 * ConnectBot: simple, powerful, open-source SSH client for Android
|
|
3 * Copyright 2007 Kenny Root, Jeffrey Sharkey
|
|
4 *
|
|
5 * Licensed under the Apache License, Version 2.0 (the "License");
|
|
6 * you may not use this file except in compliance with the License.
|
|
7 * You may obtain a copy of the License at
|
|
8 *
|
|
9 * http://www.apache.org/licenses/LICENSE-2.0
|
|
10 *
|
|
11 * Unless required by applicable law or agreed to in writing, software
|
|
12 * distributed under the License is distributed on an "AS IS" BASIS,
|
|
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14 * See the License for the specific language governing permissions and
|
|
15 * limitations under the License.
|
|
16 */
|
|
17
|
|
18 package com.trilead.ssh2.compression;
|
|
19
|
|
20 import com.jcraft.jzlib.JZlib;
|
|
21 import com.jcraft.jzlib.ZStream;
|
|
22
|
|
23 /**
|
|
24 * @author Kenny Root
|
|
25 *
|
|
26 */
|
|
27 public class Zlib implements ICompressor {
|
|
28 static private final int DEFAULT_BUF_SIZE = 4096;
|
|
29 static private final int LEVEL = 5;
|
|
30
|
|
31 private ZStream deflate;
|
|
32 private byte[] deflate_tmpbuf;
|
|
33
|
|
34 private ZStream inflate;
|
|
35 private byte[] inflate_tmpbuf;
|
|
36 private byte[] inflated_buf;
|
|
37
|
|
38 public Zlib() {
|
|
39 deflate = new ZStream();
|
|
40 inflate = new ZStream();
|
|
41 deflate.deflateInit(LEVEL);
|
|
42 inflate.inflateInit();
|
|
43 deflate_tmpbuf = new byte[DEFAULT_BUF_SIZE];
|
|
44 inflate_tmpbuf = new byte[DEFAULT_BUF_SIZE];
|
|
45 inflated_buf = new byte[DEFAULT_BUF_SIZE];
|
|
46 }
|
|
47
|
|
48 public boolean canCompressPreauth() {
|
|
49 return true;
|
|
50 }
|
|
51
|
|
52 public int getBufferSize() {
|
|
53 return DEFAULT_BUF_SIZE;
|
|
54 }
|
|
55
|
|
56 public int compress(byte[] buf, int start, int len, byte[] output) {
|
|
57 deflate.next_in = buf;
|
|
58 deflate.next_in_index = start;
|
|
59 deflate.avail_in = len - start;
|
|
60
|
|
61 if ((buf.length + 1024) > deflate_tmpbuf.length) {
|
|
62 deflate_tmpbuf = new byte[buf.length + 1024];
|
|
63 }
|
|
64
|
|
65 deflate.next_out = deflate_tmpbuf;
|
|
66 deflate.next_out_index = 0;
|
|
67 deflate.avail_out = output.length;
|
|
68
|
|
69 if (deflate.deflate(JZlib.Z_PARTIAL_FLUSH) != JZlib.Z_OK) {
|
|
70 System.err.println("compress: compression failure");
|
|
71 }
|
|
72
|
|
73 if (deflate.avail_in > 0) {
|
|
74 System.err.println("compress: deflated data too large");
|
|
75 }
|
|
76
|
|
77 int outputlen = output.length - deflate.avail_out;
|
|
78 System.arraycopy(deflate_tmpbuf, 0, output, 0, outputlen);
|
|
79 return outputlen;
|
|
80 }
|
|
81
|
|
82 public byte[] uncompress(byte[] buffer, int start, int[] length) {
|
|
83 int inflated_end = 0;
|
|
84 inflate.next_in = buffer;
|
|
85 inflate.next_in_index = start;
|
|
86 inflate.avail_in = length[0];
|
|
87
|
|
88 while (true) {
|
|
89 inflate.next_out = inflate_tmpbuf;
|
|
90 inflate.next_out_index = 0;
|
|
91 inflate.avail_out = DEFAULT_BUF_SIZE;
|
|
92 int status = inflate.inflate(JZlib.Z_PARTIAL_FLUSH);
|
|
93
|
|
94 switch (status) {
|
|
95 case JZlib.Z_OK:
|
|
96 if (inflated_buf.length < inflated_end + DEFAULT_BUF_SIZE
|
|
97 - inflate.avail_out) {
|
|
98 byte[] foo = new byte[inflated_end + DEFAULT_BUF_SIZE
|
|
99 - inflate.avail_out];
|
|
100 System.arraycopy(inflated_buf, 0, foo, 0, inflated_end);
|
|
101 inflated_buf = foo;
|
|
102 }
|
|
103
|
|
104 System.arraycopy(inflate_tmpbuf, 0, inflated_buf, inflated_end,
|
|
105 DEFAULT_BUF_SIZE - inflate.avail_out);
|
|
106 inflated_end += (DEFAULT_BUF_SIZE - inflate.avail_out);
|
|
107 length[0] = inflated_end;
|
|
108 break;
|
|
109
|
|
110 case JZlib.Z_BUF_ERROR:
|
|
111 if (inflated_end > buffer.length - start) {
|
|
112 byte[] foo = new byte[inflated_end + start];
|
|
113 System.arraycopy(buffer, 0, foo, 0, start);
|
|
114 System.arraycopy(inflated_buf, 0, foo, start, inflated_end);
|
|
115 buffer = foo;
|
|
116 }
|
|
117 else {
|
|
118 System.arraycopy(inflated_buf, 0, buffer, start,
|
|
119 inflated_end);
|
|
120 }
|
|
121
|
|
122 length[0] = inflated_end;
|
|
123 return buffer;
|
|
124
|
|
125 default:
|
|
126 System.err.println("uncompress: inflate returnd " + status);
|
|
127 return null;
|
|
128 }
|
|
129 }
|
|
130 }
|
|
131 }
|