compression cleanups

This commit is contained in:
Shikhar Bhushan
2010-03-17 23:41:22 +01:00
parent 9cbb75084a
commit 9e92463ff2
5 changed files with 61 additions and 60 deletions

View File

@@ -74,7 +74,7 @@ abstract class Converter {
this.mac = mac;
this.compression = compression;
if (compression != null)
compression.init(getCompressionType(), -1);
compression.init(getCompressionType());
this.cipherSize = cipher.getIVSize();
}
@@ -86,6 +86,6 @@ abstract class Converter {
return compression != null && (authed || !compression.isDelayed());
}
abstract Compression.Type getCompressionType();
abstract Compression.Mode getCompressionType();
}

View File

@@ -199,8 +199,8 @@ final class Decoder
}
@Override
Compression.Type getCompressionType() {
return Compression.Type.Inflater;
Compression.Mode getCompressionType() {
return Compression.Mode.INFLATE;
}
int getMaxPacketLength() {

View File

@@ -160,9 +160,8 @@ final class Encoder
}
@Override
Compression.Type getCompressionType() {
return Compression.Type.Deflater;
Compression.Mode getCompressionType() {
return Compression.Mode.DEFLATE;
}
}

View File

@@ -35,34 +35,26 @@
*/
package net.schmizz.sshj.transport.compression;
import net.schmizz.sshj.common.SSHPacket;
import net.schmizz.sshj.common.Buffer;
import net.schmizz.sshj.transport.TransportException;
/** Interface used to compress the stream of data between the SSH server and clients. */
public interface Compression {
/** Enum identifying if this object will be used to compress or uncompress data. */
enum Type {
Inflater,
Deflater
enum Mode {
INFLATE,
DEFLATE
}
/**
* Compress the given buffer in place.
*
* @param buffer the buffer containing the data to compress s
*/
void compress(SSHPacket buffer);
/**
* Initialize this object to either compress or uncompress data. This method must be called prior to any calls to
* either <code>compress</code> or <code>uncompress</code>. Once the object has been initialized, only one of
* <code>compress</code> or <code>uncompress</code> method can be called.
*
* @param type
* @param level
* @param mode
*/
void init(Type type, int level);
void init(Mode mode);
/**
* Delayed compression is an Open-SSH specific feature which informs both the client and server to not compress data
@@ -72,13 +64,22 @@ public interface Compression {
*/
boolean isDelayed();
/**
* Compress the given buffer in place.
*
* @param buffer the buffer containing the data to compress s
*/
void compress(Buffer buffer);
/**
* Uncompress the data in a buffer into another buffer.
*
* @param from the buffer containing the data to uncompress
* @param to the buffer receiving the uncompressed data
*
* @throws TransportException
*/
void uncompress(SSHPacket from, SSHPacket to)
void uncompress(Buffer from, Buffer to)
throws TransportException;
}

View File

@@ -37,8 +37,8 @@ package net.schmizz.sshj.transport.compression;
import com.jcraft.jzlib.JZlib;
import com.jcraft.jzlib.ZStream;
import net.schmizz.sshj.common.Buffer;
import net.schmizz.sshj.common.DisconnectReason;
import net.schmizz.sshj.common.SSHPacket;
import net.schmizz.sshj.common.SSHRuntimeException;
import net.schmizz.sshj.transport.TransportException;
@@ -58,64 +58,65 @@ public class ZlibCompression
}
}
static private final int BUF_SIZE = 4096;
private static final int BUF_SIZE = 4096;
private final byte[] tempBuf = new byte[BUF_SIZE];
private ZStream stream;
private final byte[] tmpbuf = new byte[BUF_SIZE];
/** Create a new instance of a ZLib base compression */
public ZlibCompression() {
}
public void compress(SSHPacket buffer) {
stream.next_in = buffer.array();
stream.next_in_index = buffer.rpos();
stream.avail_in = buffer.available();
buffer.wpos(buffer.rpos());
do {
stream.next_out = tmpbuf;
stream.next_out_index = 0;
stream.avail_out = BUF_SIZE;
int status = stream.deflate(JZlib.Z_PARTIAL_FLUSH);
switch (status) {
case JZlib.Z_OK:
buffer.putRawBytes(tmpbuf, 0, BUF_SIZE - stream.avail_out);
public void init(Mode mode) {
stream = new ZStream();
switch (mode) {
case DEFLATE:
stream.deflateInit(JZlib.Z_DEFAULT_COMPRESSION);
break;
case INFLATE:
stream.inflateInit();
break;
default:
throw new SSHRuntimeException("compress: deflate returned " + status);
assert false;
}
} while (stream.avail_out == 0);
}
public void init(Type type, int level) {
stream = new ZStream();
if (type == Type.Deflater)
stream.deflateInit(level);
else
stream.inflateInit();
}
public boolean isDelayed() {
return false;
}
public void uncompress(SSHPacket from, SSHPacket to)
public void compress(Buffer buffer) {
stream.next_in = buffer.array();
stream.next_in_index = buffer.rpos();
stream.avail_in = buffer.available();
buffer.wpos(buffer.rpos());
do {
stream.next_out = tempBuf;
stream.next_out_index = 0;
stream.avail_out = BUF_SIZE;
final int status = stream.deflate(JZlib.Z_PARTIAL_FLUSH);
if (status == JZlib.Z_OK) {
buffer.putRawBytes(tempBuf, 0, BUF_SIZE - stream.avail_out);
} else {
throw new SSHRuntimeException("compress: deflate returned " + status);
}
} while (stream.avail_out == 0);
}
public void uncompress(Buffer from, Buffer to)
throws TransportException {
stream.next_in = from.array();
stream.next_in_index = from.rpos();
stream.avail_in = from.available();
while (true) {
stream.next_out = tmpbuf;
stream.next_out = tempBuf;
stream.next_out_index = 0;
stream.avail_out = BUF_SIZE;
int status = stream.inflate(JZlib.Z_PARTIAL_FLUSH);
final int status = stream.inflate(JZlib.Z_PARTIAL_FLUSH);
switch (status) {
case JZlib.Z_OK:
to.putRawBytes(tmpbuf, 0, BUF_SIZE - stream.avail_out);
to.putRawBytes(tempBuf, 0, BUF_SIZE - stream.avail_out);
break;
case JZlib.Z_BUF_ERROR:
return; // wtf.. but this works *head spins*
return;
default:
throw new TransportException(DisconnectReason.COMPRESSION_ERROR, "uncompress: inflate returned "
+ status);