use of com.jcraft.jzlib.Deflater in project netxms by netxms.
the class NXCSession method sendFileStream.
/**
* Send binary message, data loaded from provided input stream and splitted
* into chunks of {@value FILE_BUFFER_SIZE} bytes
*
* @param requestId request ID
* @param inputStream data input stream
* @param listener progress listener
* @param allowStreamCompression true if data stream compression is allowed
* @throws IOException if socket I/O error occurs
* @throws NXCException if NetXMS server returns an error or operation was timed out
*/
private void sendFileStream(final long requestId, final InputStream inputStream, ProgressListener listener, boolean allowStreamCompression) throws IOException, NXCException {
NXCPMessage msg = new NXCPMessage(NXCPCodes.CMD_FILE_DATA, requestId);
msg.setBinaryMessage(true);
Deflater compressor = allowStreamCompression ? new Deflater(9) : null;
msg.setStream(true, allowStreamCompression);
boolean success = false;
final byte[] buffer = new byte[FILE_BUFFER_SIZE];
long bytesSent = 0;
while (true) {
final int bytesRead = inputStream.read(buffer);
if (bytesRead < FILE_BUFFER_SIZE) {
msg.setEndOfFile(true);
}
if ((compressor != null) && (bytesRead > 0)) {
byte[] compressedData = new byte[compressor.deflateBound(bytesRead) + 4];
compressor.setInput(buffer, 0, bytesRead, false);
compressor.setOutput(compressedData, 4, compressedData.length - 4);
if (compressor.deflate(JZlib.Z_SYNC_FLUSH) != JZlib.Z_OK)
throw new NXCException(RCC.IO_ERROR);
int length = compressedData.length - compressor.getAvailOut();
byte[] payload = Arrays.copyOf(compressedData, length);
// DEFLATE method
payload[0] = 2;
// reserved
payload[1] = 0;
// uncompressed length, high bits
payload[2] = (byte) ((bytesRead >> 8) & 0xFF);
// uncompressed length, low bits
payload[3] = (byte) (bytesRead & 0xFF);
msg.setBinaryData(payload);
} else {
msg.setBinaryData((bytesRead == -1) ? new byte[0] : Arrays.copyOf(buffer, bytesRead));
}
sendMessage(msg);
bytesSent += (bytesRead == -1) ? 0 : bytesRead;
if (listener != null)
listener.markProgress(bytesSent);
if (bytesRead < FILE_BUFFER_SIZE) {
success = true;
break;
}
}
if (compressor != null)
compressor.deflateEnd();
if (!success) {
NXCPMessage abortMessage = new NXCPMessage(NXCPCodes.CMD_ABORT_FILE_TRANSFER, requestId);
abortMessage.setBinaryMessage(true);
sendMessage(abortMessage);
waitForRCC(abortMessage.getMessageId());
}
}
use of com.jcraft.jzlib.Deflater in project netxms by netxms.
the class NXCPMessage method createNXCPMessage.
/**
* Create binary NXCP message
*
* @return byte stream ready to send
*/
public byte[] createNXCPMessage(boolean allowCompression) throws IOException {
ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
DataOutputStream outputStream = new DataOutputStream(byteStream);
if ((messageFlags & MF_CONTROL) == MF_CONTROL) {
outputStream.writeShort(messageCode);
outputStream.writeShort(messageFlags);
// Size
outputStream.writeInt(HEADER_SIZE);
outputStream.writeInt((int) messageId);
outputStream.writeInt((int) controlData);
} else if ((messageFlags & MF_BINARY) == MF_BINARY) {
byte[] payload = binaryData;
boolean compressed = false;
if (allowCompression && ((messageFlags & MF_STREAM) == 0) && (binaryData.length > 128)) {
ByteArrayOutputStream compDataByteStream = new ByteArrayOutputStream();
byte[] length = new byte[4];
final int unpackedPadding = (8 - ((binaryData.length + HEADER_SIZE) % 8)) & 7;
intToBytes(unpackedPadding + HEADER_SIZE, length, 0);
// unpacked message size
compDataByteStream.write(length);
DeflaterOutputStream deflaterStream = new DeflaterOutputStream(compDataByteStream, new Deflater(JZlib.Z_BEST_COMPRESSION));
deflaterStream.write(binaryData);
deflaterStream.close();
byte[] compPayload = compDataByteStream.toByteArray();
if (compPayload.length < binaryData.length) {
payload = compPayload;
compressed = true;
}
}
// wCode
outputStream.writeShort(messageCode);
// wFlags
outputStream.writeShort(compressed ? (messageFlags | MF_COMPRESSED) : messageFlags);
final int length = payload.length;
final int padding = (8 - ((length + HEADER_SIZE) % 8)) & 7;
final int packetSize = length + HEADER_SIZE + padding;
// dwSize (padded to 8 bytes boundaries)
outputStream.writeInt(packetSize);
// dwId
outputStream.writeInt((int) messageId);
// dwNumVars, here used for real size of the payload (w/o headers and padding)
outputStream.writeInt(binaryData.length);
outputStream.write(payload);
for (int i = 0; i < padding; i++) outputStream.writeByte(0);
} else {
// Create byte array with all variables
for (final NXCPMessageField nxcpVariable : fields.values()) {
final byte[] field = nxcpVariable.createNXCPDataField();
outputStream.write(field);
}
byte[] payload = byteStream.toByteArray();
boolean compressed = false;
if (allowCompression && (payload.length > 128)) {
byteStream = new ByteArrayOutputStream();
byte[] length = new byte[4];
intToBytes(payload.length + HEADER_SIZE, length, 0);
byteStream.write(length);
DeflaterOutputStream deflaterStream = new DeflaterOutputStream(byteStream, new Deflater(JZlib.Z_BEST_COMPRESSION));
deflaterStream.write(payload);
deflaterStream.close();
final int padding = (8 - (byteStream.size() % 8)) & 7;
for (int i = 0; i < padding; i++) byteStream.write(0);
byte[] compPayload = byteStream.toByteArray();
if (compPayload.length < payload.length - 4) {
payload = compPayload;
compressed = true;
}
}
// Create message header in new byte stream and add payload
byteStream = new ByteArrayOutputStream();
// noinspection IOResourceOpenedButNotSafelyClosed
outputStream = new DataOutputStream(byteStream);
outputStream.writeShort(messageCode);
outputStream.writeShort(messageFlags | (compressed ? MF_COMPRESSED : 0));
// Size
outputStream.writeInt(payload.length + HEADER_SIZE);
outputStream.writeInt((int) messageId);
outputStream.writeInt(fields.size());
outputStream.write(payload);
}
return byteStream.toByteArray();
}
use of com.jcraft.jzlib.Deflater in project netxms by netxms.
the class ZlibTest method testCompression.
public void testCompression() throws Exception {
ByteArrayOutputStream bytesOut = new ByteArrayOutputStream();
bytesOut.write(new byte[] { 0x01, 0x02, 0x03, 0x04 });
DeflaterOutputStream zout = new DeflaterOutputStream(bytesOut, new Deflater(JZlib.Z_BEST_COMPRESSION));
byte[] bytes = TEXT.getBytes();
zout.write(bytes);
zout.close();
byte[] zbytes = bytesOut.toByteArray();
ByteArrayInputStream bytesIn = new ByteArrayInputStream(zbytes);
bytesIn.skip(4);
InflaterInputStream zin = new InflaterInputStream(bytesIn);
byte[] dbytes = new byte[bytes.length];
DataInputStream din = new DataInputStream(zin);
din.readFully(dbytes);
assertTrue(Arrays.equals(bytes, dbytes));
zin.close();
System.out.println(String.format("Size: clear text %d, compressed %d", bytes.length, zbytes.length));
}
Aggregations