Search in sources :

Example 1 with Deflater

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());
    }
}
Also used : Deflater(com.jcraft.jzlib.Deflater) NXCPMessage(org.netxms.base.NXCPMessage) ConnectionPoint(org.netxms.client.topology.ConnectionPoint) AccessPoint(org.netxms.client.objects.AccessPoint)

Example 2 with Deflater

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();
}
Also used : Deflater(com.jcraft.jzlib.Deflater) DataOutputStream(java.io.DataOutputStream) DeflaterOutputStream(com.jcraft.jzlib.DeflaterOutputStream) ByteArrayOutputStream(java.io.ByteArrayOutputStream)

Example 3 with Deflater

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));
}
Also used : Deflater(com.jcraft.jzlib.Deflater) ByteArrayInputStream(java.io.ByteArrayInputStream) InflaterInputStream(com.jcraft.jzlib.InflaterInputStream) DeflaterOutputStream(com.jcraft.jzlib.DeflaterOutputStream) ByteArrayOutputStream(java.io.ByteArrayOutputStream) DataInputStream(java.io.DataInputStream)

Aggregations

Deflater (com.jcraft.jzlib.Deflater)3 DeflaterOutputStream (com.jcraft.jzlib.DeflaterOutputStream)2 ByteArrayOutputStream (java.io.ByteArrayOutputStream)2 InflaterInputStream (com.jcraft.jzlib.InflaterInputStream)1 ByteArrayInputStream (java.io.ByteArrayInputStream)1 DataInputStream (java.io.DataInputStream)1 DataOutputStream (java.io.DataOutputStream)1 NXCPMessage (org.netxms.base.NXCPMessage)1 AccessPoint (org.netxms.client.objects.AccessPoint)1 ConnectionPoint (org.netxms.client.topology.ConnectionPoint)1