kotlinx-io
kotlinx-io copied to clipboard
Extensions for interop with platform-specific APIs
Currently (https://github.com/Kotlin/kotlinx-io/pull/136), kotlinx-io will only provide a bare minimum of extensions required for interop with Java-specific APIs:
- functions to wrap
j.i.InputStreamandj.n.ReadableByteChannelintoSource. - functions to wrap
j.o.OutputStreamandj.n.WritableByteChannelintoSink. - functions to read from and write to
j.n.ByteBufferandjava.iostreams.
At the moment, it seems like interaction with most other core Java APIs could be performed via java.io streams or java.nio channels and buffers, so it should be sufficient to cover most cases.
This issue opened to initiate a discussion on which extensions should be added additionally, not only for JVM but for other targets too.
It's also worth revisiting names for JVM-specific Buffer extensions as some of them are confusing (compared to Source/Sink, where operations are more obvious, thanks to type names), like:
Buffer.readTo(out: OutputStream, byteCount: Long = size)Buffer.write(input: InputStream, byteCount: Long): Buffer
We may need to add some currently missing extensions and change the receiver of others to one of Buffer's interfaces - Sink or Source.
Some observations from looking on API doc:
- all functions which accept
Buffer(or interfaces) also acceptsbyteCount(readTo/readAtMostTo/write) - all functions which accept
ByteArrayalso acceptsstartIndexandendIndex(readTo/readAtMostTo/write) - there is no
copyTowhich acceptsByteArrayorByteBuffer - there is no
copyTo/readTo/transferTowhich acceptsByteBuffer, onlyreadAtMostTo/write/transferFrom - all functions which accepts
ByteBufferdoesn't have any other arguments - may be providebyteCount=byteBuffer.remainingor even start/end indices - it depends on howByteBufferis used (relative vs absolute) access
Overall, there are following core functions to work with bulks of memory: readTo/readAtMostTo/write/copyTo/transferTo/transferFrom - ideally I think we should provide all of them for each primitive (where applicable), be it Buffer(and interfaces), ByteArray, ByteBuffer, InputStream/OutputStream and may be ByteChannel(ByteWriteChannel/ByteReadChannel). But then it can be too much :)
- may be it's better not to introduce separate functions like
Buffer.smthandSource.smthbut do a checkis Bufferand use fast path if so because I believe most of the APIs will useSource/Sinkwhile under the hood they could haveBuffer. This could also reduce public API a little. Also this will reduce confusion when there is declaration likeBuffer.**(Buffer/ByteBuffer)as they will becomeSource.**andSink.**which is additionally directly shows in which direction operation goes, and so onlyBuffer.copyTowill be additional functionality that is specific toBuffer