android – Kotlin compress/deflate string to server not working-ThrowExceptions

Exception or error:

Quite a few questions/answers and many I have tried without success. I receive a compressed string that uses a MemoryStream and DeflateStream to do so (c#). The following decompression function works fine

fun decompress(string: String): String? {
    var decompressedString: String? = ""
    try {
        val bytes: ByteArray = Base64.decode(string, Base64.DEFAULT)

        val inflater = Inflater(true)
        val outputStream = ByteArrayOutputStream()
        val buffer = ByteArray(1024)
        inflater.setInput(bytes)

        while (!inflater.finished()) {
            val count = inflater.inflate(buffer)
            outputStream.write(buffer, 0, count)
        }
        inflater.end()
        outputStream.close()
        decompressedString = outputStream.toString("UTF8")

    } catch (e: IOException) {
        e.printStackTrace()
    }
    return decompressedString
}

At a later time I need to compress the data and send it back. Attempts to compress the data have been unsuccessful. The server keeps telling me that the “block length does not match with its complement.” I use the following function for compressing

fun compress(string: String): String? {
    var compressedString: String? = null
    try {
        val bytes: ByteArray = string.toByteArray(charset("UTF-8"))

        // Compress the bytes
        val deflater = Deflater()
        //val outputStream = ByteArrayOutputStream()
        val buffer = ByteArray(1024)
        deflater.setInput(bytes)
        deflater.finish()

        deflater.deflate(buffer)
        deflater.end()
        //outputStream.close()

        compressedString = Base64.encodeToString(buffer, Base64.DEFAULT)

    } catch (e: IOException) {
        e.printStackTrace()
    }
    return compressedString
}

The problem isn’t server side as it works fine with an iOS app but not Android. I’ve tried many variants of this all without success.

Anyone have any suggestions on what it is that I am doing incorrectly and what I need to do to get it to work?

Thanks ^.^

How to solve:

In case anyone else runs into this problem. I was able to solve it by changing the deflate function to

var compressedString: String? = ""
    val bytes: ByteArray = string.toByteArray(charset("UTF-8"))
    val deflater = Deflater(1, true)
    deflater.setInput(bytes)
    deflater.finish()

    val outputStream = ByteArrayOutputStream(bytes.size)

    try {
        val bytesCompressed = ByteArray(Short.MAX_VALUE.toInt())
        val numberOfBytesAfterCompression = deflater.deflate(bytesCompressed)
        val returnValues = ByteArray(numberOfBytesAfterCompression)
        System.arraycopy(bytesCompressed, 0, returnValues, 0, numberOfBytesAfterCompression)

        compressedString = Base64.encodeToString(returnValues, Base64.DEFAULT)
    } catch (e: IOException) {
        e.printStackTrace()
    }  finally {
        deflater.end()
        outputStream.close()
    }

Obtained from here deflater examples site.

Apparently using the prior function adds 2 additional bytes and this is what was causing the issue. After the change, the 2 bytes are not added. I don’t quite understand how or why so if someone knows and wishes to share, please do so.

Leave a Reply

Your email address will not be published. Required fields are marked *