Idiomatic representation of { buffer, bytesRead }

While working on lower-level byte streams we're encountering a number of situations that need to return something along the lines of `{ buffer, bytesRead }`. (In this setting "buffer" = ArrayBuffer.) In the most general form the signature ends up being something like

    { sourceBuffer, offset, bytesDesired } -> { newBuffer, bytesRead }

where `sourceBuffer` gets detached, then (in some other thread, most likely) up to `bytesDesired` bytes get written in at position `offset` to the backing memory, then the backing memory gets [transferred][1] to `newBuffer`, and `bytesRead` tells you how many bytes were actually read into the buffer.

I was hoping to get opinions on the most idiomatic way to represent this type in JavaScript. So far I can think of a few options:

1. Just an object literal, probably with names `{ transferred, bytesRead }`
2. A Uint8Array view onto the new buffer, starting at `offset` and extending `bytesRead`. I.e., `return new Uint8Array(result.transferred, input.offset, result.bytesRead);`.
3. A DataView view onto the buffer, similar to 2.
4. An ArrayBuffer with an additional property added!? I.e. `result.transferred.bytesRead = result.bytesRead; return result.transferred;`

1 is unambiguous, but a bit awkward, and in general does not compose well if we try to make byte streams a special case of more general streams (which is a goal).

Both 2 and 3 are essentially attempting to smuggle the two pieces of information into one object. 2 takes the "byte" idea  literally, whereas 3 uses DataView since it feels more "agnostic." In both cases you can access the underlying buffer using `view.buffer` so no generality is lost. I would be especially interested in peoples' opinions on 2 vs 3.

4 I just thought up while composing this email and is probably not such a great idea. But, I think it does work.

I wrote up a specialized version of 2 in some detail under a number of different scenarios at: https://gist.github.com/domenic/65921459ef7a31ec2839. Of particular interest might be https://gist.github.com/domenic/65921459ef7a31ec2839#a-two-buffer-pool-for-a-file-stream


[1]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer/transfer

Received on Monday, 2 March 2015 21:46:28 UTC