Skip to content

Inconsistent and confusing Sink/Source read/write-methods naming #137

Closed
@fzhinkin

Description

@fzhinkin

Sink and Source provide methods to read and write data; for some of them, the behavior could be unclear from the name itself. The naming could be improved to make what to expect from different methods more obvious.

Here is a table describing methods and their behavior:

Method Behavior
RawSource::read(sink: Buffer, bytesCount: Long): Long reads up to byteCount bytes into sink and returns the number of bytes read, or -1 if the source is exhausted
Source::read(sink: ByteArray, offset: Int, byteCount: Int): Int reads up to byteCount bytes and writes it into sink starting at offset, returns the number of bytes read, or -1 if the source is exhausted
Source::readFully(sink: RawSink, byteCount: Long): Unit reads byteCount bytes from the source and writes it into sink, throws exception if there are not enough data in the source
Source::readAll(sink: RawSink): Long Reads all data until exhaustion and writes it into sink, return the number of bytes read
Source::readFully(sink: ByteArray) Reads sink.length bytes from from the source
Source::readByteArray() Reads all data from the source into a newly allocated array
Source::readByteArray(byteCount: Long): ByteArray Reads byteCount bytes from the source into newly allocated array
RawSink::write(source: Buffer, byteCount: Long) writes byteCount bytes from source
Sink::write(source: ByteArray, offset: Int, byteCount: Int): Sink writes byteCount bytes from source starting from offset
Sink::writeAll(source: RawSource): Long reads data from source until its exhaustion and writes it to this sink, return the number of bytes written
Sink::write(source: RawSource, byteCount: Long): Sink reads byteCount bytes from source and writes into this sink, throws whatever exception source will throw during the read

There are some inconsistencies in the behavior of read/write method pairs, as well as in their naming:

  • Source::read(sink: ByteArray, offset: Int, byteCount: Int): Int is a unix-style read method that does not guarantee that the whole array's slice will be filled but instead returns how many bytes were actually read. Corresponding write-method, Sink::write(source: ByteArray, offset: Int, byteCount: Int): Sink, unlike it's unix ancestor, writes the whole slice.
  • Source::readFully(sink: RawSink, byteCount: Long): Unit contains Fully in the name, it's write counterpart, Sink::write(source: RawSource, byteCount: Long): Sink, doesn't.
  • At the same time, there are readAll write writeAll methods, which do conceptually the same thing as readFully/write, but use a different naming convention.

The behavior of Source::read(sink: ByteArray, offset: Int, byteCount: Int): Int and Sink::write(source: ByteArray, offset: Int, byteCount: Int): Sink mimics java.io.InputStream/OutputStream, so leaving names and behavior without any changes might be OK. Also, there are extension functions to fill the whole array with data.

However, other functions may have names allowing to distinguish them from each other and to provide a more obvious hint regarding expected behavior.

I looked at some other IO libraries, and here are the naming conventions adopted there:

I'm suggesting the following rename:

Old name New name
Source::read(sink: ByteArray, offset: Int, byteCount: Int): Int don't change
Source::readFully(sink: RawSink, byteCount: Long): Unit Source::readExactly(sink: RawSink, byteCount: Long): Unit
Source::readFully(sink: ByteArray) Source::readExactly(sink: ByteArray)
Source::readAll(sink: RawSink): Long Source::readAllTo(sink: RawSink): Long
Sink::write(source: ByteArray, offset: Int, byteCount: Int): Sink don't change
Sink::writeAll(source: RawSource): Long Sink::writeAllFrom(source: RawSource): Long
Sink::write(source: RawSource, byteCount: Long): Sink don't change

Write methods, except writeAll, have the same behavior so they could have the same name; readExactly better describes the operation compared to readFully; readAllTo/writeAllFrom additionally stress out the direction of an operation.

Your opinion will be welcomed if you have better ideas regarding the naming.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions