joyent/node — pull request #4581 by Raynos (2013-01-13 01:31:53+00:00)
Title: Object streams + stream fixes

Support for having streams of "objects" which means user land modules can use `_read`, `_write`, `push` and all the buffering / back pressure logic isaacs has done in streams2 in their streams of objects.

This adds the `isObjectStream` boolean to options to switch a stream into an object stream. The object stream semantics are different, namely:

- `read()` always returns a single object. the `n` argument is ignored.
- `push(item)` pushes a single object onto the stream's internal buffer
- `cb(null, item)` in `_read` pushes a single object onto the stream's internal buffer.

If internal `onread` is ever called with something that is not a `Buffer`, `string`, `null` or `undefined` it will switch a normal stream into object stream mode.

## Bonus bug fixes

The tests for streams2 didn't tell you if they ran successfully so I added a counter to the tiny tap-like test function to ensure all tests actually ran. this found some bugs.

Specifically the drainState counter could become negative if a writable stream was unpiped and we didn't know whether it needed drain so we just did it anyway. If the drainState counter is negative then either pipe is broken or backpressure is not respected, a test has been added to ensure backpressure is respected.

Another bug was unpipe did not set `state.flowing = false` so the pipe was broken since pipe would not start flow and the readable listener which started flow was removed.

Another bug was we forgot to call `endReadable` when `_read(null, null)` was called synchronously.

All the tests pass