diff --git a/api/current.txt b/api/current.txt index 4c56ac98..22e159f2 100644 --- a/api/current.txt +++ b/api/current.txt @@ -450,6 +450,14 @@ package androidx.core.util { method @RequiresApi(17) public static void writeText(android.util.AtomicFile, String text, java.nio.charset.Charset charset = "Charsets.UTF_8"); } + public final class Base64Kt { + ctor public Base64Kt(); + method public static byte[] decodeBase64(String, int flags = "Base64.DEFAULT"); + method public static byte[] decodeBase64(byte[], int flags = "Base64.DEFAULT", int offset = "0", int length = "size"); + method public static String encodeBase64(String, int flags = "Base64.DEFAULT", java.nio.charset.Charset charset = "UTF_8"); + method public static String encodeBase64(byte[], int flags = "Base64.DEFAULT", int offset = "0", int length = "size"); + } + public final class HalfKt { ctor public HalfKt(); method @RequiresApi(26) public static android.util.Half toHalf(short); diff --git a/src/androidTest/java/androidx/core/util/Base64Test.kt b/src/androidTest/java/androidx/core/util/Base64Test.kt new file mode 100644 index 00000000..46c01473 --- /dev/null +++ b/src/androidTest/java/androidx/core/util/Base64Test.kt @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package androidx.core.util + +import android.util.Base64.NO_WRAP +import org.junit.Assert.assertArrayEquals +import org.junit.Assert.assertEquals +import org.junit.Test +import kotlin.text.Charsets.UTF_16BE + +class Base64Test { + @Test fun encodeFromString() { + val result = "a\uD83C\uDF69c".encodeBase64() + assertEquals("YfCfjalj\n", result) + } + + @Test fun encodeFromStringWithFlags() { + val result = "a\uD83C\uDF69c".encodeBase64(flags = NO_WRAP) + assertEquals("YfCfjalj", result) + } + + @Test fun encodeFromStringWithCharset() { + val result = "a\uD83C\uDF69c".encodeBase64(charset = UTF_16BE) + assertEquals("AGHYPN9pAGM=\n", result) + } + + @Test fun encodeFromByteArray() { + val result = "a\uD83C\uDF69c".toByteArray().encodeBase64() + assertEquals("YfCfjalj\n", result) + } + + @Test fun encodeFromByteArrayFlags() { + val result = "a\uD83C\uDF69c".toByteArray().encodeBase64(flags = NO_WRAP) + assertEquals("YfCfjalj", result) + } + + @Test fun encodeFromByteArrayOffsetAndLength() { + val result = "a\uD83C\uDF69c".toByteArray().encodeBase64(offset = 1, length = 4) + assertEquals("8J+NqQ==\n", result) + } + + @Test fun decodeFromString() { + val result = "YfCfjalj\n".decodeBase64() + assertArrayEquals("a\uD83C\uDF69c".toByteArray(), result) + } + + @Test fun decodeFromStringWithFlags() { + val result = "YfCfjalj".decodeBase64(flags = NO_WRAP) + assertArrayEquals("a\uD83C\uDF69c".toByteArray(), result) + } + + @Test fun decodeFromByteArray() { + val result = "YfCfjalj\n".toByteArray().decodeBase64() + assertArrayEquals("a\uD83C\uDF69c".toByteArray(), result) + } + + @Test fun decodeFromByteArrayWithFlags() { + val result = "YfCfjalj".toByteArray().decodeBase64(flags = NO_WRAP) + assertArrayEquals("a\uD83C\uDF69c".toByteArray(), result) + } + + @Test fun decodeFromByteArrayOffsetAndLength() { + val result = "xx8J+NqQ==xx".toByteArray().decodeBase64(offset = 2, length = 8) + assertArrayEquals("\uD83C\uDF69".toByteArray(), result) + } +} diff --git a/src/main/java/androidx/core/util/Base64.kt b/src/main/java/androidx/core/util/Base64.kt new file mode 100644 index 00000000..ba1a7b1e --- /dev/null +++ b/src/main/java/androidx/core/util/Base64.kt @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +@file:Suppress("NOTHING_TO_INLINE") + +package androidx.core.util + +import android.util.Base64 +import java.nio.charset.Charset +import kotlin.text.Charsets.US_ASCII +import kotlin.text.Charsets.UTF_8 + +/** + * Encode this [String] to its base-64 ASCII string representation. + * + * @see Base64.encode + */ +inline fun String.encodeBase64( + flags: Int = Base64.DEFAULT, + charset: Charset = UTF_8 +): String = Base64.encode(toByteArray(charset), flags).toString(US_ASCII) + +/** + * Encode this [ByteArray] to its base-64 ASCII string representation. + * + * @see Base64.encode + */ +inline fun ByteArray.encodeBase64( + flags: Int = Base64.DEFAULT, + offset: Int = 0, + length: Int = size +): String = Base64.encode(this, offset, length, flags).toString(US_ASCII) + +/** + * Decode this base-64 encoded ASCII [String] to its original bytes. + * + * @see Base64.decode + */ +inline fun String.decodeBase64( + flags: Int = Base64.DEFAULT +): ByteArray = Base64.decode(toByteArray(US_ASCII), flags) + +/** + * Decode this base-64 encoded [ByteArray] to its original bytes. + * + * @see Base64.decode + */ +inline fun ByteArray.decodeBase64( + flags: Int = Base64.DEFAULT, + offset: Int = 0, + length: Int = size +): ByteArray = Base64.decode(this, offset, length, flags)