Skip to content

Commit e59479c

Browse files
gnpricechrisbobbe
authored andcommitted
android [nfc]: Convert TextCompressionModule to Kotlin
Just Android Studio's auto-conversion, plus a bit of reformatting.
1 parent 0b21df3 commit e59479c

File tree

2 files changed

+90
-96
lines changed

2 files changed

+90
-96
lines changed

android/app/src/main/java/com/zulipmobile/TextCompressionModule.java

Lines changed: 0 additions & 96 deletions
This file was deleted.
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
package com.zulipmobile
2+
3+
import android.util.Base64
4+
import com.facebook.react.bridge.Promise
5+
import com.facebook.react.bridge.ReactApplicationContext
6+
import com.facebook.react.bridge.ReactContextBaseJavaModule
7+
import com.facebook.react.bridge.ReactMethod
8+
import java.io.ByteArrayOutputStream
9+
import java.io.IOException
10+
import java.io.UnsupportedEncodingException
11+
import java.util.HashMap
12+
import java.util.zip.DataFormatException
13+
import java.util.zip.Deflater
14+
import java.util.zip.Inflater
15+
16+
// TODO: Write unit tests; see
17+
// https://github.com/zulip/zulip-mobile/blob/main/docs/howto/testing.md#unit-tests-android.
18+
internal class TextCompressionModule(reactContext: ReactApplicationContext?) :
19+
ReactContextBaseJavaModule(reactContext) {
20+
override fun getName(): String {
21+
return "TextCompressionModule"
22+
}
23+
24+
// TODO: Experiment what value gives the best performance.
25+
private val bufferSize = 8192
26+
27+
private val header = "z|zlib base64|"
28+
override fun getConstants(): Map<String, Any>? {
29+
val constants: MutableMap<String, Any> = HashMap()
30+
constants["header"] = header
31+
return constants
32+
}
33+
34+
@ReactMethod
35+
fun compress(input: String, promise: Promise) {
36+
try {
37+
val outputStream = ByteArrayOutputStream()
38+
val deflater = Deflater()
39+
deflater.setInput(input.toByteArray(charset("UTF-8")))
40+
deflater.finish()
41+
val buffer = ByteArray(bufferSize)
42+
while (!deflater.finished()) {
43+
val byteCount = deflater.deflate(buffer)
44+
outputStream.write(buffer, 0, byteCount)
45+
}
46+
deflater.end()
47+
outputStream.close()
48+
// The RN bridge currently doesn't support sending byte strings, so we
49+
// have to encode the compressed output as a `String`. To avoid any
50+
// trouble, we use base64 to keep things inside ASCII.
51+
//
52+
// Ultimately our ASCII data seems to end up going to SQLite with size
53+
// no more than about 1 byte/char (presumably the string gets encoded
54+
// as UTF-8 and it's exactly 1 byte/char), so this is pretty OK.
55+
promise.resolve(header + Base64.encodeToString(outputStream.toByteArray(),
56+
Base64.DEFAULT))
57+
} catch (e: UnsupportedEncodingException) {
58+
promise.reject("UNSUPPORTED_ENCODING_EXCEPTION", e)
59+
} catch (e: IOException) {
60+
promise.reject("IO_EXCEPTION", e)
61+
}
62+
}
63+
64+
@ReactMethod
65+
fun decompress(input: String, promise: Promise) {
66+
try {
67+
val inflater = Inflater()
68+
val inputBytes = input.toByteArray(charset("ISO-8859-1"))
69+
inflater.setInput(Base64.decode(inputBytes,
70+
header.length,
71+
inputBytes.size - header.length,
72+
Base64.DEFAULT))
73+
val outputStream = ByteArrayOutputStream()
74+
val buffer = ByteArray(bufferSize)
75+
while (inflater.remaining != 0) {
76+
val byteCount = inflater.inflate(buffer)
77+
outputStream.write(buffer, 0, byteCount)
78+
}
79+
inflater.end()
80+
outputStream.close()
81+
promise.resolve(outputStream.toString("UTF-8"))
82+
} catch (e: UnsupportedEncodingException) {
83+
promise.reject("UNSUPPORTED_ENCODING_EXCEPTION", e)
84+
} catch (e: IOException) {
85+
promise.reject("IO_EXCEPTION", e)
86+
} catch (e: DataFormatException) {
87+
promise.reject("DATA_FORMAT_EXCEPTION", e)
88+
}
89+
}
90+
}

0 commit comments

Comments
 (0)