Skip to content
This repository has been archived by the owner on Nov 14, 2018. It is now read-only.

Base 64 Kotlin extensions #406

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open

Base 64 Kotlin extensions #406

wants to merge 2 commits into from

Conversation

jaredsburrows
Copy link
Contributor

@jaredsburrows jaredsburrows commented Mar 7, 2018

import java.nio.charset.Charset

/**
* From [String] to Base-64 encoded [String].
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a sentence fragment. Prefix it with a verb like "Convert".

offset: Int = 0,
len: Int = this.length,
flags: Int = Base64.DEFAULT
): String = Base64.encode(toByteArray(), offset, len, flags).toString(Charset.forName("US-ASCII"))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The toByteArray charset parameter should be hoisted onto this function as we cannot assume UTF-8 is the desired encoding. And below.

offset: Int = 0,
len: Int = this.length,
flags: Int = Base64.DEFAULT
): String = Base64.encode(toByteArray(), offset, len, flags).toString(Charset.forName("US-ASCII"))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

import java.nio.charset.Charset

/**
* From [String] to Base-64 encoded [String].
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also nit: lowercase "Base" on all these

/**
* From Base-64 encoded [String] to decoded [String].
*/
fun String.fromBase64(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Kotlin standard library typically puts "from" methods as extensions on the companion of the type on which they operate and take an instance as the first parameter.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is no companion object in ByteArray.

/**
* From Base-64 encoded [ByteArray] to decoded [ByteArray].
*/
fun ByteArray.fromBase64(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These can all be inline since they're aliases.

assertEquals(expected, actual)
}

@Test fun fromBase64String() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pair of byte array tests too?

@jaredsburrows
Copy link
Contributor Author

@JakeWharton All fixed. What do you want to do about ByteArray not having a companion object?

@JakeWharton
Copy link
Contributor

We might have to leave it out until https://youtrack.jetbrains.com/issue/KT-11968 is fixed. I'll ask JetBrains about it at our weekly meeting next week.

Copy link
Contributor

@JakeWharton JakeWharton left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Worked out an API design that I like. Sorry for the churn.

len: Int = this.length,
flags: Int = Base64.DEFAULT,
charset: Charset = Charsets.US_ASCII
): String = Base64.encode(toByteArray(), offset, len, flags).toString(charset)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The charset should be used for toByteArray and the default should be UTF_8. The ASCII charset is for toString().

/**
* Convert [String] to base-64 encoded [String].
*/
inline fun String.toBase64(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's call this .encodeBase64 as there's no Base64 type so we're not really going "to" it.

/**
* Convert base-64 encoded [String] to decoded [String].
*/
inline fun String.Companion.fromBase64(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can go back to being an instance extension and be called decodeBase64().

len: Int = input.length,
flags: Int = Base64.DEFAULT,
charset: Charset = Charsets.US_ASCII
): String = Base64.decode(input.toByteArray(), offset, len, flags).toString(charset)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pass US_ASCII to toByteArray.

offset: Int = 0,
len: Int = input.length,
flags: Int = Base64.DEFAULT,
charset: Charset = Charsets.US_ASCII
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be UTF_8

*/
inline fun String.toBase64(
offset: Int = 0,
len: Int = this.length,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Length won't work here as you are using it as the length of the bytes whereas the parameter represents the number of characters. You need to do a substring before calling toByteArray and then pass the length of the byte array to Base64.

I would also write a test for this with two multi-byte UTF-8 characters in the source string and then a length of 1 which should thus encode more than one byte.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I updated this PR with everything else.

How would this substring work?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any update on how you want this to work? Or do you mind if I just make the PR for the String to Base64 and Base64 to String?

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants