-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
(Draft) Base64 read & write Buffer #819
base: master
Are you sure you want to change the base?
Conversation
Do you really need this? My thoughts have always been that if base64 is causing a performance problem, the solution is to avoid base64. |
(I’m also extremely sensitive to keeping Okio small.) |
The premise is that there's a choice in the format in which data is being provided, which isn't always the case 😄 It's also still the most convenient format to use when embedding raw data within JSON. On mobile, the size of data downloaded from network requests can become non negligible for the app's memory, so I suspect that avoiding those extra copies when decoding can offer a small but nice performance boost while reading content, mostly by limiting the number of allocations and therefore the work of garbage collection. |
I like the feature; I just am reluctant to put it into the library because it leans into an awkward design. With |
I can try to see what's doable using |
Agreed! Though we’re not saving much code on Base64 by keeping it in Okio; the streaming and non-streaming implementations are different. |
That's true, it basically just saves the space of the dictionaries with encoding characters, which isn't saying much. Another solution would potentially be to have Minus the fact that if it's a large Base64 then a internal inline fun ByteString.commonBase64(): String =
Buffer().write(this).readBase64()
internal inline fun ByteString.commonBase64Url(): String =
Buffer().write(this).readBase64Url()
internal inline fun String.commonDecodeBase64(): ByteString? {
val buffer = Buffer()
try {
buffer.writeBase64(this)
} catch (e: IllegalArgumentException) { // TODO: Dedicated Base64 exception?
return null
}
return buffer.readByteString()
} This way only a single Base64 implementation remains, for |
Good point! I’m still reluctant to add streaming base64 to Okio, just in interest of making sure most of the library is of value to most of its users. |
`ByteString` relies on Buffer implementation for Base64 capabilities. `BufferedSource` and `BufferedSink` API for Base64.
Write a Base64-encoded string to a buffer, and read the contents of a buffer as a Base64-encoded string, to avoid having the extra copies required when using byte strings.
A few questions remain:
BufferedSource
andBufferedSink
? Seems like that would be a good idea.Also, I migrated the Base64 maps from byte arrays to strings because it seems wasteful to encode to a byte array then decode to a string. They could also be a char array, although I'm not sure that would make much of a difference.
Closes #613