-
Notifications
You must be signed in to change notification settings - Fork 59
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
Improve UnsafeByteStringOperations
APIs
#259
Comments
Reasoning behind the current API: Use of the unsafe API has some implications, and unless a developer understands what they are doing, it's better to abstain from using it. Yet another aspect: unsafe API is tightly bound to the ByteString implementation, and when we decide to change something (or to add yet another ByteString implementation, like rope-like byte strings allowing faster concatenation), some client code will be broken. Having a pretty inconvenient API is a way to ensure that not so many folks will occasionally start using the API. |
I understand this reasoning, and my point is that the annotation is the Kotlin mechanism to express this. I agree that the clunky API is another barrier, but I disagree that this is the right solution given the extent to which these APIs will be needed (see my other message below). Also, this is not the only problem here. The absence of return value from @OptIn(UnsafeByteStringApi::class)
private fun ByteString.toNSData(): NSData {
lateinit var nsData: NSData
UnsafeByteStringOperations.withByteArrayUnsafe(this) {
nsData = it.toNSData()
}
return nsData
}
@OptIn(ExperimentalForeignApi::class)
private fun ByteArray.toNSData(): NSData = memScoped {
NSData.create(bytes = allocArrayOf(this@toNSData), length = this@toNSData.size.convert())
} This is not necessary, so it would be nice to have a
That is fair, then maybe we're just missing built-in conversions between But the library cannot cover all possible external representations. |
Actually I think I would even go as far as saying these unsafe APIs will be needed way more often than this sentence implies. In particular the Any API that currently returns a There are many exampes in the JDK or popular libraries:
While I do believe that |
These unsafe operations are really needed for any zero-copy conversion between
ByteString
and other immutable APIs, or between representations that the developer knows will not be mutated during their lifespan.The opt-in annotation should be enough to deter developers from using them, so I believe it's worth making their usage slightly more comfortable. I see 2 main issues right now:
withByteArrayUnsafe
doesn't return the lambda's result, so it's not convenient to use for conversions. It requires capturing the variable outside the lambda, and this can only be deemed safe by checking the current implementation, which is really not nice (we're already using unsafe APIs, we don't want to rely on implementation details on top of that).So I would simply suggest the following:
UnsafeByteStringOperations
wrapperByteString.Companion.wrap()
andByteString.getBackingArrayReference
with the@UnsafeByteStringApi
annotationByteString.Companion.wrap()
andByteString.getBackingArrayReference
public
ByteString.Companion.wrap(array)
towrapUnsafe
, or turn it into an extensionByteArray.asByteStringUnsafe
(with the conventionalas-
prefix for methods that just wrap and keep the original instance without copy). If we go the extension route, we could also consider turning the "safe"ByteString(ByteArray)
constructor into the extensionByteArray.toByteString()
(see ReplaceByteString(ByteArray)
constructor withByteArray.toByteString()
#260).I believe
getBackingArrayReference
is already a clear indication that it's unsafe because we're accessing the backing array, so with the unsafe annotation I don't think we would need to rename it differently. But we could go as far as naming itunsafeBackingArrayReference()
.The text was updated successfully, but these errors were encountered: