Skip to content

Commit 7aef688

Browse files
Split Base64 utility to reduce reflection
1 parent d0b5113 commit 7aef688

File tree

3 files changed

+75
-86
lines changed

3 files changed

+75
-86
lines changed
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package org.signal.libsignal.util
2+
3+
import android.util.Base64
4+
5+
public class AndroidBase64 : org.signal.libsignal.util.Base64.Impl {
6+
public override fun decode(encoded: ByteArray): ByteArray = Base64.decode(encoded, 0)
7+
8+
public override fun decodeUrl(encoded: ByteArray): ByteArray = Base64.decode(encoded, Base64.URL_SAFE)
9+
10+
public override fun encode(raw: ByteArray): String = Base64.encodeToString(raw, Base64.NO_WRAP)
11+
12+
public override fun encodeUrl(raw: ByteArray): String = Base64.encodeToString(
13+
raw,
14+
Base64.NO_WRAP or Base64.NO_PADDING or Base64.URL_SAFE,
15+
)
16+
}

java/client/src/test/java/org/signal/libsignal/util/Base64.java

Lines changed: 0 additions & 86 deletions
This file was deleted.
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
//
2+
// Copyright 2024 Signal Messenger, LLC.
3+
// SPDX-License-Identifier: AGPL-3.0-only
4+
//
5+
6+
package org.signal.libsignal.util
7+
8+
import java.nio.charset.StandardCharsets
9+
10+
// This whole helper can go away when we reach Android 26, which supports java.util.Base64.
11+
public class Base64 {
12+
public interface Impl {
13+
public fun decode(encoded: ByteArray): ByteArray
14+
public fun decodeUrl(encoded: ByteArray): ByteArray
15+
public fun encode(raw: ByteArray): String
16+
public fun encodeUrl(raw: ByteArray): String
17+
}
18+
19+
companion object {
20+
@JvmStatic
21+
public fun decode(str: String): ByteArray = impl.decode(str.toByteArray(StandardCharsets.UTF_8))
22+
23+
@JvmStatic
24+
public fun decodeUrl(str: String): ByteArray = impl.decodeUrl(str.toByteArray(StandardCharsets.UTF_8))
25+
26+
@JvmStatic
27+
public fun encodeToString(input: ByteArray): String = impl.encode(input)
28+
29+
@JvmStatic
30+
public fun encodeToStringUrl(input: ByteArray): String = impl.encodeUrl(input)
31+
32+
val impl: Impl = run {
33+
// Prefer the Android class. If we preferred the JRE one, we'd only test the Android
34+
// codepath when testing on older emulators.
35+
try {
36+
try {
37+
var androidImpl = Class.forName("org.signal.libsignal.util.AndroidBase64")
38+
Impl::class.java.cast(androidImpl.getConstructor().newInstance())
39+
} catch (notFoundException: ClassNotFoundException) {
40+
JavaBase64
41+
}
42+
} catch (e: Exception) {
43+
throw AssertionError(e)
44+
}
45+
}
46+
}
47+
48+
private object JavaBase64 : Impl {
49+
public override fun decode(encoded: ByteArray): ByteArray = java.util.Base64.getDecoder().decode(encoded)
50+
51+
public override fun decodeUrl(encoded: ByteArray): ByteArray = java.util.Base64.getUrlDecoder().decode(encoded)
52+
53+
public override fun encode(raw: ByteArray): String = java.util.Base64.getEncoder().encodeToString(raw)
54+
55+
public override fun encodeUrl(
56+
raw: ByteArray,
57+
): String = java.util.Base64.getUrlEncoder().withoutPadding().encodeToString(raw)
58+
}
59+
}

0 commit comments

Comments
 (0)