Qt qCompress equivalent in Java

I have a Qt based client / server application. The client application compresses the data using a call qCompress, and the server unpacks it using the method qUncompress.

Now I need to write a new client application in Java that communicates with the same server. For proper decompression, I need to make sure that I use the same compression as qCompress.

Web browsing, it seems Qt can use ZIP compression. I looked at classes related to java-zip. However, I am not sure if this will work. For example, a constructor ZipEntryrequires a name as a parameter. However, Qt does not require any names as a parameter.

I would appreciate it if you could confirm if Java zip classes are compatible with Qt compression / compression. If they are compatible, what will be the value of my parameter for the constructor ZipEntry? Regards.

+4
source share
2 answers

There is no library that I know, but you can use java.util.zip.Deflaterto compress the data and add the size of the uncompressed data at the beginning of the byte array:

import java.nio.ByteBuffer;
import java.util.Arrays;
import java.util.zip.DataFormatException;
import java.util.zip.Deflater;

final int MAX_DATA = 1024;
final int SIZE_LENGTH = 4;

// Input data
byte[] uncompressed = "hello".getBytes(Charset.forName("UTF-8"));

// This is simplistic, you should use a dynamic buffer
byte[] buffer = new byte[MAX_DATA];

// Add the uncompressed data size to the first 4 bytes
ByteBuffer.wrap(buffer, 0, SIZE_LENGTH).putInt(uncompressed.length);

// Compress it
Deflater deflater = new Deflater();
deflater.setInput(uncompressed);
deflater.finish();
// Write past the size bytes when compressing
int size = deflater.deflate(buffer, SIZE_LENGTH, buffer.length - SIZE_LENGTH);
// TODO maybe check the returned size value to increase the buffer size?
if (!deflater.finished()) throw new DataFormatException("Buffer size exceeded");

// Compressed data that can be consumed by qUncompress
byte[] compressed = Arrays.copyOf(buffer, SIZE_LENGTH + size);
+1
source

For those who do qCompress on the client side and send java to the application. This helper function can help you unzip it. Pay attention to the comment - I use it to process POST data, so I can not trust the data telling me what size it has.

/** This takes data sent from Qt qCompress and decompresses it.
* Note that we don't use the first 4 bytes (which is the size of the decompressed data) to avoid someone crafting
* a message which says the decompressed data is 2^32-1 even when it not.
* @param input The raw bytearray containing the whole output from qCompress
* @return The decompressed data
* @throws IOException
* @throws DataFormatException
*/
public static byte[] qUncompress(byte[] input) throws IOException, DataFormatException {
  Inflater inflater = new Inflater();
  inflater.setInput(input, 4, input.length - 4); //Strip off the first 4 bytes - this is a non standard uncompressed size that qCompress adds.
  ByteArrayOutputStream outputStream = new ByteArrayOutputStream(input.length);
  byte[] buffer = new byte[4096];
  while (!inflater.finished()) {
     int count = inflater.inflate(buffer);
     outputStream.write(buffer, 0, count);
  }
  outputStream.close();
  return outputStream.toByteArray();
}
0
source

All Articles