diff options
Diffstat (limited to 'assets/php/vendor/react/stream')
32 files changed, 0 insertions, 6401 deletions
diff --git a/assets/php/vendor/react/stream/.gitignore b/assets/php/vendor/react/stream/.gitignore deleted file mode 100755 index 987e2a2..0000000 --- a/assets/php/vendor/react/stream/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -composer.lock -vendor diff --git a/assets/php/vendor/react/stream/.travis.yml b/assets/php/vendor/react/stream/.travis.yml deleted file mode 100755 index f4e3376..0000000 --- a/assets/php/vendor/react/stream/.travis.yml +++ /dev/null @@ -1,50 +0,0 @@ -language: php - -php: -# - 5.3 # requires old distro, see below - - 5.4 - - 5.5 - - 5.6 - - 7.0 -# - 7.0 # Mac OS X test setup, ignore errors, see below - - 7.1 - - 7.2 - - nightly # ignore errors, see below - - hhvm # ignore errors, see below - -# lock distro so new future defaults will not break the build -dist: trusty - -matrix: - include: - - php: 5.3 - dist: precise - include: - - os: osx - language: generic - php: 7.0 # just to look right on travis - env: - - PACKAGE: php70 - allow_failures: - - php: nightly - - php: hhvm - - os: osx - -install: - # OSX install inspired by https://github.com/kiler129/TravisCI-OSX-PHP - - | - if [[ "${TRAVIS_OS_NAME}" == "osx" ]]; then - brew tap homebrew/homebrew-php - echo "Installing PHP ..." - brew install "${PACKAGE}" - brew install "${PACKAGE}"-xdebug - brew link "${PACKAGE}" - echo "Installing composer ..." - curl -s http://getcomposer.org/installer | php - mv composer.phar /usr/local/bin/composer - fi - - composer install --no-interaction - -script: - - vendor/bin/phpunit --coverage-text - - time php examples/91-benchmark-throughput.php diff --git a/assets/php/vendor/react/stream/CHANGELOG.md b/assets/php/vendor/react/stream/CHANGELOG.md deleted file mode 100755 index f64815d..0000000 --- a/assets/php/vendor/react/stream/CHANGELOG.md +++ /dev/null @@ -1,377 +0,0 @@ -# Changelog - -## 0.7.7 (2018-01-19) - -* Improve test suite by fixing forward compatibility with upcoming EventLoop - releases, avoid risky tests and add test group to skip integration tests - relying on internet connection and apply appropriate test timeouts. - (#128, #131 and #132 by @clue) - -## 0.7.6 (2017-12-21) - -* Fix: Work around reading from unbuffered pipe stream in legacy PHP < 5.4.28 and PHP < 5.5.12 - (#126 by @clue) - -* Improve test suite by simplifying test bootstrapping logic via Composer and - test against PHP 7.2 - (#127 by @clue and #124 by @carusogabriel) - -## 0.7.5 (2017-11-20) - -* Fix: Igore excessive `fopen()` mode flags for `WritableResourceStream` - (#119 by @clue) - -* Fix: Fix forward compatibility with upcoming EventLoop releases - (#121 by @clue) - -* Restructure examples to ease getting started - (#123 by @clue) - -* Improve test suite by adding forward compatibility with PHPUnit 6 and - ignore Mac OS X test failures for now until Travis tests work again - (#122 by @gabriel-caruso and #120 by @clue) - -## 0.7.4 (2017-10-11) - -* Fix: Remove event listeners from `CompositeStream` once closed and - remove undocumented left-over `close` event argument - (#116 by @clue) - -* Minor documentation improvements: Fix wrong class name in example, - fix typos in README and - fix forward compatibility with upcoming EventLoop releases in example - (#113 by @docteurklein and #114 and #115 by @clue) - -* Improve test suite by running against Mac OS X on Travis - (#112 by @clue) - -## 0.7.3 (2017-08-05) - -* Improvement: Support Événement 3.0 a long side 2.0 and 1.0 - (#108 by @WyriHaximus) - -* Readme: Corrected loop initialization in usage example - (#109 by @pulyavin) - -* Travis: Lock linux distribution preventing future builds from breaking - (#110 by @clue) - -## 0.7.2 (2017-06-15) - -* Bug fix: WritableResourceStream: Close the underlying stream when closing the stream. - (#107 by @WyriHaximus) - -## 0.7.1 (2017-05-20) - -* Feature: Add optional `$writeChunkSize` parameter to limit maximum number of - bytes to write at once. - (#105 by @clue) - - ```php - $stream = new WritableResourceStream(STDOUT, $loop, null, 8192); - ``` - -* Ignore HHVM test failures for now until Travis tests work again - (#106 by @clue) - -## 0.7.0 (2017-05-04) - -* Removed / BC break: Remove deprecated and unneeded functionality - (#45, #87, #90, #91 and #93 by @clue) - - * Remove deprecated `Stream` class, use `DuplexResourceStream` instead - (#87 by @clue) - - * Remove public `$buffer` property, use new constructor parameters instead - (#91 by @clue) - - * Remove public `$stream` property from all resource streams - (#90 by @clue) - - * Remove undocumented and now unused `ReadableStream` and `WritableStream` - (#93 by @clue) - - * Remove `BufferedSink` - (#45 by @clue) - -* Feature / BC break: Simplify `ThroughStream` by using data callback instead of - inheritance. It is now a direct implementation of `DuplexStreamInterface`. - (#88 and #89 by @clue) - - ```php - $through = new ThroughStream(function ($data) { - return json_encode($data) . PHP_EOL; - }); - $through->on('data', $this->expectCallableOnceWith("[2, true]\n")); - - $through->write(array(2, true)); - ``` - -* Feature / BC break: The `CompositeStream` starts closed if either side is - already closed and forwards pause to pipe source on first write attempt. - (#96 and #103 by @clue) - - If either side of the composite stream closes, it will also close the other - side. We now also ensure that if either side is already closed during - instantiation, it will also close the other side. - -* BC break: Mark all classes as `final` and - mark internal API as `private` to discourage inheritance - (#95 and #99 by @clue) - -* Feature / BC break: Only emit `error` event for fatal errors - (#92 by @clue) - - > The `error` event was previously also allowed to be emitted for non-fatal - errors, but our implementations actually only ever emitted this as a fatal - error and then closed the stream. - -* Feature: Explicitly allow custom events and exclude any semantics - (#97 by @clue) - -* Support legacy PHP 5.3 through PHP 7.1 and HHVM and improve usage documentation - (#100 and #102 by @clue) - -* Actually require all dependencies so this is self-contained and improve - forward compatibility with EventLoop v1.0 and v0.5 - (#94 and #98 by @clue) - -## 0.6.0 (2017-03-26) - -* Feature / Fix / BC break: Add `DuplexResourceStream` and deprecate `Stream` - (#85 by @clue) - - ```php - // old (does still work for BC reasons) - $stream = new Stream($connection, $loop); - - // new - $stream = new DuplexResourceStream($connection, $loop); - ``` - - Note that the `DuplexResourceStream` now rejects read-only or write-only - streams, so this may affect BC. If you want a read-only or write-only - resource, use `ReadableResourceStream` or `WritableResourceStream` instead of - `DuplexResourceStream`. - - > BC note: This class was previously called `Stream`. The `Stream` class still - exists for BC reasons and will be removed in future versions of this package. - -* Feature / BC break: Add `WritableResourceStream` (previously called `Buffer`) - (#84 by @clue) - - ```php - // old - $stream = new Buffer(STDOUT, $loop); - - // new - $stream = new WritableResourceStream(STDOUT, $loop); - ``` - -* Feature: Add `ReadableResourceStream` - (#83 by @clue) - - ```php - $stream = new ReadableResourceStream(STDIN, $loop); - ``` - -* Fix / BC Break: Enforce using non-blocking I/O - (#46 by @clue) - - > BC note: This is known to affect process pipes on Windows which do not - support non-blocking I/O and could thus block the whole EventLoop previously. - -* Feature / Fix / BC break: Consistent semantics for - `DuplexStreamInterface::end()` to ensure it SHOULD also end readable side - (#86 by @clue) - -* Fix: Do not use unbuffered reads on pipe streams for legacy PHP < 5.4 - (#80 by @clue) - -## 0.5.0 (2017-03-08) - -* Feature / BC break: Consistent `end` event semantics (EOF) - (#70 by @clue) - - The `end` event will now only be emitted for a *successful* end, not if the - stream closes due to an unrecoverable `error` event or if you call `close()` - explicitly. - If you want to detect when the stream closes (terminates), use the `close` - event instead. - -* BC break: Remove custom (undocumented) `full-drain` event from `Buffer` - (#63 and #68 by @clue) - - > The `full-drain` event was undocumented and mostly used internally. - Relying on this event has attracted some low-quality code in the past, so - we've removed this from the public API in order to work out a better - solution instead. - If you want to detect when the buffer finishes flushing data to the stream, - you may want to look into its `end()` method or the `close` event instead. - -* Feature / BC break: Consistent event semantics and documentation, - explicitly state *when* events will be emitted and *which* arguments they - receive. - (#73 and #69 by @clue) - - The documentation now explicitly defines each event and its arguments. - Custom events and event arguments are still supported. - Most notably, all defined events only receive inherently required event - arguments and no longer transmit the instance they are emitted on for - consistency and performance reasons. - - ```php - // old (inconsistent and not supported by all implementations) - $stream->on('data', function ($data, $stream) { - // process $data - }); - - // new (consistent throughout the whole ecosystem) - $stream->on('data', function ($data) use ($stream) { - // process $data - }); - ``` - - > This mostly adds documentation (and thus some stricter, consistent - definitions) for the existing behavior, it does NOT define any major - changes otherwise. - Most existing code should be compatible with these changes, unless - it relied on some undocumented/unintended semantics. - -* Feature / BC break: Consistent method semantics and documentation - (#72 by @clue) - - > This mostly adds documentation (and thus some stricter, consistent - definitions) for the existing behavior, it does NOT define any major - changes otherwise. - Most existing code should be compatible with these changes, unless - it relied on some undocumented/unintended semantics. - -* Feature: Consistent `pipe()` semantics for closed and closing streams - (#71 from @clue) - - The source stream will now always be paused via `pause()` when the - destination stream closes. Also, properly stop piping if the source - stream closes and remove all event forwarding. - -* Improve test suite by adding PHPUnit to `require-dev` and improving coverage. - (#74 and #75 by @clue, #66 by @nawarian) - -## 0.4.6 (2017-01-25) - -* Feature: The `Buffer` can now be injected into the `Stream` (or be used standalone) - (#62 by @clue) - -* Fix: Forward `close` event only once for `CompositeStream` and `ThroughStream` - (#60 by @clue) - -* Fix: Consistent `close` event behavior for `Buffer` - (#61 by @clue) - -## 0.4.5 (2016-11-13) - -* Feature: Support setting read buffer size to `null` (infinite) - (#42 by @clue) - -* Fix: Do not emit `full-drain` event if `Buffer` is closed during `drain` event - (#55 by @clue) - -* Vastly improved performance by factor of 10x to 20x. - Raise default buffer sizes to 64 KiB and simplify and improve error handling - and unneeded function calls. - (#53, #55, #56 by @clue) - -## 0.4.4 (2016-08-22) - -* Bug fix: Emit `error` event and close `Stream` when accessing the underlying - stream resource fails with a permanent error. - (#52 and #40 by @clue, #25 by @lysenkobv) - -* Bug fix: Do not emit empty `data` event if nothing has been read (stream reached EOF) - (#39 by @clue) - -* Bug fix: Ignore empty writes to `Buffer` - (#51 by @clue) - -* Add benchmarking script to measure throughput in CI - (#41 by @clue) - -## 0.4.3 (2015-10-07) - -* Bug fix: Read buffer to 0 fixes error with libevent and large quantity of I/O (@mbonneau) -* Bug fix: No double-write during drain call (@arnaud-lb) -* Bug fix: Support HHVM (@clue) -* Adjust compatibility to 5.3 (@clue) - -## 0.4.2 (2014-09-09) - -* Added DuplexStreamInterface -* Stream sets stream resources to non-blocking -* Fixed potential race condition in pipe - -## 0.4.1 (2014-04-13) - -* Bug fix: v0.3.4 changes merged for v0.4.1 - -## 0.3.4 (2014-03-30) - -* Bug fix: [Stream] Fixed 100% CPU spike from non-empty write buffer on closed stream - -## 0.4.0 (2014-02-02) - -* BC break: Bump minimum PHP version to PHP 5.4, remove 5.3 specific hacks -* BC break: Update to Evenement 2.0 -* Dependency: Autoloading and filesystem structure now PSR-4 instead of PSR-0 - -## 0.3.3 (2013-07-08) - -* Bug fix: [Stream] Correctly detect closed connections - -## 0.3.2 (2013-05-10) - -* Bug fix: [Stream] Make sure CompositeStream is closed properly - -## 0.3.1 (2013-04-21) - -* Bug fix: [Stream] Allow any `ReadableStreamInterface` on `BufferedSink::createPromise()` - -## 0.3.0 (2013-04-14) - -* Feature: [Stream] Factory method for BufferedSink - -## 0.2.6 (2012-12-26) - -* Version bump - -## 0.2.5 (2012-11-26) - -* Feature: Make BufferedSink trigger progress events on the promise (@jsor) - -## 0.2.4 (2012-11-18) - -* Feature: Added ThroughStream, CompositeStream, ReadableStream and WritableStream -* Feature: Added BufferedSink - -## 0.2.3 (2012-11-14) - -* Version bump - -## 0.2.2 (2012-10-28) - -* Version bump - -## 0.2.1 (2012-10-14) - -* Bug fix: Check for EOF in `Buffer::write()` - -## 0.2.0 (2012-09-10) - -* Version bump - -## 0.1.1 (2012-07-12) - -* Bug fix: Testing and functional against PHP >= 5.3.3 and <= 5.3.8 - -## 0.1.0 (2012-07-11) - -* First tagged release diff --git a/assets/php/vendor/react/stream/LICENSE b/assets/php/vendor/react/stream/LICENSE deleted file mode 100755 index a808108..0000000 --- a/assets/php/vendor/react/stream/LICENSE +++ /dev/null @@ -1,19 +0,0 @@ -Copyright (c) 2012 Igor Wiedler, Chris Boden - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is furnished -to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. diff --git a/assets/php/vendor/react/stream/README.md b/assets/php/vendor/react/stream/README.md deleted file mode 100755 index c362534..0000000 --- a/assets/php/vendor/react/stream/README.md +++ /dev/null @@ -1,1224 +0,0 @@ -# Stream - -[](https://travis-ci.org/reactphp/stream) - -Event-driven readable and writable streams for non-blocking I/O in [ReactPHP](https://reactphp.org/). - -In order to make the [EventLoop](https://github.com/reactphp/event-loop) -easier to use, this component introduces the powerful concept of "streams". -Streams allow you to efficiently process huge amounts of data (such as a multi -Gigabyte file download) in small chunks without having to store everything in -memory at once. -They are very similar to the streams found in PHP itself, -but have an interface more suited for async, non-blocking I/O. - -**Table of contents** - -* [Stream usage](#stream-usage) - * [ReadableStreamInterface](#readablestreaminterface) - * [data event](#data-event) - * [end event](#end-event) - * [error event](#error-event) - * [close event](#close-event) - * [isReadable()](#isreadable) - * [pause()](#pause) - * [resume()](#resume) - * [pipe()](#pipe) - * [close()](#close) - * [WritableStreamInterface](#writablestreaminterface) - * [drain event](#drain-event) - * [pipe event](#pipe-event) - * [error event](#error-event-1) - * [close event](#close-event-1) - * [isWritable()](#iswritable) - * [write()](#write) - * [end()](#end) - * [close()](#close-1) - * [DuplexStreamInterface](#duplexstreaminterface) -* [Creating streams](#creating-streams) - * [ReadableResourceStream](#readableresourcestream) - * [WritableResourceStream](#writableresourcestream) - * [DuplexResourceStream](#duplexresourcestream) - * [ThroughStream](#throughstream) - * [CompositeStream](#compositestream) -* [Usage](#usage) -* [Install](#install) -* [Tests](#tests) -* [License](#license) -* [More](#more) - -## Stream usage - -ReactPHP uses the concept of "streams" throughout its ecosystem to provide a -consistent higher-level abstraction for processing streams of arbitrary data -contents and size. -While a stream itself is a quite low-level concept, it can be used as a powerful -abstraction to build higher-level components and protocols on top. - -If you're new to this concept, it helps to think of them as a water pipe: -You can consume water from a source or you can produce water and forward (pipe) -it to any destination (sink). - -Similarly, streams can either be - -* readable (such as `STDIN` terminal input) or -* writable (such as `STDOUT` terminal output) or -* duplex (both readable *and* writable, such as a TCP/IP connection) - -Accordingly, this package defines the following three interfaces - -* [`ReadableStreamInterface`](#readablestreaminterface) -* [`WritableStreamInterface`](#writablestreaminterface) -* [`DuplexStreamInterface`](#duplexstreaminterface) - -### ReadableStreamInterface - -The `ReadableStreamInterface` is responsible for providing an interface for -read-only streams and the readable side of duplex streams. - -Besides defining a few methods, this interface also implements the -`EventEmitterInterface` which allows you to react to certain events. - -The event callback functions MUST be a valid `callable` that obeys strict -parameter definitions and MUST accept event parameters exactly as documented. -The event callback functions MUST NOT throw an `Exception`. -The return value of the event callback functions will be ignored and has no -effect, so for performance reasons you're recommended to not return any -excessive data structures. - -Every implementation of this interface MUST follow these event semantics in -order to be considered a well-behaving stream. - -> Note that higher-level implementations of this interface may choose to - define additional events with dedicated semantics not defined as part of - this low-level stream specification. Conformance with these event semantics - is out of scope for this interface, so you may also have to refer to the - documentation of such a higher-level implementation. - -#### data event - -The `data` event will be emitted whenever some data was read/received -from this source stream. -The event receives a single mixed argument for incoming data. - -```php -$stream->on('data', function ($data) { - echo $data; -}); -``` - -This event MAY be emitted any number of times, which may be zero times if -this stream does not send any data at all. -It SHOULD not be emitted after an `end` or `close` event. - -The given `$data` argument may be of mixed type, but it's usually -recommended it SHOULD be a `string` value or MAY use a type that allows -representation as a `string` for maximum compatibility. - -Many common streams (such as a TCP/IP connection or a file-based stream) -will emit the raw (binary) payload data that is received over the wire as -chunks of `string` values. - -Due to the stream-based nature of this, the sender may send any number -of chunks with varying sizes. There are no guarantees that these chunks -will be received with the exact same framing the sender intended to send. -In other words, many lower-level protocols (such as TCP/IP) transfer the -data in chunks that may be anywhere between single-byte values to several -dozens of kilobytes. You may want to apply a higher-level protocol to -these low-level data chunks in order to achieve proper message framing. - -#### end event - -The `end` event will be emitted once the source stream has successfully -reached the end of the stream (EOF). - -```php -$stream->on('end', function () { - echo 'END'; -}); -``` - -This event SHOULD be emitted once or never at all, depending on whether -a successful end was detected. -It SHOULD NOT be emitted after a previous `end` or `close` event. -It MUST NOT be emitted if the stream closes due to a non-successful -end, such as after a previous `error` event. - -After the stream is ended, it MUST switch to non-readable mode, -see also `isReadable()`. - -This event will only be emitted if the *end* was reached successfully, -not if the stream was interrupted by an unrecoverable error or explicitly -closed. Not all streams know this concept of a "successful end". -Many use-cases involve detecting when the stream closes (terminates) -instead, in this case you should use the `close` event. -After the stream emits an `end` event, it SHOULD usually be followed by a -`close` event. - -Many common streams (such as a TCP/IP connection or a file-based stream) -will emit this event if either the remote side closes the connection or -a file handle was successfully read until reaching its end (EOF). - -Note that this event should not be confused with the `end()` method. -This event defines a successful end *reading* from a source stream, while -the `end()` method defines *writing* a successful end to a destination -stream. - -#### error event - -The `error` event will be emitted once a fatal error occurs, usually while -trying to read from this stream. -The event receives a single `Exception` argument for the error instance. - -```php -$server->on('error', function (Exception $e) { - echo 'Error: ' . $e->getMessage() . PHP_EOL; -}); -``` - -This event SHOULD be emitted once the stream detects a fatal error, such -as a fatal transmission error or after an unexpected `data` or premature -`end` event. -It SHOULD NOT be emitted after a previous `error`, `end` or `close` event. -It MUST NOT be emitted if this is not a fatal error condition, such as -a temporary network issue that did not cause any data to be lost. - -After the stream errors, it MUST close the stream and SHOULD thus be -followed by a `close` event and then switch to non-readable mode, see -also `close()` and `isReadable()`. - -Many common streams (such as a TCP/IP connection or a file-based stream) -only deal with data transmission and do not make assumption about data -boundaries (such as unexpected `data` or premature `end` events). -In other words, many lower-level protocols (such as TCP/IP) may choose -to only emit this for a fatal transmission error once and will then -close (terminate) the stream in response. - -If this stream is a `DuplexStreamInterface`, you should also notice -how the writable side of the stream also implements an `error` event. -In other words, an error may occur while either reading or writing the -stream which should result in the same error processing. - -#### close event - -The `close` event will be emitted once the stream closes (terminates). - -```php -$stream->on('close', function () { - echo 'CLOSED'; -}); -``` - -This event SHOULD be emitted once or never at all, depending on whether -the stream ever terminates. -It SHOULD NOT be emitted after a previous `close` event. - -After the stream is closed, it MUST switch to non-readable mode, -see also `isReadable()`. - -Unlike the `end` event, this event SHOULD be emitted whenever the stream -closes, irrespective of whether this happens implicitly due to an -unrecoverable error or explicitly when either side closes the stream. -If you only want to detect a *successful* end, you should use the `end` -event instead. - -Many common streams (such as a TCP/IP connection or a file-based stream) -will likely choose to emit this event after reading a *successful* `end` -event or after a fatal transmission `error` event. - -If this stream is a `DuplexStreamInterface`, you should also notice -how the writable side of the stream also implements a `close` event. -In other words, after receiving this event, the stream MUST switch into -non-writable AND non-readable mode, see also `isWritable()`. -Note that this event should not be confused with the `end` event. - -#### isReadable() - -The `isReadable(): bool` method can be used to -check whether this stream is in a readable state (not closed already). - -This method can be used to check if the stream still accepts incoming -data events or if it is ended or closed already. -Once the stream is non-readable, no further `data` or `end` events SHOULD -be emitted. - -```php -assert($stream->isReadable() === false); - -$stream->on('data', assertNeverCalled()); -$stream->on('end', assertNeverCalled()); -``` - -A successfully opened stream always MUST start in readable mode. - -Once the stream ends or closes, it MUST switch to non-readable mode. -This can happen any time, explicitly through `close()` or -implicitly due to a remote close or an unrecoverable transmission error. -Once a stream has switched to non-readable mode, it MUST NOT transition -back to readable mode. - -If this stream is a `DuplexStreamInterface`, you should also notice -how the writable side of the stream also implements an `isWritable()` -method. Unless this is a half-open duplex stream, they SHOULD usually -have the same return value. - -#### pause() - -The `pause(): void` method can be used to -pause reading incoming data events. - -Removes the data source file descriptor from the event loop. This -allows you to throttle incoming data. - -Unless otherwise noted, a successfully opened stream SHOULD NOT start -in paused state. - -Once the stream is paused, no futher `data` or `end` events SHOULD -be emitted. - -```php -$stream->pause(); - -$stream->on('data', assertShouldNeverCalled()); -$stream->on('end', assertShouldNeverCalled()); -``` - -This method is advisory-only, though generally not recommended, the -stream MAY continue emitting `data` events. - -You can continue processing events by calling `resume()` again. - -Note that both methods can be called any number of times, in particular -calling `pause()` more than once SHOULD NOT have any effect. - -See also `resume()`. - -#### resume() - -The `resume(): void` method can be used to -resume reading incoming data events. - -Re-attach the data source after a previous `pause()`. - -```php -$stream->pause(); - -$loop->addTimer(1.0, function () use ($stream) { - $stream->resume(); -}); -``` - -Note that both methods can be called any number of times, in particular -calling `resume()` without a prior `pause()` SHOULD NOT have any effect. - -See also `pause()`. - -#### pipe() - -The `pipe(WritableStreamInterface $dest, array $options = [])` method can be used to -pipe all the data from this readable source into the given writable destination. - -Automatically sends all incoming data to the destination. -Automatically throttles the source based on what the destination can handle. - -```php -$source->pipe($dest); -``` - -Similarly, you can also pipe an instance implementing `DuplexStreamInterface` -into itself in order to write back all the data that is received. -This may be a useful feature for a TCP/IP echo service: - -```php -$connection->pipe($connection); -``` - -This method returns the destination stream as-is, which can be used to -set up chains of piped streams: - -```php -$source->pipe($decodeGzip)->pipe($filterBadWords)->pipe($dest); -``` - -By default, this will call `end()` on the destination stream once the -source stream emits an `end` event. This can be disabled like this: - -```php -$source->pipe($dest, array('end' => false)); -``` - -Note that this only applies to the `end` event. -If an `error` or explicit `close` event happens on the source stream, -you'll have to manually close the destination stream: - -```php -$source->pipe($dest); -$source->on('close', function () use ($dest) { - $dest->end('BYE!'); -}); -``` - -If the source stream is not readable (closed state), then this is a NO-OP. - -```php -$source->close(); -$source->pipe($dest); // NO-OP -``` - -If the destinantion stream is not writable (closed state), then this will simply -throttle (pause) the source stream: - -```php -$dest->close(); -$source->pipe($dest); // calls $source->pause() -``` - -Similarly, if the destination stream is closed while the pipe is still -active, it will also throttle (pause) the source stream: - -```php -$source->pipe($dest); -$dest->close(); // calls $source->pause() -``` - -Once the pipe is set up successfully, the destination stream MUST emit -a `pipe` event with this source stream an event argument. - -#### close() - -The `close(): void` method can be used to -close the stream (forcefully). - -This method can be used to (forcefully) close the stream. - -```php -$stream->close(); -``` - -Once the stream is closed, it SHOULD emit a `close` event. -Note that this event SHOULD NOT be emitted more than once, in particular -if this method is called multiple times. - -After calling this method, the stream MUST switch into a non-readable -mode, see also `isReadable()`. -This means that no further `data` or `end` events SHOULD be emitted. - -```php -$stream->close(); -assert($stream->isReadable() === false); - -$stream->on('data', assertNeverCalled()); -$stream->on('end', assertNeverCalled()); -``` - -If this stream is a `DuplexStreamInterface`, you should also notice -how the writable side of the stream also implements a `close()` method. -In other words, after calling this method, the stream MUST switch into -non-writable AND non-readable mode, see also `isWritable()`. -Note that this method should not be confused with the `end()` method. - -### WritableStreamInterface - -The `WritableStreamInterface` is responsible for providing an interface for -write-only streams and the writable side of duplex streams. - -Besides defining a few methods, this interface also implements the -`EventEmitterInterface` which allows you to react to certain events. - -The event callback functions MUST be a valid `callable` that obeys strict -parameter definitions and MUST accept event parameters exactly as documented. -The event callback functions MUST NOT throw an `Exception`. -The return value of the event callback functions will be ignored and has no -effect, so for performance reasons you're recommended to not return any -excessive data structures. - -Every implementation of this interface MUST follow these event semantics in -order to be considered a well-behaving stream. - -> Note that higher-level implementations of this interface may choose to - define additional events with dedicated semantics not defined as part of - this low-level stream specification. Conformance with these event semantics - is out of scope for this interface, so you may also have to refer to the - documentation of such a higher-level implementation. - -#### drain event - -The `drain` event will be emitted whenever the write buffer became full -previously and is now ready to accept more data. - -```php -$stream->on('drain', function () use ($stream) { - echo 'Stream is now ready to accept more data'; -}); -``` - -This event SHOULD be emitted once every time the buffer became full -previously and is now ready to accept more data. -In other words, this event MAY be emitted any number of times, which may -be zero times if the buffer never became full in the first place. -This event SHOULD NOT be emitted if the buffer has not become full -previously. - -This event is mostly used internally, see also `write()` for more details. - -#### pipe event - -The `pipe` event will be emitted whenever a readable stream is `pipe()`d -into this stream. -The event receives a single `ReadableStreamInterface` argument for the -source stream. - -```php -$stream->on('pipe', function (ReadableStreamInterface $source) use ($stream) { - echo 'Now receiving piped data'; - - // explicitly close target if source emits an error - $source->on('error', function () use ($stream) { - $stream->close(); - }); -}); - -$source->pipe($stream); -``` - -This event MUST be emitted once for each readable stream that is -successfully piped into this destination stream. -In other words, this event MAY be emitted any number of times, which may -be zero times if no stream is ever piped into this stream. -This event MUST NOT be emitted if either the source is not readable -(closed already) or this destination is not writable (closed already). - -This event is mostly used internally, see also `pipe()` for more details. - -#### error event - -The `error` event will be emitted once a fatal error occurs, usually while -trying to write to this stream. -The event receives a single `Exception` argument for the error instance. - -```php -$stream->on('error', function (Exception $e) { - echo 'Error: ' . $e->getMessage() . PHP_EOL; -}); -``` - -This event SHOULD be emitted once the stream detects a fatal error, such -as a fatal transmission error. -It SHOULD NOT be emitted after a previous `error` or `close` event. -It MUST NOT be emitted if this is not a fatal error condition, such as -a temporary network issue that did not cause any data to be lost. - -After the stream errors, it MUST close the stream and SHOULD thus be -followed by a `close` event and then switch to non-writable mode, see -also `close()` and `isWritable()`. - -Many common streams (such as a TCP/IP connection or a file-based stream) -only deal with data transmission and may choose -to only emit this for a fatal transmission error once and will then -close (terminate) the stream in response. - -If this stream is a `DuplexStreamInterface`, you should also notice -how the readable side of the stream also implements an `error` event. -In other words, an error may occur while either reading or writing the -stream which should result in the same error processing. - -#### close event - -The `close` event will be emitted once the stream closes (terminates). - -```php -$stream->on('close', function () { - echo 'CLOSED'; -}); -``` - -This event SHOULD be emitted once or never at all, depending on whether -the stream ever terminates. -It SHOULD NOT be emitted after a previous `close` event. - -After the stream is closed, it MUST switch to non-writable mode, -see also `isWritable()`. - -This event SHOULD be emitted whenever the stream closes, irrespective of -whether this happens implicitly due to an unrecoverable error or -explicitly when either side closes the stream. - -Many common streams (such as a TCP/IP connection or a file-based stream) -will likely choose to emit this event after flushing the buffer from -the `end()` method, after receiving a *successful* `end` event or after -a fatal transmission `error` event. - -If this stream is a `DuplexStreamInterface`, you should also notice -how the readable side of the stream also implements a `close` event. -In other words, after receiving this event, the stream MUST switch into -non-writable AND non-readable mode, see also `isReadable()`. -Note that this event should not be confused with the `end` event. - -#### isWritable() - -The `isWritable(): bool` method can be used to -check whether this stream is in a writable state (not closed already). - -This method can be used to check if the stream still accepts writing -any data or if it is ended or closed already. -Writing any data to a non-writable stream is a NO-OP: - -```php -assert($stream->isWritable() === false); - -$stream->write('end'); // NO-OP -$stream->end('end'); // NO-OP -``` - -A successfully opened stream always MUST start in writable mode. - -Once the stream ends or closes, it MUST switch to non-writable mode. -This can happen any time, explicitly through `end()` or `close()` or -implicitly due to a remote close or an unrecoverable transmission error. -Once a stream has switched to non-writable mode, it MUST NOT transition -back to writable mode. - -If this stream is a `DuplexStreamInterface`, you should also notice -how the readable side of the stream also implements an `isReadable()` -method. Unless this is a half-open duplex stream, they SHOULD usually -have the same return value. - -#### write() - -The `write(mixed $data): bool` method can be used to -write some data into the stream. - -A successful write MUST be confirmed with a boolean `true`, which means -that either the data was written (flushed) immediately or is buffered and -scheduled for a future write. Note that this interface gives you no -control over explicitly flushing the buffered data, as finding the -appropriate time for this is beyond the scope of this interface and left -up to the implementation of this interface. - -Many common streams (such as a TCP/IP connection or file-based stream) -may choose to buffer all given data and schedule a future flush by using -an underlying EventLoop to check when the resource is actually writable. - -If a stream cannot handle writing (or flushing) the data, it SHOULD emit -an `error` event and MAY `close()` the stream if it can not recover from -this error. - -If the internal buffer is full after adding `$data`, then `write()` -SHOULD return `false`, indicating that the caller should stop sending -data until the buffer drains. -The stream SHOULD send a `drain` event once the buffer is ready to accept -more data. - -Similarly, if the the stream is not writable (already in a closed state) -it MUST NOT process the given `$data` and SHOULD return `false`, -indicating that the caller should stop sending data. - -The given `$data` argument MAY be of mixed type, but it's usually -recommended it SHOULD be a `string` value or MAY use a type that allows -representation as a `string` for maximum compatibility. - -Many common streams (such as a TCP/IP connection or a file-based stream) -will only accept the raw (binary) payload data that is transferred over -the wire as chunks of `string` values. - -Due to the stream-based nature of this, the sender may send any number -of chunks with varying sizes. There are no guarantees that these chunks -will be received with the exact same framing the sender intended to send. -In other words, many lower-level protocols (such as TCP/IP) transfer the -data in chunks that may be anywhere between single-byte values to several -dozens of kilobytes. You may want to apply a higher-level protocol to -these low-level data chunks in order to achieve proper message framing. - -#### end() - -The `end(mixed $data = null): void` method can be used to -successfully end the stream (after optionally sending some final data). - -This method can be used to successfully end the stream, i.e. close -the stream after sending out all data that is currently buffered. - -```php -$stream->write('hello'); -$stream->write('world'); -$stream->end(); -``` - -If there's no data currently buffered and nothing to be flushed, then -this method MAY `close()` the stream immediately. - -If there's still data in the buffer that needs to be flushed first, then -this method SHOULD try to write out this data and only then `close()` -the stream. -Once the stream is closed, it SHOULD emit a `close` event. - -Note that this interface gives you no control over explicitly flushing -the buffered data, as finding the appropriate time for this is beyond the -scope of this interface and left up to the implementation of this -interface. - -Many common streams (such as a TCP/IP connection or file-based stream) -may choose to buffer all given data and schedule a future flush by using -an underlying EventLoop to check when the resource is actually writable. - -You can optionally pass some final data that is written to the stream -before ending the stream. If a non-`null` value is given as `$data`, then -this method will behave just like calling `write($data)` before ending -with no data. - -```php -// shorter version -$stream->end('bye'); - -// same as longer version -$stream->write('bye'); -$stream->end(); -``` - -After calling this method, the stream MUST switch into a non-writable -mode, see also `isWritable()`. -This means that no further writes are possible, so any additional -`write()` or `end()` calls have no effect. - -```php -$stream->end(); -assert($stream->isWritable() === false); - -$stream->write('nope'); // NO-OP -$stream->end(); // NO-OP -``` - -If this stream is a `DuplexStreamInterface`, calling this method SHOULD -also end its readable side, unless the stream supports half-open mode. -In other words, after calling this method, these streams SHOULD switch -into non-writable AND non-readable mode, see also `isReadable()`. -This implies that in this case, the stream SHOULD NOT emit any `data` -or `end` events anymore. -Streams MAY choose to use the `pause()` method logic for this, but -special care may have to be taken to ensure a following call to the -`resume()` method SHOULD NOT continue emitting readable events. - -Note that this method should not be confused with the `close()` method. - -#### close() - -The `close(): void` method can be used to -close the stream (forcefully). - -This method can be used to forcefully close the stream, i.e. close -the stream without waiting for any buffered data to be flushed. -If there's still data in the buffer, this data SHOULD be discarded. - -```php -$stream->close(); -``` - -Once the stream is closed, it SHOULD emit a `close` event. -Note that this event SHOULD NOT be emitted more than once, in particular -if this method is called multiple times. - -After calling this method, the stream MUST switch into a non-writable -mode, see also `isWritable()`. -This means that no further writes are possible, so any additional -`write()` or `end()` calls have no effect. - -```php -$stream->close(); -assert($stream->isWritable() === false); - -$stream->write('nope'); // NO-OP -$stream->end(); // NO-OP -``` - -Note that this method should not be confused with the `end()` method. -Unlike the `end()` method, this method does not take care of any existing -buffers and simply discards any buffer contents. -Likewise, this method may also be called after calling `end()` on a -stream in order to stop waiting for the stream to flush its final data. - -```php -$stream->end(); -$loop->addTimer(1.0, function () use ($stream) { - $stream->close(); -}); -``` - -If this stream is a `DuplexStreamInterface`, you should also notice -how the readable side of the stream also implements a `close()` method. -In other words, after calling this method, the stream MUST switch into -non-writable AND non-readable mode, see also `isReadable()`. - -### DuplexStreamInterface - -The `DuplexStreamInterface` is responsible for providing an interface for -duplex streams (both readable and writable). - -It builds on top of the existing interfaces for readable and writable streams -and follows the exact same method and event semantics. -If you're new to this concept, you should look into the -`ReadableStreamInterface` and `WritableStreamInterface` first. - -Besides defining a few methods, this interface also implements the -`EventEmitterInterface` which allows you to react to the same events defined -on the `ReadbleStreamInterface` and `WritableStreamInterface`. - -The event callback functions MUST be a valid `callable` that obeys strict -parameter definitions and MUST accept event parameters exactly as documented. -The event callback functions MUST NOT throw an `Exception`. -The return value of the event callback functions will be ignored and has no -effect, so for performance reasons you're recommended to not return any -excessive data structures. - -Every implementation of this interface MUST follow these event semantics in -order to be considered a well-behaving stream. - -> Note that higher-level implementations of this interface may choose to - define additional events with dedicated semantics not defined as part of - this low-level stream specification. Conformance with these event semantics - is out of scope for this interface, so you may also have to refer to the - documentation of such a higher-level implementation. - -See also [`ReadableStreamInterface`](#readablestreaminterface) and -[`WritableStreamInterface`](#writablestreaminterface) for more details. - -## Creating streams - -ReactPHP uses the concept of "streams" throughout its ecosystem, so that -many higher-level consumers of this package only deal with -[stream usage](#stream-usage). -This implies that stream instances are most often created within some -higher-level components and many consumers never actually have to deal with -creating a stream instance. - -* Use [react/socket](https://github.com/reactphp/socket) - if you want to accept incoming or establish outgoing plaintext TCP/IP or - secure TLS socket connection streams. -* Use [react/http](https://github.com/reactphp/http) - if you want to receive an incoming HTTP request body streams. -* Use [react/child-process](https://github.com/reactphp/child-process) - if you want to communicate with child processes via process pipes such as - STDIN, STDOUT, STDERR etc. -* Use experimental [react/filesystem](https://github.com/reactphp/filesystem) - if you want to read from / write to the filesystem. -* See also the last chapter for [more real-world applications](#more). - -However, if you are writing a lower-level component or want to create a stream -instance from a stream resource, then the following chapter is for you. - -> Note that the following examples use `fopen()` and `stream_socket_client()` - for illustration purposes only. - These functions SHOULD NOT be used in a truly async program because each call - may take several seconds to complete and would block the EventLoop otherwise. - Additionally, the `fopen()` call will return a file handle on some platforms - which may or may not be supported by all EventLoop implementations. - As an alternative, you may want to use higher-level libraries listed above. - -### ReadableResourceStream - -The `ReadableResourceStream` is a concrete implementation of the -[`ReadableStreamInterface`](#readablestreaminterface) for PHP's stream resources. - -This can be used to represent a read-only resource like a file stream opened in -readable mode or a stream such as `STDIN`: - -```php -$stream = new ReadableResourceStream(STDIN, $loop); -$stream->on('data', function ($chunk) { - echo $chunk; -}); -$stream->on('end', function () { - echo 'END'; -}); -``` - -See also [`ReadableStreamInterface`](#readablestreaminterface) for more details. - -The first parameter given to the constructor MUST be a valid stream resource -that is opened in reading mode (e.g. `fopen()` mode `r`). -Otherwise, it will throw an `InvalidArgumentException`: - -```php -// throws InvalidArgumentException -$stream = new ReadableResourceStream(false, $loop); -``` - -See also the [`DuplexResourceStream`](#readableresourcestream) for read-and-write -stream resources otherwise. - -Internally, this class tries to enable non-blocking mode on the stream resource -which may not be supported for all stream resources. -Most notably, this is not supported by pipes on Windows (STDIN etc.). -If this fails, it will throw a `RuntimeException`: - -```php -// throws RuntimeException on Windows -$stream = new ReadableResourceStream(STDIN, $loop); -``` - -Once the constructor is called with a valid stream resource, this class will -take care of the underlying stream resource. -You SHOULD only use its public API and SHOULD NOT interfere with the underlying -stream resource manually. - -This class takes an optional `int|null $readChunkSize` parameter that controls -the maximum buffer size in bytes to read at once from the stream. -You can use a `null` value here in order to apply its default value. -This value SHOULD NOT be changed unless you know what you're doing. -This can be a positive number which means that up to X bytes will be read -at once from the underlying stream resource. Note that the actual number -of bytes read may be lower if the stream resource has less than X bytes -currently available. -This can be `-1` which means "read everything available" from the -underlying stream resource. -This should read until the stream resource is not readable anymore -(i.e. underlying buffer drained), note that this does not neccessarily -mean it reached EOF. - -```php -$stream = new ReadableResourceStream(STDIN, $loop, 8192); -``` - -> PHP bug warning: If the PHP process has explicitly been started without a - `STDIN` stream, then trying to read from `STDIN` may return data from - another stream resource. This does not happen if you start this with an empty - stream like `php test.php < /dev/null` instead of `php test.php <&-`. - See [#81](https://github.com/reactphp/stream/issues/81) for more details. - -### WritableResourceStream - -The `WritableResourceStream` is a concrete implementation of the -[`WritableStreamInterface`](#writablestreaminterface) for PHP's stream resources. - -This can be used to represent a write-only resource like a file stream opened in -writable mode or a stream such as `STDOUT` or `STDERR`: - -```php -$stream = new WritableResourceStream(STDOUT, $loop); -$stream->write('hello!'); -$stream->end(); -``` - -See also [`WritableStreamInterface`](#writablestreaminterface) for more details. - -The first parameter given to the constructor MUST be a valid stream resource -that is opened for writing. -Otherwise, it will throw an `InvalidArgumentException`: - -```php -// throws InvalidArgumentException -$stream = new WritableResourceStream(false, $loop); -``` - -See also the [`DuplexResourceStream`](#readableresourcestream) for read-and-write -stream resources otherwise. - -Internally, this class tries to enable non-blocking mode on the stream resource -which may not be supported for all stream resources. -Most notably, this is not supported by pipes on Windows (STDOUT, STDERR etc.). -If this fails, it will throw a `RuntimeException`: - -```php -// throws RuntimeException on Windows -$stream = new WritableResourceStream(STDOUT, $loop); -``` - -Once the constructor is called with a valid stream resource, this class will -take care of the underlying stream resource. -You SHOULD only use its public API and SHOULD NOT interfere with the underlying -stream resource manually. - -Any `write()` calls to this class will not be performed instantly, but will -be performed asynchronously, once the EventLoop reports the stream resource is -ready to accept data. -For this, it uses an in-memory buffer string to collect all outstanding writes. -This buffer has a soft-limit applied which defines how much data it is willing -to accept before the caller SHOULD stop sending further data. - -This class takes an optional `int|null $writeBufferSoftLimit` parameter that controls -this maximum buffer size in bytes. -You can use a `null` value here in order to apply its default value. -This value SHOULD NOT be changed unless you know what you're doing. - -```php -$stream = new WritableResourceStream(STDOUT, $loop, 8192); -``` - -This class takes an optional `int|null $writeChunkSize` parameter that controls -this maximum buffer size in bytes to write at once to the stream. -You can use a `null` value here in order to apply its default value. -This value SHOULD NOT be changed unless you know what you're doing. -This can be a positive number which means that up to X bytes will be written -at once to the underlying stream resource. Note that the actual number -of bytes written may be lower if the stream resource has less than X bytes -currently available. -This can be `-1` which means "write everything available" to the -underlying stream resource. - -```php -$stream = new WritableResourceStream(STDOUT, $loop, null, 8192); -``` - -See also [`write()`](#write) for more details. - -### DuplexResourceStream - -The `DuplexResourceStream` is a concrete implementation of the -[`DuplexStreamInterface`](#duplexstreaminterface) for PHP's stream resources. - -This can be used to represent a read-and-write resource like a file stream opened -in read and write mode mode or a stream such as a TCP/IP connection: - -```php -$conn = stream_socket_client('tcp://google.com:80'); -$stream = new DuplexResourceStream($conn, $loop); -$stream->write('hello!'); -$stream->end(); -``` - -See also [`DuplexStreamInterface`](#duplexstreaminterface) for more details. - -The first parameter given to the constructor MUST be a valid stream resource -that is opened for reading *and* writing. -Otherwise, it will throw an `InvalidArgumentException`: - -```php -// throws InvalidArgumentException -$stream = new DuplexResourceStream(false, $loop); -``` - -See also the [`ReadableResourceStream`](#readableresourcestream) for read-only -and the [`WritableResourceStream`](#writableresourcestream) for write-only -stream resources otherwise. - -Internally, this class tries to enable non-blocking mode on the stream resource -which may not be supported for all stream resources. -Most notably, this is not supported by pipes on Windows (STDOUT, STDERR etc.). -If this fails, it will throw a `RuntimeException`: - -```php -// throws RuntimeException on Windows -$stream = new DuplexResourceStream(STDOUT, $loop); -``` - -Once the constructor is called with a valid stream resource, this class will -take care of the underlying stream resource. -You SHOULD only use its public API and SHOULD NOT interfere with the underlying -stream resource manually. - -This class takes an optional `int|null $readChunkSize` parameter that controls -the maximum buffer size in bytes to read at once from the stream. -You can use a `null` value here in order to apply its default value. -This value SHOULD NOT be changed unless you know what you're doing. -This can be a positive number which means that up to X bytes will be read -at once from the underlying stream resource. Note that the actual number -of bytes read may be lower if the stream resource has less than X bytes -currently available. -This can be `-1` which means "read everything available" from the -underlying stream resource. -This should read until the stream resource is not readable anymore -(i.e. underlying buffer drained), note that this does not neccessarily -mean it reached EOF. - -```php -$conn = stream_socket_client('tcp://google.com:80'); -$stream = new DuplexResourceStream($conn, $loop, 8192); -``` - -Any `write()` calls to this class will not be performed instantly, but will -be performed asynchronously, once the EventLoop reports the stream resource is -ready to accept data. -For this, it uses an in-memory buffer string to collect all outstanding writes. -This buffer has a soft-limit applied which defines how much data it is willing -to accept before the caller SHOULD stop sending further data. - -This class takes another optional `WritableStreamInterface|null $buffer` parameter -that controls this write behavior of this stream. -You can use a `null` value here in order to apply its default value. -This value SHOULD NOT be changed unless you know what you're doing. - -If you want to change the write buffer soft limit, you can pass an instance of -[`WritableResourceStream`](#writableresourcestream) like this: - -```php -$conn = stream_socket_client('tcp://google.com:80'); -$buffer = new WritableResourceStream($conn, $loop, 8192); -$stream = new DuplexResourceStream($conn, $loop, null, $buffer); -``` - -See also [`WritableResourceStream`](#writableresourcestream) for more details. - -### ThroughStream - -The `ThroughStream` implements the -[`DuplexStreamInterface`](#duplexstreaminterface) and will simply pass any data -you write to it through to its readable end. - -```php -$through = new ThroughStream(); -$through->on('data', $this->expectCallableOnceWith('hello')); - -$through->write('hello'); -``` - -Similarly, the [`end()` method](#end) will end the stream and emit an -[`end` event](#end-event) and then [`close()`](#close-1) the stream. -The [`close()` method](#close-1) will close the stream and emit a -[`close` event](#close-event). -Accordingly, this is can also be used in a [`pipe()`](#pipe) context like this: - -```php -$through = new ThroughStream(); -$source->pipe($through)->pipe($dest); -``` - -Optionally, its constructor accepts any callable function which will then be -used to *filter* any data written to it. This function receives a single data -argument as passed to the writable side and must return the data as it will be -passed to its readable end: - -```php -$through = new ThroughStream('strtoupper'); -$source->pipe($through)->pipe($dest); -``` - -Note that this class makes no assumptions about any data types. This can be -used to convert data, for example for transforming any structured data into -a newline-delimited JSON (NDJSON) stream like this: - -```php -$through = new ThroughStream(function ($data) { - return json_encode($data) . PHP_EOL; -}); -$through->on('data', $this->expectCallableOnceWith("[2, true]\n")); - -$through->write(array(2, true)); -``` - -The callback function is allowed to throw an `Exception`. In this case, -the stream will emit an `error` event and then [`close()`](#close-1) the stream. - -```php -$through = new ThroughStream(function ($data) { - if (!is_string($data)) { - throw new \UnexpectedValueException('Only strings allowed'); - } - return $data; -}); -$through->on('error', $this->expectCallableOnce())); -$through->on('close', $this->expectCallableOnce())); -$through->on('data', $this->expectCallableNever())); - -$through->write(2); -``` - -### CompositeStream - -The `CompositeStream` implements the -[`DuplexStreamInterface`](#duplexstreaminterface) and can be used to create a -single duplex stream from two individual streams implementing -[`ReadableStreamInterface`](#readablestreaminterface) and -[`WritableStreamInterface`](#writablestreaminterface) respectively. - -This is useful for some APIs which may require a single -[`DuplexStreamInterface`](#duplexstreaminterface) or simply because it's often -more convenient to work with a single stream instance like this: - -```php -$stdin = new ReadableResourceStream(STDIN, $loop); -$stdout = new WritableResourceStream(STDOUT, $loop); - -$stdio = new CompositeStream($stdin, $stdout); - -$stdio->on('data', function ($chunk) use ($stdio) { - $stdio->write('You said: ' . $chunk); -}); -``` - -This is a well-behaving stream which forwards all stream events from the -underlying streams and forwards all streams calls to the underlying streams. - -If you `write()` to the duplex stream, it will simply `write()` to the -writable side and return its status. - -If you `end()` the duplex stream, it will `end()` the writable side and will -`pause()` the readable side. - -If you `close()` the duplex stream, both input streams will be closed. -If either of the two input streams emits a `close` event, the duplex stream -will also close. -If either of the two input streams is already closed while constructing the -duplex stream, it will `close()` the other side and return a closed stream. - -## Usage - -The following example can be used to pipe the contents of a source file into -a destination file without having to ever read the whole file into memory: - -```php -$loop = new React\EventLoop\StreamSelectLoop; - -$source = new React\Stream\ReadableResourceStream(fopen('source.txt', 'r'), $loop); -$dest = new React\Stream\WritableResourceStream(fopen('destination.txt', 'w'), $loop); - -$source->pipe($dest); - -$loop->run(); -``` - -> Note that this example uses `fopen()` for illustration purposes only. - This should not be used in a truly async program because the filesystem is - inherently blocking and each call could potentially take several seconds. - See also [creating streams](#creating-streams) for more sophisticated - examples. - -## Install - -The recommended way to install this library is [through Composer](https://getcomposer.org). -[New to Composer?](https://getcomposer.org/doc/00-intro.md) - -This will install the latest supported version: - -```bash -$ composer require react/stream:^0.7.7 -``` - -See also the [CHANGELOG](CHANGELOG.md) for details about version upgrades. - -This project aims to run on any platform and thus does not require any PHP -extensions and supports running on legacy PHP 5.3 through current PHP 7+ and HHVM. -It's *highly recommended to use PHP 7+* for this project due to its vast -performance improvements. - -## Tests - -To run the test suite, you first need to clone this repo and then install all -dependencies [through Composer](https://getcomposer.org): - -```bash -$ composer install -``` - -To run the test suite, go to the project root and run: - -```bash -$ php vendor/bin/phpunit -``` - -The test suite also contains a number of functional integration tests that rely -on a stable internet connection. -If you do not want to run these, they can simply be skipped like this: - -```bash -$ php vendor/bin/phpunit --exclude-group internet -``` - -## License - -MIT, see [LICENSE file](LICENSE). - -## More - -* See [creating streams](#creating-streams) for more information on how streams - are created in real-world applications. -* See our [users wiki](https://github.com/reactphp/react/wiki/Users) and the - [dependents on Packagist](https://packagist.org/packages/react/stream/dependents) - for a list of packages that use streams in real-world applications. diff --git a/assets/php/vendor/react/stream/composer.json b/assets/php/vendor/react/stream/composer.json deleted file mode 100755 index f6faa66..0000000 --- a/assets/php/vendor/react/stream/composer.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "name": "react/stream", - "description": "Event-driven readable and writable streams for non-blocking I/O in ReactPHP", - "keywords": ["event-driven", "readable", "writable", "stream", "non-blocking", "io", "pipe", "ReactPHP"], - "license": "MIT", - "require": { - "php": ">=5.3.8", - "react/event-loop": "^1.0 || ^0.5 || ^0.4 || ^0.3.5", - "evenement/evenement": "^3.0 || ^2.0 || ^1.0" - }, - "require-dev": { - "phpunit/phpunit": "^6.4 || ^5.7 || ^4.8.35", - "clue/stream-filter": "~1.2" - }, - "autoload": { - "psr-4": { - "React\\Stream\\": "src" - } - }, - "autoload-dev": { - "psr-4": { - "React\\Tests\\Stream\\": "tests" - } - } -} diff --git a/assets/php/vendor/react/stream/examples/01-http.php b/assets/php/vendor/react/stream/examples/01-http.php deleted file mode 100755 index 3687f7c..0000000 --- a/assets/php/vendor/react/stream/examples/01-http.php +++ /dev/null @@ -1,40 +0,0 @@ -<?php - -// Simple plaintext HTTP client example (for illustration purposes only). -// This shows how a plaintext TCP/IP connection is established to then send an -// application level protocol message (HTTP). -// Real applications should use react/http-client instead! -// -// This simple example only accepts an optional host parameter to send the -// request to. -// -// $ php examples/01-http.php -// $ php examples/01-http.php reactphp.org - -use React\EventLoop\Factory; -use React\Stream\DuplexResourceStream; - -require __DIR__ . '/../vendor/autoload.php'; - -$host = isset($argv[1]) ? $argv[1] : 'www.google.com'; - -// connect to tcp://www.google.com:80 (blocking call!) -// for illustration purposes only, should use react/http-client or react/socket instead! -$resource = stream_socket_client('tcp://' . $host . ':80'); -if (!$resource) { - exit(1); -} - -$loop = Factory::create(); -$stream = new DuplexResourceStream($resource, $loop); - -$stream->on('data', function ($chunk) { - echo $chunk; -}); -$stream->on('close', function () { - echo '[CLOSED]' . PHP_EOL; -}); - -$stream->write("GET / HTTP/1.0\r\nHost: $host\r\n\r\n"); - -$loop->run(); diff --git a/assets/php/vendor/react/stream/examples/02-https.php b/assets/php/vendor/react/stream/examples/02-https.php deleted file mode 100755 index 163f7c8..0000000 --- a/assets/php/vendor/react/stream/examples/02-https.php +++ /dev/null @@ -1,40 +0,0 @@ -<?php - -// Simple secure HTTPS client example (for illustration purposes only). -// This shows how a secure TLS connection is established to then send an -// application level protocol message (HTTP). -// Real applications should use react/http-client instead! -// -// This simple example only accepts an optional host parameter to send the -// request to. -// -// $ php examples/02-https.php -// $ php examples/02-https.php reactphp.org - -use React\EventLoop\Factory; -use React\Stream\DuplexResourceStream; - -require __DIR__ . '/../vendor/autoload.php'; - -$host = isset($argv[1]) ? $argv[1] : 'www.google.com'; - -// connect to tls://www.google.com:443 (blocking call!) -// for illustration purposes only, should use react/http-client or react/socket instead! -$resource = stream_socket_client('tls://' . $host . ':443'); -if (!$resource) { - exit(1); -} - -$loop = Factory::create(); -$stream = new DuplexResourceStream($resource, $loop); - -$stream->on('data', function ($chunk) { - echo $chunk; -}); -$stream->on('close', function () { - echo '[CLOSED]' . PHP_EOL; -}); - -$stream->write("GET / HTTP/1.0\r\nHost: $host\r\n\r\n"); - -$loop->run(); diff --git a/assets/php/vendor/react/stream/examples/11-cat.php b/assets/php/vendor/react/stream/examples/11-cat.php deleted file mode 100755 index 90fadc0..0000000 --- a/assets/php/vendor/react/stream/examples/11-cat.php +++ /dev/null @@ -1,28 +0,0 @@ -<?php - -// Simple example piping everything from STDIN to STDOUT. -// This allows you to output everything you type on your keyboard or to redirect -// the pipes to show contents of files and other streams. -// -// $ php examples/11-cat.php -// $ php examples/11-cat.php < README.md -// $ echo hello | php examples/11-cat.php - -use React\EventLoop\Factory; -use React\Stream\ReadableResourceStream; -use React\Stream\WritableResourceStream; - -require __DIR__ . '/../vendor/autoload.php'; - -if (DIRECTORY_SEPARATOR === '\\') { - fwrite(STDERR, 'Non-blocking console I/O not supported on Microsoft Windows' . PHP_EOL); - exit(1); -} - -$loop = Factory::create(); - -$stdout = new WritableResourceStream(STDOUT, $loop); -$stdin = new ReadableResourceStream(STDIN, $loop); -$stdin->pipe($stdout); - -$loop->run(); diff --git a/assets/php/vendor/react/stream/examples/91-benchmark-throughput.php b/assets/php/vendor/react/stream/examples/91-benchmark-throughput.php deleted file mode 100755 index ecf695c..0000000 --- a/assets/php/vendor/react/stream/examples/91-benchmark-throughput.php +++ /dev/null @@ -1,62 +0,0 @@ -<?php - -// Benchmark to measure throughput performance piping an input stream to an output stream. -// This allows you to get an idea of how fast stream processing with PHP can be -// and also to play around with differnt types of input and output streams. -// -// This example accepts a number of parameters to control the timeout (-t 1), -// the input file (-i /dev/zero) and the output file (-o /dev/null). -// -// $ php examples/91-benchmark-throughput.php -// $ php examples/91-benchmark-throughput.php -t 10 -o zero.bin -// $ php examples/91-benchmark-throughput.php -t 60 -i zero.bin - -require __DIR__ . '/../vendor/autoload.php'; - -if (DIRECTORY_SEPARATOR === '\\') { - fwrite(STDERR, 'Non-blocking console I/O not supported on Microsoft Windows' . PHP_EOL); - exit(1); -} - -$args = getopt('i:o:t:'); -$if = isset($args['i']) ? $args['i'] : '/dev/zero'; -$of = isset($args['o']) ? $args['o'] : '/dev/null'; -$t = isset($args['t']) ? $args['t'] : 1; - -// passing file descriptors requires mapping paths (https://bugs.php.net/bug.php?id=53465) -$if = str_replace('/dev/fd/', 'php://fd/', $if); -$of = str_replace('/dev/fd/', 'php://fd/', $of); - -$loop = new React\EventLoop\StreamSelectLoop(); - -// setup information stream -$info = new React\Stream\WritableResourceStream(STDERR, $loop); -if (extension_loaded('xdebug')) { - $info->write('NOTICE: The "xdebug" extension is loaded, this has a major impact on performance.' . PHP_EOL); -} -$info->write('piping from ' . $if . ' to ' . $of . ' (for max ' . $t . ' second(s)) ...'. PHP_EOL); - -// setup input and output streams and pipe inbetween -$fh = fopen($if, 'r'); -$in = new React\Stream\ReadableResourceStream($fh, $loop); -$out = new React\Stream\WritableResourceStream(fopen($of, 'w'), $loop); -$in->pipe($out); - -// stop input stream in $t seconds -$start = microtime(true); -$timeout = $loop->addTimer($t, function () use ($in, &$bytes) { - $in->close(); -}); - -// print stream position once stream closes -$in->on('close', function () use ($fh, $start, $loop, $timeout, $info) { - $t = microtime(true) - $start; - $loop->cancelTimer($timeout); - - $bytes = ftell($fh); - - $info->write('read ' . $bytes . ' byte(s) in ' . round($t, 3) . ' second(s) => ' . round($bytes / 1024 / 1024 / $t, 1) . ' MiB/s' . PHP_EOL); - $info->write('peak memory usage of ' . round(memory_get_peak_usage(true) / 1024 / 1024, 1) . ' MiB' . PHP_EOL); -}); - -$loop->run(); diff --git a/assets/php/vendor/react/stream/phpunit.xml.dist b/assets/php/vendor/react/stream/phpunit.xml.dist deleted file mode 100755 index 13d3fab..0000000 --- a/assets/php/vendor/react/stream/phpunit.xml.dist +++ /dev/null @@ -1,25 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> - -<phpunit backupGlobals="false" - backupStaticAttributes="false" - colors="true" - convertErrorsToExceptions="true" - convertNoticesToExceptions="true" - convertWarningsToExceptions="true" - processIsolation="false" - stopOnFailure="false" - syntaxCheck="false" - bootstrap="vendor/autoload.php" -> - <testsuites> - <testsuite name="React Test Suite"> - <directory>./tests/</directory> - </testsuite> - </testsuites> - - <filter> - <whitelist> - <directory>./src/</directory> - </whitelist> - </filter> -</phpunit> diff --git a/assets/php/vendor/react/stream/src/CompositeStream.php b/assets/php/vendor/react/stream/src/CompositeStream.php deleted file mode 100755 index 153f2a3..0000000 --- a/assets/php/vendor/react/stream/src/CompositeStream.php +++ /dev/null @@ -1,82 +0,0 @@ -<?php - -namespace React\Stream; - -use Evenement\EventEmitter; - -final class CompositeStream extends EventEmitter implements DuplexStreamInterface -{ - private $readable; - private $writable; - private $closed = false; - - public function __construct(ReadableStreamInterface $readable, WritableStreamInterface $writable) - { - $this->readable = $readable; - $this->writable = $writable; - - if (!$readable->isReadable() || !$writable->isWritable()) { - return $this->close(); - } - - Util::forwardEvents($this->readable, $this, array('data', 'end', 'error')); - Util::forwardEvents($this->writable, $this, array('drain', 'error', 'pipe')); - - $this->readable->on('close', array($this, 'close')); - $this->writable->on('close', array($this, 'close')); - } - - public function isReadable() - { - return $this->readable->isReadable(); - } - - public function pause() - { - $this->readable->pause(); - } - - public function resume() - { - if (!$this->writable->isWritable()) { - return; - } - - $this->readable->resume(); - } - - public function pipe(WritableStreamInterface $dest, array $options = array()) - { - return Util::pipe($this, $dest, $options); - } - - public function isWritable() - { - return $this->writable->isWritable(); - } - - public function write($data) - { - return $this->writable->write($data); - } - - public function end($data = null) - { - $this->readable->pause(); - $this->writable->end($data); - } - - public function close() - { - if ($this->closed) { - return; - } - - $this->closed = true; - $this->readable->close(); - $this->writable->close(); - - $this->emit('close'); - $this->removeAllListeners(); - } -} diff --git a/assets/php/vendor/react/stream/src/DuplexResourceStream.php b/assets/php/vendor/react/stream/src/DuplexResourceStream.php deleted file mode 100755 index 982ebb0..0000000 --- a/assets/php/vendor/react/stream/src/DuplexResourceStream.php +++ /dev/null @@ -1,224 +0,0 @@ -<?php - -namespace React\Stream; - -use Evenement\EventEmitter; -use React\EventLoop\LoopInterface; -use InvalidArgumentException; - -final class DuplexResourceStream extends EventEmitter implements DuplexStreamInterface -{ - private $stream; - private $loop; - - /** - * Controls the maximum buffer size in bytes to read at once from the stream. - * - * This can be a positive number which means that up to X bytes will be read - * at once from the underlying stream resource. Note that the actual number - * of bytes read may be lower if the stream resource has less than X bytes - * currently available. - * - * This can be `-1` which means read everything available from the - * underlying stream resource. - * This should read until the stream resource is not readable anymore - * (i.e. underlying buffer drained), note that this does not neccessarily - * mean it reached EOF. - * - * @var int - */ - private $bufferSize; - private $buffer; - - private $readable = true; - private $writable = true; - private $closing = false; - private $listening = false; - - public function __construct($stream, LoopInterface $loop, $readChunkSize = null, WritableStreamInterface $buffer = null) - { - if (!is_resource($stream) || get_resource_type($stream) !== "stream") { - throw new InvalidArgumentException('First parameter must be a valid stream resource'); - } - - // ensure resource is opened for reading and wrting (fopen mode must contain "+") - $meta = stream_get_meta_data($stream); - if (isset($meta['mode']) && $meta['mode'] !== '' && strpos($meta['mode'], '+') === false) { - throw new InvalidArgumentException('Given stream resource is not opened in read and write mode'); - } - - // this class relies on non-blocking I/O in order to not interrupt the event loop - // e.g. pipes on Windows do not support this: https://bugs.php.net/bug.php?id=47918 - if (stream_set_blocking($stream, 0) !== true) { - throw new \RuntimeException('Unable to set stream resource to non-blocking mode'); - } - - // Use unbuffered read operations on the underlying stream resource. - // Reading chunks from the stream may otherwise leave unread bytes in - // PHP's stream buffers which some event loop implementations do not - // trigger events on (edge triggered). - // This does not affect the default event loop implementation (level - // triggered), so we can ignore platforms not supporting this (HHVM). - // Pipe streams (such as STDIN) do not seem to require this and legacy - // PHP versions cause SEGFAULTs on unbuffered pipe streams, so skip this. - if (function_exists('stream_set_read_buffer') && !$this->isLegacyPipe($stream)) { - stream_set_read_buffer($stream, 0); - } - - if ($buffer === null) { - $buffer = new WritableResourceStream($stream, $loop); - } - - $this->stream = $stream; - $this->loop = $loop; - $this->bufferSize = ($readChunkSize === null) ? 65536 : (int)$readChunkSize; - $this->buffer = $buffer; - - $that = $this; - - $this->buffer->on('error', function ($error) use ($that) { - $that->emit('error', array($error)); - }); - - $this->buffer->on('close', array($this, 'close')); - - $this->buffer->on('drain', function () use ($that) { - $that->emit('drain'); - }); - - $this->resume(); - } - - public function isReadable() - { - return $this->readable; - } - - public function isWritable() - { - return $this->writable; - } - - public function pause() - { - if ($this->listening) { - $this->loop->removeReadStream($this->stream); - $this->listening = false; - } - } - - public function resume() - { - if (!$this->listening && $this->readable) { - $this->loop->addReadStream($this->stream, array($this, 'handleData')); - $this->listening = true; - } - } - - public function write($data) - { - if (!$this->writable) { - return false; - } - - return $this->buffer->write($data); - } - - public function close() - { - if (!$this->writable && !$this->closing) { - return; - } - - $this->closing = false; - - $this->readable = false; - $this->writable = false; - - $this->emit('close'); - $this->pause(); - $this->buffer->close(); - $this->removeAllListeners(); - - if (is_resource($this->stream)) { - fclose($this->stream); - } - } - - public function end($data = null) - { - if (!$this->writable) { - return; - } - - $this->closing = true; - - $this->readable = false; - $this->writable = false; - $this->pause(); - - $this->buffer->end($data); - } - - public function pipe(WritableStreamInterface $dest, array $options = array()) - { - return Util::pipe($this, $dest, $options); - } - - /** @internal */ - public function handleData($stream) - { - $error = null; - set_error_handler(function ($errno, $errstr, $errfile, $errline) use (&$error) { - $error = new \ErrorException( - $errstr, - 0, - $errno, - $errfile, - $errline - ); - }); - - $data = stream_get_contents($stream, $this->bufferSize); - - restore_error_handler(); - - if ($error !== null) { - $this->emit('error', array(new \RuntimeException('Unable to read from stream: ' . $error->getMessage(), 0, $error))); - $this->close(); - return; - } - - if ($data !== '') { - $this->emit('data', array($data)); - } else{ - // no data read => we reached the end and close the stream - $this->emit('end'); - $this->close(); - } - } - - /** - * Returns whether this is a pipe resource in a legacy environment - * - * This works around a legacy PHP bug (#61019) that was fixed in PHP 5.4.28+ - * and PHP 5.5.12+ and newer. - * - * @param resource $resource - * @return bool - * @link https://github.com/reactphp/child-process/issues/40 - * - * @codeCoverageIgnore - */ - private function isLegacyPipe($resource) - { - if (PHP_VERSION_ID < 50428 || (PHP_VERSION_ID >= 50500 && PHP_VERSION_ID < 50512)) { - $meta = stream_get_meta_data($resource); - - if (isset($meta['stream_type']) && $meta['stream_type'] === 'STDIO') { - return true; - } - } - return false; - } -} diff --git a/assets/php/vendor/react/stream/src/DuplexStreamInterface.php b/assets/php/vendor/react/stream/src/DuplexStreamInterface.php deleted file mode 100755 index 631ce31..0000000 --- a/assets/php/vendor/react/stream/src/DuplexStreamInterface.php +++ /dev/null @@ -1,39 +0,0 @@ -<?php - -namespace React\Stream; - -/** - * The `DuplexStreamInterface` is responsible for providing an interface for - * duplex streams (both readable and writable). - * - * It builds on top of the existing interfaces for readable and writable streams - * and follows the exact same method and event semantics. - * If you're new to this concept, you should look into the - * `ReadableStreamInterface` and `WritableStreamInterface` first. - * - * Besides defining a few methods, this interface also implements the - * `EventEmitterInterface` which allows you to react to the same events defined - * on the `ReadbleStreamInterface` and `WritableStreamInterface`. - * - * The event callback functions MUST be a valid `callable` that obeys strict - * parameter definitions and MUST accept event parameters exactly as documented. - * The event callback functions MUST NOT throw an `Exception`. - * The return value of the event callback functions will be ignored and has no - * effect, so for performance reasons you're recommended to not return any - * excessive data structures. - * - * Every implementation of this interface MUST follow these event semantics in - * order to be considered a well-behaving stream. - * - * > Note that higher-level implementations of this interface may choose to - * define additional events with dedicated semantics not defined as part of - * this low-level stream specification. Conformance with these event semantics - * is out of scope for this interface, so you may also have to refer to the - * documentation of such a higher-level implementation. - * - * @see ReadableStreamInterface - * @see WritableStreamInterface - */ -interface DuplexStreamInterface extends ReadableStreamInterface, WritableStreamInterface -{ -} diff --git a/assets/php/vendor/react/stream/src/ReadableResourceStream.php b/assets/php/vendor/react/stream/src/ReadableResourceStream.php deleted file mode 100755 index 015a96b..0000000 --- a/assets/php/vendor/react/stream/src/ReadableResourceStream.php +++ /dev/null @@ -1,177 +0,0 @@ -<?php - -namespace React\Stream; - -use Evenement\EventEmitter; -use React\EventLoop\LoopInterface; -use InvalidArgumentException; - -final class ReadableResourceStream extends EventEmitter implements ReadableStreamInterface -{ - /** - * @var resource - */ - private $stream; - - private $loop; - - /** - * Controls the maximum buffer size in bytes to read at once from the stream. - * - * This value SHOULD NOT be changed unless you know what you're doing. - * - * This can be a positive number which means that up to X bytes will be read - * at once from the underlying stream resource. Note that the actual number - * of bytes read may be lower if the stream resource has less than X bytes - * currently available. - * - * This can be `-1` which means read everything available from the - * underlying stream resource. - * This should read until the stream resource is not readable anymore - * (i.e. underlying buffer drained), note that this does not neccessarily - * mean it reached EOF. - * - * @var int - */ - private $bufferSize; - - private $closed = false; - private $listening = false; - - public function __construct($stream, LoopInterface $loop, $readChunkSize = null) - { - if (!is_resource($stream) || get_resource_type($stream) !== "stream") { - throw new InvalidArgumentException('First parameter must be a valid stream resource'); - } - - // ensure resource is opened for reading (fopen mode must contain "r" or "+") - $meta = stream_get_meta_data($stream); - if (isset($meta['mode']) && $meta['mode'] !== '' && strpos($meta['mode'], 'r') === strpos($meta['mode'], '+')) { - throw new InvalidArgumentException('Given stream resource is not opened in read mode'); - } - - // this class relies on non-blocking I/O in order to not interrupt the event loop - // e.g. pipes on Windows do not support this: https://bugs.php.net/bug.php?id=47918 - if (stream_set_blocking($stream, 0) !== true) { - throw new \RuntimeException('Unable to set stream resource to non-blocking mode'); - } - - // Use unbuffered read operations on the underlying stream resource. - // Reading chunks from the stream may otherwise leave unread bytes in - // PHP's stream buffers which some event loop implementations do not - // trigger events on (edge triggered). - // This does not affect the default event loop implementation (level - // triggered), so we can ignore platforms not supporting this (HHVM). - // Pipe streams (such as STDIN) do not seem to require this and legacy - // PHP versions cause SEGFAULTs on unbuffered pipe streams, so skip this. - if (function_exists('stream_set_read_buffer') && !$this->isLegacyPipe($stream)) { - stream_set_read_buffer($stream, 0); - } - - $this->stream = $stream; - $this->loop = $loop; - $this->bufferSize = ($readChunkSize === null) ? 65536 : (int)$readChunkSize; - - $this->resume(); - } - - public function isReadable() - { - return !$this->closed; - } - - public function pause() - { - if ($this->listening) { - $this->loop->removeReadStream($this->stream); - $this->listening = false; - } - } - - public function resume() - { - if (!$this->listening && !$this->closed) { - $this->loop->addReadStream($this->stream, array($this, 'handleData')); - $this->listening = true; - } - } - - public function pipe(WritableStreamInterface $dest, array $options = array()) - { - return Util::pipe($this, $dest, $options); - } - - public function close() - { - if ($this->closed) { - return; - } - - $this->closed = true; - - $this->emit('close'); - $this->pause(); - $this->removeAllListeners(); - - if (is_resource($this->stream)) { - fclose($this->stream); - } - } - - /** @internal */ - public function handleData() - { - $error = null; - set_error_handler(function ($errno, $errstr, $errfile, $errline) use (&$error) { - $error = new \ErrorException( - $errstr, - 0, - $errno, - $errfile, - $errline - ); - }); - - $data = stream_get_contents($this->stream, $this->bufferSize); - - restore_error_handler(); - - if ($error !== null) { - $this->emit('error', array(new \RuntimeException('Unable to read from stream: ' . $error->getMessage(), 0, $error))); - $this->close(); - return; - } - - if ($data !== '') { - $this->emit('data', array($data)); - } else{ - // no data read => we reached the end and close the stream - $this->emit('end'); - $this->close(); - } - } - - /** - * Returns whether this is a pipe resource in a legacy environment - * - * This works around a legacy PHP bug (#61019) that was fixed in PHP 5.4.28+ - * and PHP 5.5.12+ and newer. - * - * @param resource $resource - * @return bool - * @link https://github.com/reactphp/child-process/issues/40 - * - * @codeCoverageIgnore - */ - private function isLegacyPipe($resource) - { - if (PHP_VERSION_ID < 50428 || (PHP_VERSION_ID >= 50500 && PHP_VERSION_ID < 50512)) { - $meta = stream_get_meta_data($resource); - - if (isset($meta['stream_type']) && $meta['stream_type'] === 'STDIO') { - return true; - } - } - return false; - } -} diff --git a/assets/php/vendor/react/stream/src/ReadableStreamInterface.php b/assets/php/vendor/react/stream/src/ReadableStreamInterface.php deleted file mode 100755 index 2b4c3d0..0000000 --- a/assets/php/vendor/react/stream/src/ReadableStreamInterface.php +++ /dev/null @@ -1,362 +0,0 @@ -<?php - -namespace React\Stream; - -use Evenement\EventEmitterInterface; - -/** - * The `ReadableStreamInterface` is responsible for providing an interface for - * read-only streams and the readable side of duplex streams. - * - * Besides defining a few methods, this interface also implements the - * `EventEmitterInterface` which allows you to react to certain events: - * - * data event: - * The `data` event will be emitted whenever some data was read/received - * from this source stream. - * The event receives a single mixed argument for incoming data. - * - * ```php - * $stream->on('data', function ($data) { - * echo $data; - * }); - * ``` - * - * This event MAY be emitted any number of times, which may be zero times if - * this stream does not send any data at all. - * It SHOULD not be emitted after an `end` or `close` event. - * - * The given `$data` argument may be of mixed type, but it's usually - * recommended it SHOULD be a `string` value or MAY use a type that allows - * representation as a `string` for maximum compatibility. - * - * Many common streams (such as a TCP/IP connection or a file-based stream) - * will emit the raw (binary) payload data that is received over the wire as - * chunks of `string` values. - * - * Due to the stream-based nature of this, the sender may send any number - * of chunks with varying sizes. There are no guarantees that these chunks - * will be received with the exact same framing the sender intended to send. - * In other words, many lower-level protocols (such as TCP/IP) transfer the - * data in chunks that may be anywhere between single-byte values to several - * dozens of kilobytes. You may want to apply a higher-level protocol to - * these low-level data chunks in order to achieve proper message framing. - * - * end event: - * The `end` event will be emitted once the source stream has successfully - * reached the end of the stream (EOF). - * - * ```php - * $stream->on('end', function () { - * echo 'END'; - * }); - * ``` - * - * This event SHOULD be emitted once or never at all, depending on whether - * a successful end was detected. - * It SHOULD NOT be emitted after a previous `end` or `close` event. - * It MUST NOT be emitted if the stream closes due to a non-successful - * end, such as after a previous `error` event. - * - * After the stream is ended, it MUST switch to non-readable mode, - * see also `isReadable()`. - * - * This event will only be emitted if the *end* was reached successfully, - * not if the stream was interrupted by an unrecoverable error or explicitly - * closed. Not all streams know this concept of a "successful end". - * Many use-cases involve detecting when the stream closes (terminates) - * instead, in this case you should use the `close` event. - * After the stream emits an `end` event, it SHOULD usually be followed by a - * `close` event. - * - * Many common streams (such as a TCP/IP connection or a file-based stream) - * will emit this event if either the remote side closes the connection or - * a file handle was successfully read until reaching its end (EOF). - * - * Note that this event should not be confused with the `end()` method. - * This event defines a successful end *reading* from a source stream, while - * the `end()` method defines *writing* a successful end to a destination - * stream. - * - * error event: - * The `error` event will be emitted once a fatal error occurs, usually while - * trying to read from this stream. - * The event receives a single `Exception` argument for the error instance. - * - * ```php - * $stream->on('error', function (Exception $e) { - * echo 'Error: ' . $e->getMessage() . PHP_EOL; - * }); - * ``` - * - * This event SHOULD be emitted once the stream detects a fatal error, such - * as a fatal transmission error or after an unexpected `data` or premature - * `end` event. - * It SHOULD NOT be emitted after a previous `error`, `end` or `close` event. - * It MUST NOT be emitted if this is not a fatal error condition, such as - * a temporary network issue that did not cause any data to be lost. - * - * After the stream errors, it MUST close the stream and SHOULD thus be - * followed by a `close` event and then switch to non-readable mode, see - * also `close()` and `isReadable()`. - * - * Many common streams (such as a TCP/IP connection or a file-based stream) - * only deal with data transmission and do not make assumption about data - * boundaries (such as unexpected `data` or premature `end` events). - * In other words, many lower-level protocols (such as TCP/IP) may choose - * to only emit this for a fatal transmission error once and will then - * close (terminate) the stream in response. - * - * If this stream is a `DuplexStreamInterface`, you should also notice - * how the writable side of the stream also implements an `error` event. - * In other words, an error may occur while either reading or writing the - * stream which should result in the same error processing. - * - * close event: - * The `close` event will be emitted once the stream closes (terminates). - * - * ```php - * $stream->on('close', function () { - * echo 'CLOSED'; - * }); - * ``` - * - * This event SHOULD be emitted once or never at all, depending on whether - * the stream ever terminates. - * It SHOULD NOT be emitted after a previous `close` event. - * - * After the stream is closed, it MUST switch to non-readable mode, - * see also `isReadable()`. - * - * Unlike the `end` event, this event SHOULD be emitted whenever the stream - * closes, irrespective of whether this happens implicitly due to an - * unrecoverable error or explicitly when either side closes the stream. - * If you only want to detect a *successful* end, you should use the `end` - * event instead. - * - * Many common streams (such as a TCP/IP connection or a file-based stream) - * will likely choose to emit this event after reading a *successful* `end` - * event or after a fatal transmission `error` event. - * - * If this stream is a `DuplexStreamInterface`, you should also notice - * how the writable side of the stream also implements a `close` event. - * In other words, after receiving this event, the stream MUST switch into - * non-writable AND non-readable mode, see also `isWritable()`. - * Note that this event should not be confused with the `end` event. - * - * The event callback functions MUST be a valid `callable` that obeys strict - * parameter definitions and MUST accept event parameters exactly as documented. - * The event callback functions MUST NOT throw an `Exception`. - * The return value of the event callback functions will be ignored and has no - * effect, so for performance reasons you're recommended to not return any - * excessive data structures. - * - * Every implementation of this interface MUST follow these event semantics in - * order to be considered a well-behaving stream. - * - * > Note that higher-level implementations of this interface may choose to - * define additional events with dedicated semantics not defined as part of - * this low-level stream specification. Conformance with these event semantics - * is out of scope for this interface, so you may also have to refer to the - * documentation of such a higher-level implementation. - * - * @see EventEmitterInterface - */ -interface ReadableStreamInterface extends EventEmitterInterface -{ - /** - * Checks whether this stream is in a readable state (not closed already). - * - * This method can be used to check if the stream still accepts incoming - * data events or if it is ended or closed already. - * Once the stream is non-readable, no further `data` or `end` events SHOULD - * be emitted. - * - * ```php - * assert($stream->isReadable() === false); - * - * $stream->on('data', assertNeverCalled()); - * $stream->on('end', assertNeverCalled()); - * ``` - * - * A successfully opened stream always MUST start in readable mode. - * - * Once the stream ends or closes, it MUST switch to non-readable mode. - * This can happen any time, explicitly through `close()` or - * implicitly due to a remote close or an unrecoverable transmission error. - * Once a stream has switched to non-readable mode, it MUST NOT transition - * back to readable mode. - * - * If this stream is a `DuplexStreamInterface`, you should also notice - * how the writable side of the stream also implements an `isWritable()` - * method. Unless this is a half-open duplex stream, they SHOULD usually - * have the same return value. - * - * @return bool - */ - public function isReadable(); - - /** - * Pauses reading incoming data events. - * - * Removes the data source file descriptor from the event loop. This - * allows you to throttle incoming data. - * - * Unless otherwise noted, a successfully opened stream SHOULD NOT start - * in paused state. - * - * Once the stream is paused, no futher `data` or `end` events SHOULD - * be emitted. - * - * ```php - * $stream->pause(); - * - * $stream->on('data', assertShouldNeverCalled()); - * $stream->on('end', assertShouldNeverCalled()); - * ``` - * - * This method is advisory-only, though generally not recommended, the - * stream MAY continue emitting `data` events. - * - * You can continue processing events by calling `resume()` again. - * - * Note that both methods can be called any number of times, in particular - * calling `pause()` more than once SHOULD NOT have any effect. - * - * @see self::resume() - * @return void - */ - public function pause(); - - /** - * Resumes reading incoming data events. - * - * Re-attach the data source after a previous `pause()`. - * - * ```php - * $stream->pause(); - * - * $loop->addTimer(1.0, function () use ($stream) { - * $stream->resume(); - * }); - * ``` - * - * Note that both methods can be called any number of times, in particular - * calling `resume()` without a prior `pause()` SHOULD NOT have any effect. - * - * @see self::pause() - * @return void - */ - public function resume(); - - /** - * Pipes all the data from this readable source into the given writable destination. - * - * Automatically sends all incoming data to the destination. - * Automatically throttles the source based on what the destination can handle. - * - * ```php - * $source->pipe($dest); - * ``` - * - * Similarly, you can also pipe an instance implementing `DuplexStreamInterface` - * into itself in order to write back all the data that is received. - * This may be a useful feature for a TCP/IP echo service: - * - * ```php - * $connection->pipe($connection); - * ``` - * - * This method returns the destination stream as-is, which can be used to - * set up chains of piped streams: - * - * ```php - * $source->pipe($decodeGzip)->pipe($filterBadWords)->pipe($dest); - * ``` - * - * By default, this will call `end()` on the destination stream once the - * source stream emits an `end` event. This can be disabled like this: - * - * ```php - * $source->pipe($dest, array('end' => false)); - * ``` - * - * Note that this only applies to the `end` event. - * If an `error` or explicit `close` event happens on the source stream, - * you'll have to manually close the destination stream: - * - * ```php - * $source->pipe($dest); - * $source->on('close', function () use ($dest) { - * $dest->end('BYE!'); - * }); - * ``` - * - * If the source stream is not readable (closed state), then this is a NO-OP. - * - * ```php - * $source->close(); - * $source->pipe($dest); // NO-OP - * ``` - * - * If the destinantion stream is not writable (closed state), then this will simply - * throttle (pause) the source stream: - * - * ```php - * $dest->close(); - * $source->pipe($dest); // calls $source->pause() - * ``` - * - * Similarly, if the destination stream is closed while the pipe is still - * active, it will also throttle (pause) the source stream: - * - * ```php - * $source->pipe($dest); - * $dest->close(); // calls $source->pause() - * ``` - * - * Once the pipe is set up successfully, the destination stream MUST emit - * a `pipe` event with this source stream an event argument. - * - * @param WritableStreamInterface $dest - * @param array $options - * @return WritableStreamInterface $dest stream as-is - */ - public function pipe(WritableStreamInterface $dest, array $options = array()); - - /** - * Closes the stream (forcefully). - * - * This method can be used to (forcefully) close the stream. - * - * ```php - * $stream->close(); - * ``` - * - * Once the stream is closed, it SHOULD emit a `close` event. - * Note that this event SHOULD NOT be emitted more than once, in particular - * if this method is called multiple times. - * - * After calling this method, the stream MUST switch into a non-readable - * mode, see also `isReadable()`. - * This means that no further `data` or `end` events SHOULD be emitted. - * - * ```php - * $stream->close(); - * assert($stream->isReadable() === false); - * - * $stream->on('data', assertNeverCalled()); - * $stream->on('end', assertNeverCalled()); - * ``` - * - * If this stream is a `DuplexStreamInterface`, you should also notice - * how the writable side of the stream also implements a `close()` method. - * In other words, after calling this method, the stream MUST switch into - * non-writable AND non-readable mode, see also `isWritable()`. - * Note that this method should not be confused with the `end()` method. - * - * @return void - * @see WritableStreamInterface::close() - */ - public function close(); -} diff --git a/assets/php/vendor/react/stream/src/ThroughStream.php b/assets/php/vendor/react/stream/src/ThroughStream.php deleted file mode 100755 index da2fbb0..0000000 --- a/assets/php/vendor/react/stream/src/ThroughStream.php +++ /dev/null @@ -1,190 +0,0 @@ -<?php - -namespace React\Stream; - -use Evenement\EventEmitter; -use InvalidArgumentException; - -/** - * The `ThroughStream` implements the - * [`DuplexStreamInterface`](#duplexstreaminterface) and will simply pass any data - * you write to it through to its readable end. - * - * ```php - * $through = new ThroughStream(); - * $through->on('data', $this->expectCallableOnceWith('hello')); - * - * $through->write('hello'); - * ``` - * - * Similarly, the [`end()` method](#end) will end the stream and emit an - * [`end` event](#end-event) and then [`close()`](#close-1) the stream. - * The [`close()` method](#close-1) will close the stream and emit a - * [`close` event](#close-event). - * Accordingly, this is can also be used in a [`pipe()`](#pipe) context like this: - * - * ```php - * $through = new ThroughStream(); - * $source->pipe($through)->pipe($dest); - * ``` - * - * Optionally, its constructor accepts any callable function which will then be - * used to *filter* any data written to it. This function receives a single data - * argument as passed to the writable side and must return the data as it will be - * passed to its readable end: - * - * ```php - * $through = new ThroughStream('strtoupper'); - * $source->pipe($through)->pipe($dest); - * ``` - * - * Note that this class makes no assumptions about any data types. This can be - * used to convert data, for example for transforming any structured data into - * a newline-delimited JSON (NDJSON) stream like this: - * - * ```php - * $through = new ThroughStream(function ($data) { - * return json_encode($data) . PHP_EOL; - * }); - * $through->on('data', $this->expectCallableOnceWith("[2, true]\n")); - * - * $through->write(array(2, true)); - * ``` - * - * The callback function is allowed to throw an `Exception`. In this case, - * the stream will emit an `error` event and then [`close()`](#close-1) the stream. - * - * ```php - * $through = new ThroughStream(function ($data) { - * if (!is_string($data)) { - * throw new \UnexpectedValueException('Only strings allowed'); - * } - * return $data; - * }); - * $through->on('error', $this->expectCallableOnce())); - * $through->on('close', $this->expectCallableOnce())); - * $through->on('data', $this->expectCallableNever())); - * - * $through->write(2); - * ``` - * - * @see WritableStreamInterface::write() - * @see WritableStreamInterface::end() - * @see DuplexStreamInterface::close() - * @see WritableStreamInterface::pipe() - */ -final class ThroughStream extends EventEmitter implements DuplexStreamInterface -{ - private $readable = true; - private $writable = true; - private $closed = false; - private $paused = false; - private $drain = false; - private $callback; - - public function __construct($callback = null) - { - if ($callback !== null && !is_callable($callback)) { - throw new InvalidArgumentException('Invalid transformation callback given'); - } - - $this->callback = $callback; - } - - public function pause() - { - $this->paused = true; - } - - public function resume() - { - if ($this->drain) { - $this->drain = false; - $this->emit('drain'); - } - $this->paused = false; - } - - public function pipe(WritableStreamInterface $dest, array $options = array()) - { - return Util::pipe($this, $dest, $options); - } - - public function isReadable() - { - return $this->readable; - } - - public function isWritable() - { - return $this->writable; - } - - public function write($data) - { - if (!$this->writable) { - return false; - } - - if ($this->callback !== null) { - try { - $data = call_user_func($this->callback, $data); - } catch (\Exception $e) { - $this->emit('error', array($e)); - $this->close(); - - return false; - } - } - - $this->emit('data', array($data)); - - if ($this->paused) { - $this->drain = true; - return false; - } - - return true; - } - - public function end($data = null) - { - if (!$this->writable) { - return; - } - - if (null !== $data) { - $this->write($data); - - // return if write() already caused the stream to close - if (!$this->writable) { - return; - } - } - - $this->readable = false; - $this->writable = false; - $this->paused = true; - $this->drain = false; - - $this->emit('end'); - $this->close(); - } - - public function close() - { - if ($this->closed) { - return; - } - - $this->readable = false; - $this->writable = false; - $this->closed = true; - $this->paused = true; - $this->drain = false; - $this->callback = null; - - $this->emit('close'); - $this->removeAllListeners(); - } -} diff --git a/assets/php/vendor/react/stream/src/Util.php b/assets/php/vendor/react/stream/src/Util.php deleted file mode 100755 index 14ddcfc..0000000 --- a/assets/php/vendor/react/stream/src/Util.php +++ /dev/null @@ -1,75 +0,0 @@ -<?php - -namespace React\Stream; - -final class Util -{ - /** - * Pipes all the data from the given $source into the $dest - * - * @param ReadableStreamInterface $source - * @param WritableStreamInterface $dest - * @param array $options - * @return WritableStreamInterface $dest stream as-is - * @see ReadableStreamInterface::pipe() for more details - */ - public static function pipe(ReadableStreamInterface $source, WritableStreamInterface $dest, array $options = array()) - { - // source not readable => NO-OP - if (!$source->isReadable()) { - return $dest; - } - - // destination not writable => just pause() source - if (!$dest->isWritable()) { - $source->pause(); - - return $dest; - } - - $dest->emit('pipe', array($source)); - - // forward all source data events as $dest->write() - $source->on('data', $dataer = function ($data) use ($source, $dest) { - $feedMore = $dest->write($data); - - if (false === $feedMore) { - $source->pause(); - } - }); - $dest->on('close', function () use ($source, $dataer) { - $source->removeListener('data', $dataer); - $source->pause(); - }); - - // forward destination drain as $source->resume() - $dest->on('drain', $drainer = function () use ($source) { - $source->resume(); - }); - $source->on('close', function () use ($dest, $drainer) { - $dest->removeListener('drain', $drainer); - }); - - // forward end event from source as $dest->end() - $end = isset($options['end']) ? $options['end'] : true; - if ($end) { - $source->on('end', $ender = function () use ($dest) { - $dest->end(); - }); - $dest->on('close', function () use ($source, $ender) { - $source->removeListener('end', $ender); - }); - } - - return $dest; - } - - public static function forwardEvents($source, $target, array $events) - { - foreach ($events as $event) { - $source->on($event, function () use ($event, $target) { - $target->emit($event, func_get_args()); - }); - } - } -} diff --git a/assets/php/vendor/react/stream/src/WritableResourceStream.php b/assets/php/vendor/react/stream/src/WritableResourceStream.php deleted file mode 100755 index 7e04205..0000000 --- a/assets/php/vendor/react/stream/src/WritableResourceStream.php +++ /dev/null @@ -1,171 +0,0 @@ -<?php - -namespace React\Stream; - -use Evenement\EventEmitter; -use React\EventLoop\LoopInterface; - -final class WritableResourceStream extends EventEmitter implements WritableStreamInterface -{ - private $stream; - private $loop; - private $softLimit; - private $writeChunkSize; - - private $listening = false; - private $writable = true; - private $closed = false; - private $data = ''; - - public function __construct($stream, LoopInterface $loop, $writeBufferSoftLimit = null, $writeChunkSize = null) - { - if (!is_resource($stream) || get_resource_type($stream) !== "stream") { - throw new \InvalidArgumentException('First parameter must be a valid stream resource'); - } - - // ensure resource is opened for writing (fopen mode must contain either of "waxc+") - $meta = stream_get_meta_data($stream); - if (isset($meta['mode']) && $meta['mode'] !== '' && strtr($meta['mode'], 'waxc+', '.....') === $meta['mode']) { - throw new \InvalidArgumentException('Given stream resource is not opened in write mode'); - } - - // this class relies on non-blocking I/O in order to not interrupt the event loop - // e.g. pipes on Windows do not support this: https://bugs.php.net/bug.php?id=47918 - if (stream_set_blocking($stream, 0) !== true) { - throw new \RuntimeException('Unable to set stream resource to non-blocking mode'); - } - - $this->stream = $stream; - $this->loop = $loop; - $this->softLimit = ($writeBufferSoftLimit === null) ? 65536 : (int)$writeBufferSoftLimit; - $this->writeChunkSize = ($writeChunkSize === null) ? -1 : (int)$writeChunkSize; - } - - public function isWritable() - { - return $this->writable; - } - - public function write($data) - { - if (!$this->writable) { - return false; - } - - $this->data .= $data; - - if (!$this->listening && $this->data !== '') { - $this->listening = true; - - $this->loop->addWriteStream($this->stream, array($this, 'handleWrite')); - } - - return !isset($this->data[$this->softLimit - 1]); - } - - public function end($data = null) - { - if (null !== $data) { - $this->write($data); - } - - $this->writable = false; - - // close immediately if buffer is already empty - // otherwise wait for buffer to flush first - if ($this->data === '') { - $this->close(); - } - } - - public function close() - { - if ($this->closed) { - return; - } - - if ($this->listening) { - $this->listening = false; - $this->loop->removeWriteStream($this->stream); - } - - $this->closed = true; - $this->writable = false; - $this->data = ''; - - $this->emit('close'); - $this->removeAllListeners(); - - if (is_resource($this->stream)) { - fclose($this->stream); - } - } - - /** @internal */ - public function handleWrite() - { - $error = null; - set_error_handler(function ($errno, $errstr, $errfile, $errline) use (&$error) { - $error = array( - 'message' => $errstr, - 'number' => $errno, - 'file' => $errfile, - 'line' => $errline - ); - }); - - if ($this->writeChunkSize === -1) { - $sent = fwrite($this->stream, $this->data); - } else { - $sent = fwrite($this->stream, $this->data, $this->writeChunkSize); - } - - restore_error_handler(); - - // Only report errors if *nothing* could be sent. - // Any hard (permanent) error will fail to send any data at all. - // Sending excessive amounts of data will only flush *some* data and then - // report a temporary error (EAGAIN) which we do not raise here in order - // to keep the stream open for further tries to write. - // Should this turn out to be a permanent error later, it will eventually - // send *nothing* and we can detect this. - if ($sent === 0 || $sent === false) { - if ($error !== null) { - $error = new \ErrorException( - $error['message'], - 0, - $error['number'], - $error['file'], - $error['line'] - ); - } - - $this->emit('error', array(new \RuntimeException('Unable to write to stream: ' . ($error !== null ? $error->getMessage() : 'Unknown error'), 0, $error))); - $this->close(); - - return; - } - - $exceeded = isset($this->data[$this->softLimit - 1]); - $this->data = (string) substr($this->data, $sent); - - // buffer has been above limit and is now below limit - if ($exceeded && !isset($this->data[$this->softLimit - 1])) { - $this->emit('drain'); - } - - // buffer is now completely empty => stop trying to write - if ($this->data === '') { - // stop waiting for resource to be writable - if ($this->listening) { - $this->loop->removeWriteStream($this->stream); - $this->listening = false; - } - - // buffer is end()ing and now completely empty => close buffer - if (!$this->writable) { - $this->close(); - } - } - } -} diff --git a/assets/php/vendor/react/stream/src/WritableStreamInterface.php b/assets/php/vendor/react/stream/src/WritableStreamInterface.php deleted file mode 100755 index 3bc932e..0000000 --- a/assets/php/vendor/react/stream/src/WritableStreamInterface.php +++ /dev/null @@ -1,347 +0,0 @@ -<?php - -namespace React\Stream; - -use Evenement\EventEmitterInterface; - -/** - * The `WritableStreamInterface` is responsible for providing an interface for - * write-only streams and the writable side of duplex streams. - * - * Besides defining a few methods, this interface also implements the - * `EventEmitterInterface` which allows you to react to certain events: - * - * drain event: - * The `drain` event will be emitted whenever the write buffer became full - * previously and is now ready to accept more data. - * - * ```php - * $stream->on('drain', function () use ($stream) { - * echo 'Stream is now ready to accept more data'; - * }); - * ``` - * - * This event SHOULD be emitted once every time the buffer became full - * previously and is now ready to accept more data. - * In other words, this event MAY be emitted any number of times, which may - * be zero times if the buffer never became full in the first place. - * This event SHOULD NOT be emitted if the buffer has not become full - * previously. - * - * This event is mostly used internally, see also `write()` for more details. - * - * pipe event: - * The `pipe` event will be emitted whenever a readable stream is `pipe()`d - * into this stream. - * The event receives a single `ReadableStreamInterface` argument for the - * source stream. - * - * ```php - * $stream->on('pipe', function (ReadableStreamInterface $source) use ($stream) { - * echo 'Now receiving piped data'; - * - * // explicitly close target if source emits an error - * $source->on('error', function () use ($stream) { - * $stream->close(); - * }); - * }); - * - * $source->pipe($stream); - * ``` - * - * This event MUST be emitted once for each readable stream that is - * successfully piped into this destination stream. - * In other words, this event MAY be emitted any number of times, which may - * be zero times if no stream is ever piped into this stream. - * This event MUST NOT be emitted if either the source is not readable - * (closed already) or this destination is not writable (closed already). - * - * This event is mostly used internally, see also `pipe()` for more details. - * - * error event: - * The `error` event will be emitted once a fatal error occurs, usually while - * trying to write to this stream. - * The event receives a single `Exception` argument for the error instance. - * - * ```php - * $stream->on('error', function (Exception $e) { - * echo 'Error: ' . $e->getMessage() . PHP_EOL; - * }); - * ``` - * - * This event SHOULD be emitted once the stream detects a fatal error, such - * as a fatal transmission error. - * It SHOULD NOT be emitted after a previous `error` or `close` event. - * It MUST NOT be emitted if this is not a fatal error condition, such as - * a temporary network issue that did not cause any data to be lost. - * - * After the stream errors, it MUST close the stream and SHOULD thus be - * followed by a `close` event and then switch to non-writable mode, see - * also `close()` and `isWritable()`. - * - * Many common streams (such as a TCP/IP connection or a file-based stream) - * only deal with data transmission and may choose - * to only emit this for a fatal transmission error once and will then - * close (terminate) the stream in response. - * - * If this stream is a `DuplexStreamInterface`, you should also notice - * how the readable side of the stream also implements an `error` event. - * In other words, an error may occur while either reading or writing the - * stream which should result in the same error processing. - * - * close event: - * The `close` event will be emitted once the stream closes (terminates). - * - * ```php - * $stream->on('close', function () { - * echo 'CLOSED'; - * }); - * ``` - * - * This event SHOULD be emitted once or never at all, depending on whether - * the stream ever terminates. - * It SHOULD NOT be emitted after a previous `close` event. - * - * After the stream is closed, it MUST switch to non-writable mode, - * see also `isWritable()`. - * - * This event SHOULD be emitted whenever the stream closes, irrespective of - * whether this happens implicitly due to an unrecoverable error or - * explicitly when either side closes the stream. - * - * Many common streams (such as a TCP/IP connection or a file-based stream) - * will likely choose to emit this event after flushing the buffer from - * the `end()` method, after receiving a *successful* `end` event or after - * a fatal transmission `error` event. - * - * If this stream is a `DuplexStreamInterface`, you should also notice - * how the readable side of the stream also implements a `close` event. - * In other words, after receiving this event, the stream MUST switch into - * non-writable AND non-readable mode, see also `isReadable()`. - * Note that this event should not be confused with the `end` event. - * - * The event callback functions MUST be a valid `callable` that obeys strict - * parameter definitions and MUST accept event parameters exactly as documented. - * The event callback functions MUST NOT throw an `Exception`. - * The return value of the event callback functions will be ignored and has no - * effect, so for performance reasons you're recommended to not return any - * excessive data structures. - * - * Every implementation of this interface MUST follow these event semantics in - * order to be considered a well-behaving stream. - * - * > Note that higher-level implementations of this interface may choose to - * define additional events with dedicated semantics not defined as part of - * this low-level stream specification. Conformance with these event semantics - * is out of scope for this interface, so you may also have to refer to the - * documentation of such a higher-level implementation. - * - * @see EventEmitterInterface - * @see DuplexStreamInterface - */ -interface WritableStreamInterface extends EventEmitterInterface -{ - /** - * Checks whether this stream is in a writable state (not closed already). - * - * This method can be used to check if the stream still accepts writing - * any data or if it is ended or closed already. - * Writing any data to a non-writable stream is a NO-OP: - * - * ```php - * assert($stream->isWritable() === false); - * - * $stream->write('end'); // NO-OP - * $stream->end('end'); // NO-OP - * ``` - * - * A successfully opened stream always MUST start in writable mode. - * - * Once the stream ends or closes, it MUST switch to non-writable mode. - * This can happen any time, explicitly through `end()` or `close()` or - * implicitly due to a remote close or an unrecoverable transmission error. - * Once a stream has switched to non-writable mode, it MUST NOT transition - * back to writable mode. - * - * If this stream is a `DuplexStreamInterface`, you should also notice - * how the readable side of the stream also implements an `isReadable()` - * method. Unless this is a half-open duplex stream, they SHOULD usually - * have the same return value. - * - * @return bool - */ - public function isWritable(); - - /** - * Write some data into the stream. - * - * A successful write MUST be confirmed with a boolean `true`, which means - * that either the data was written (flushed) immediately or is buffered and - * scheduled for a future write. Note that this interface gives you no - * control over explicitly flushing the buffered data, as finding the - * appropriate time for this is beyond the scope of this interface and left - * up to the implementation of this interface. - * - * Many common streams (such as a TCP/IP connection or file-based stream) - * may choose to buffer all given data and schedule a future flush by using - * an underlying EventLoop to check when the resource is actually writable. - * - * If a stream cannot handle writing (or flushing) the data, it SHOULD emit - * an `error` event and MAY `close()` the stream if it can not recover from - * this error. - * - * If the internal buffer is full after adding `$data`, then `write()` - * SHOULD return `false`, indicating that the caller should stop sending - * data until the buffer drains. - * The stream SHOULD send a `drain` event once the buffer is ready to accept - * more data. - * - * Similarly, if the the stream is not writable (already in a closed state) - * it MUST NOT process the given `$data` and SHOULD return `false`, - * indicating that the caller should stop sending data. - * - * The given `$data` argument MAY be of mixed type, but it's usually - * recommended it SHOULD be a `string` value or MAY use a type that allows - * representation as a `string` for maximum compatibility. - * - * Many common streams (such as a TCP/IP connection or a file-based stream) - * will only accept the raw (binary) payload data that is transferred over - * the wire as chunks of `string` values. - * - * Due to the stream-based nature of this, the sender may send any number - * of chunks with varying sizes. There are no guarantees that these chunks - * will be received with the exact same framing the sender intended to send. - * In other words, many lower-level protocols (such as TCP/IP) transfer the - * data in chunks that may be anywhere between single-byte values to several - * dozens of kilobytes. You may want to apply a higher-level protocol to - * these low-level data chunks in order to achieve proper message framing. - * - * @param mixed|string $data - * @return bool - */ - public function write($data); - - /** - * Successfully ends the stream (after optionally sending some final data). - * - * This method can be used to successfully end the stream, i.e. close - * the stream after sending out all data that is currently buffered. - * - * ```php - * $stream->write('hello'); - * $stream->write('world'); - * $stream->end(); - * ``` - * - * If there's no data currently buffered and nothing to be flushed, then - * this method MAY `close()` the stream immediately. - * - * If there's still data in the buffer that needs to be flushed first, then - * this method SHOULD try to write out this data and only then `close()` - * the stream. - * Once the stream is closed, it SHOULD emit a `close` event. - * - * Note that this interface gives you no control over explicitly flushing - * the buffered data, as finding the appropriate time for this is beyond the - * scope of this interface and left up to the implementation of this - * interface. - * - * Many common streams (such as a TCP/IP connection or file-based stream) - * may choose to buffer all given data and schedule a future flush by using - * an underlying EventLoop to check when the resource is actually writable. - * - * You can optionally pass some final data that is written to the stream - * before ending the stream. If a non-`null` value is given as `$data`, then - * this method will behave just like calling `write($data)` before ending - * with no data. - * - * ```php - * // shorter version - * $stream->end('bye'); - * - * // same as longer version - * $stream->write('bye'); - * $stream->end(); - * ``` - * - * After calling this method, the stream MUST switch into a non-writable - * mode, see also `isWritable()`. - * This means that no further writes are possible, so any additional - * `write()` or `end()` calls have no effect. - * - * ```php - * $stream->end(); - * assert($stream->isWritable() === false); - * - * $stream->write('nope'); // NO-OP - * $stream->end(); // NO-OP - * ``` - * - * If this stream is a `DuplexStreamInterface`, calling this method SHOULD - * also end its readable side, unless the stream supports half-open mode. - * In other words, after calling this method, these streams SHOULD switch - * into non-writable AND non-readable mode, see also `isReadable()`. - * This implies that in this case, the stream SHOULD NOT emit any `data` - * or `end` events anymore. - * Streams MAY choose to use the `pause()` method logic for this, but - * special care may have to be taken to ensure a following call to the - * `resume()` method SHOULD NOT continue emitting readable events. - * - * Note that this method should not be confused with the `close()` method. - * - * @param mixed|string|null $data - * @return void - */ - public function end($data = null); - - /** - * Closes the stream (forcefully). - * - * This method can be used to forcefully close the stream, i.e. close - * the stream without waiting for any buffered data to be flushed. - * If there's still data in the buffer, this data SHOULD be discarded. - * - * ```php - * $stream->close(); - * ``` - * - * Once the stream is closed, it SHOULD emit a `close` event. - * Note that this event SHOULD NOT be emitted more than once, in particular - * if this method is called multiple times. - * - * After calling this method, the stream MUST switch into a non-writable - * mode, see also `isWritable()`. - * This means that no further writes are possible, so any additional - * `write()` or `end()` calls have no effect. - * - * ```php - * $stream->close(); - * assert($stream->isWritable() === false); - * - * $stream->write('nope'); // NO-OP - * $stream->end(); // NO-OP - * ``` - * - * Note that this method should not be confused with the `end()` method. - * Unlike the `end()` method, this method does not take care of any existing - * buffers and simply discards any buffer contents. - * Likewise, this method may also be called after calling `end()` on a - * stream in order to stop waiting for the stream to flush its final data. - * - * ```php - * $stream->end(); - * $loop->addTimer(1.0, function () use ($stream) { - * $stream->close(); - * }); - * ``` - * - * If this stream is a `DuplexStreamInterface`, you should also notice - * how the readable side of the stream also implements a `close()` method. - * In other words, after calling this method, the stream MUST switch into - * non-writable AND non-readable mode, see also `isReadable()`. - * - * @return void - * @see ReadableStreamInterface::close() - */ - public function close(); -} diff --git a/assets/php/vendor/react/stream/tests/CallableStub.php b/assets/php/vendor/react/stream/tests/CallableStub.php deleted file mode 100755 index 31cc834..0000000 --- a/assets/php/vendor/react/stream/tests/CallableStub.php +++ /dev/null @@ -1,10 +0,0 @@ -<?php - -namespace React\Tests\Stream; - -class CallableStub -{ - public function __invoke() - { - } -} diff --git a/assets/php/vendor/react/stream/tests/CompositeStreamTest.php b/assets/php/vendor/react/stream/tests/CompositeStreamTest.php deleted file mode 100755 index df89c3e..0000000 --- a/assets/php/vendor/react/stream/tests/CompositeStreamTest.php +++ /dev/null @@ -1,267 +0,0 @@ -<?php - -namespace React\Tests\Stream; - -use React\Stream\CompositeStream; -use React\Stream\ThroughStream; - -/** - * @covers React\Stream\CompositeStream - */ -class CompositeStreamTest extends TestCase -{ - /** @test */ - public function itShouldCloseReadableIfNotWritable() - { - $readable = $this->getMockBuilder('React\Stream\ReadableStreamInterface')->getMock(); - $readable - ->expects($this->once()) - ->method('isReadable') - ->willReturn(true); - $readable - ->expects($this->once()) - ->method('close'); - - $writable = $this->getMockBuilder('React\Stream\WritableStreamInterface')->getMock(); - $writable - ->expects($this->once()) - ->method('isWritable') - ->willReturn(false); - - $composite = new CompositeStream($readable, $writable); - - $composite->on('close', $this->expectCallableNever()); - $composite->close(); - } - - /** @test */ - public function itShouldCloseWritableIfNotReadable() - { - $readable = $this->getMockBuilder('React\Stream\ReadableStreamInterface')->getMock(); - $readable - ->expects($this->once()) - ->method('isReadable') - ->willReturn(false); - - $writable = $this->getMockBuilder('React\Stream\WritableStreamInterface')->getMock(); - $writable - ->expects($this->once()) - ->method('close'); - - $composite = new CompositeStream($readable, $writable); - - $composite->on('close', $this->expectCallableNever()); - $composite->close(); - } - - /** @test */ - public function itShouldForwardWritableCallsToWritableStream() - { - $readable = $this->getMockBuilder('React\Stream\ReadableStreamInterface')->getMock(); - $readable - ->expects($this->once()) - ->method('isReadable') - ->willReturn(true); - - $writable = $this->getMockBuilder('React\Stream\WritableStreamInterface')->getMock(); - $writable - ->expects($this->once()) - ->method('write') - ->with('foo'); - $writable - ->expects($this->exactly(2)) - ->method('isWritable') - ->willReturn(true); - - $composite = new CompositeStream($readable, $writable); - $composite->write('foo'); - $composite->isWritable(); - } - - /** @test */ - public function itShouldForwardReadableCallsToReadableStream() - { - $readable = $this->getMockBuilder('React\Stream\ReadableStreamInterface')->getMock(); - $readable - ->expects($this->exactly(2)) - ->method('isReadable') - ->willReturn(true); - $readable - ->expects($this->once()) - ->method('pause'); - $readable - ->expects($this->once()) - ->method('resume'); - - $writable = $this->getMockBuilder('React\Stream\WritableStreamInterface')->getMock(); - $writable - ->expects($this->any()) - ->method('isWritable') - ->willReturn(true); - - $composite = new CompositeStream($readable, $writable); - $composite->isReadable(); - $composite->pause(); - $composite->resume(); - } - - /** @test */ - public function itShouldNotForwardResumeIfStreamIsNotWritable() - { - $readable = $this->getMockBuilder('React\Stream\ReadableStreamInterface')->getMock(); - $readable - ->expects($this->once()) - ->method('isReadable') - ->willReturn(true); - $readable - ->expects($this->never()) - ->method('resume'); - - $writable = $this->getMockBuilder('React\Stream\WritableStreamInterface')->getMock(); - $writable - ->expects($this->exactly(2)) - ->method('isWritable') - ->willReturnOnConsecutiveCalls(true, false); - - $composite = new CompositeStream($readable, $writable); - $composite->resume(); - } - - /** @test */ - public function endShouldDelegateToWritableWithData() - { - $readable = $this->getMockBuilder('React\Stream\ReadableStreamInterface')->getMock(); - $readable - ->expects($this->once()) - ->method('isReadable') - ->willReturn(true); - - $writable = $this->getMockBuilder('React\Stream\WritableStreamInterface')->getMock(); - $writable - ->expects($this->once()) - ->method('isWritable') - ->willReturn(true); - $writable - ->expects($this->once()) - ->method('end') - ->with('foo'); - - $composite = new CompositeStream($readable, $writable); - $composite->end('foo'); - } - - /** @test */ - public function closeShouldCloseBothStreams() - { - $readable = $this->getMockBuilder('React\Stream\ReadableStreamInterface')->getMock(); - $readable - ->expects($this->once()) - ->method('isReadable') - ->willReturn(true); - $readable - ->expects($this->once()) - ->method('close'); - - $writable = $this->getMockBuilder('React\Stream\WritableStreamInterface')->getMock(); - $writable - ->expects($this->once()) - ->method('isWritable') - ->willReturn(true); - $writable - ->expects($this->once()) - ->method('close'); - - $composite = new CompositeStream($readable, $writable); - $composite->close(); - } - - /** @test */ - public function itShouldForwardCloseOnlyOnce() - { - $readable = new ThroughStream(); - $writable = new ThroughStream(); - - $composite = new CompositeStream($readable, $writable); - $composite->on('close', $this->expectCallableOnce()); - - $readable->close(); - $writable->close(); - } - - /** @test */ - public function itShouldForwardCloseAndRemoveAllListeners() - { - $in = new ThroughStream(); - - $composite = new CompositeStream($in, $in); - $composite->on('close', $this->expectCallableOnce()); - - $this->assertTrue($composite->isReadable()); - $this->assertTrue($composite->isWritable()); - $this->assertCount(1, $composite->listeners('close')); - - $composite->close(); - - $this->assertFalse($composite->isReadable()); - $this->assertFalse($composite->isWritable()); - $this->assertCount(0, $composite->listeners('close')); - } - - /** @test */ - public function itShouldReceiveForwardedEvents() - { - $readable = new ThroughStream(); - $writable = new ThroughStream(); - - $composite = new CompositeStream($readable, $writable); - $composite->on('data', $this->expectCallableOnce()); - $composite->on('drain', $this->expectCallableOnce()); - - $readable->emit('data', array('foo')); - $writable->emit('drain'); - } - - /** @test */ - public function itShouldHandlePipingCorrectly() - { - $readable = $this->getMockBuilder('React\Stream\ReadableStreamInterface')->getMock(); - $readable - ->expects($this->once()) - ->method('isReadable') - ->willReturn(true); - - $writable = $this->getMockBuilder('React\Stream\WritableStreamInterface')->getMock(); - $writable->expects($this->any())->method('isWritable')->willReturn(True); - $writable - ->expects($this->once()) - ->method('write') - ->with('foo'); - - $composite = new CompositeStream($readable, $writable); - - $input = new ThroughStream(); - $input->pipe($composite); - $input->emit('data', array('foo')); - } - - /** @test */ - public function itShouldForwardPipeCallsToReadableStream() - { - $readable = new ThroughStream(); - - $writable = $this->getMockBuilder('React\Stream\WritableStreamInterface')->getMock(); - $writable->expects($this->any())->method('isWritable')->willReturn(True); - - $composite = new CompositeStream($readable, $writable); - - $output = $this->getMockBuilder('React\Stream\WritableStreamInterface')->getMock(); - $output->expects($this->any())->method('isWritable')->willReturn(True); - $output - ->expects($this->once()) - ->method('write') - ->with('foo'); - - $composite->pipe($output); - $readable->emit('data', array('foo')); - } -} diff --git a/assets/php/vendor/react/stream/tests/DuplexResourceStreamIntegrationTest.php b/assets/php/vendor/react/stream/tests/DuplexResourceStreamIntegrationTest.php deleted file mode 100755 index fb5f02a..0000000 --- a/assets/php/vendor/react/stream/tests/DuplexResourceStreamIntegrationTest.php +++ /dev/null @@ -1,352 +0,0 @@ -<?php - -namespace React\Tests\Stream; - -use React\Stream\DuplexResourceStream; -use React\Stream\ReadableResourceStream; -use React\EventLoop\ExtEventLoop; -use React\EventLoop\ExtLibeventLoop; -use React\EventLoop\ExtLibevLoop; -use React\EventLoop\LoopInterface; -use React\EventLoop\LibEventLoop; -use React\EventLoop\LibEvLoop; -use React\EventLoop\StreamSelectLoop; - -class DuplexResourceStreamIntegrationTest extends TestCase -{ - public function loopProvider() - { - return array( - array( - function() { - return true; - }, - function () { - return new StreamSelectLoop(); - } - ), - array( - function () { - return function_exists('event_base_new'); - }, - function () { - return class_exists('React\EventLoop\ExtLibeventLoop') ? new ExtLibeventLoop() : new LibEventLoop(); - } - ), - array( - function () { - return class_exists('libev\EventLoop'); - }, - function () { - return class_exists('React\EventLoop\ExtLibevLoop') ? new ExtLibevLoop() : new LibEvLoop(); - } - ), - array( - function () { - return class_exists('EventBase') && class_exists('React\EventLoop\ExtEventLoop'); - }, - function () { - return new ExtEventLoop(); - } - ) - ); - } - - /** - * @dataProvider loopProvider - */ - public function testBufferReadsLargeChunks($condition, $loopFactory) - { - if (true !== $condition()) { - return $this->markTestSkipped('Loop implementation not available'); - } - - $loop = $loopFactory(); - - list($sockA, $sockB) = stream_socket_pair(STREAM_PF_UNIX, STREAM_SOCK_STREAM, 0); - - $bufferSize = 4096; - $streamA = new DuplexResourceStream($sockA, $loop, $bufferSize); - $streamB = new DuplexResourceStream($sockB, $loop, $bufferSize); - - $testString = str_repeat("*", $bufferSize + 1); - - $buffer = ""; - $streamB->on('data', function ($data) use (&$buffer) { - $buffer .= $data; - }); - - $streamA->write($testString); - - $this->loopTick($loop); - $this->loopTick($loop); - $this->loopTick($loop); - - $streamA->close(); - $streamB->close(); - - $this->assertEquals($testString, $buffer); - } - - /** - * @dataProvider loopProvider - */ - public function testWriteLargeChunk($condition, $loopFactory) - { - if (true !== $condition()) { - return $this->markTestSkipped('Loop implementation not available'); - } - - $loop = $loopFactory(); - - list($sockA, $sockB) = stream_socket_pair(STREAM_PF_UNIX, STREAM_SOCK_STREAM, 0); - - $streamA = new DuplexResourceStream($sockA, $loop); - $streamB = new DuplexResourceStream($sockB, $loop); - - // limit seems to be 192 KiB - $size = 256 * 1024; - - // sending side sends and expects clean close with no errors - $streamA->end(str_repeat('*', $size)); - $streamA->on('close', $this->expectCallableOnce()); - $streamA->on('error', $this->expectCallableNever()); - - // receiving side counts bytes and expects clean close with no errors - $received = 0; - $streamB->on('data', function ($chunk) use (&$received) { - $received += strlen($chunk); - }); - $streamB->on('close', $this->expectCallableOnce()); - $streamB->on('error', $this->expectCallableNever()); - - $loop->run(); - - $streamA->close(); - $streamB->close(); - - $this->assertEquals($size, $received); - } - - /** - * @dataProvider loopProvider - */ - public function testDoesNotEmitDataIfNothingHasBeenWritten($condition, $loopFactory) - { - if (true !== $condition()) { - return $this->markTestSkipped('Loop implementation not available'); - } - - $loop = $loopFactory(); - - list($sockA, $sockB) = stream_socket_pair(STREAM_PF_UNIX, STREAM_SOCK_STREAM, 0); - - $streamA = new DuplexResourceStream($sockA, $loop); - $streamB = new DuplexResourceStream($sockB, $loop); - - // end streamA without writing any data - $streamA->end(); - - // streamB should not emit any data - $streamB->on('data', $this->expectCallableNever()); - - $loop->run(); - - $streamA->close(); - $streamB->close(); - } - - /** - * @dataProvider loopProvider - */ - public function testDoesNotWriteDataIfRemoteSideFromPairHasBeenClosed($condition, $loopFactory) - { - if (true !== $condition()) { - return $this->markTestSkipped('Loop implementation not available'); - } - - $loop = $loopFactory(); - - list($sockA, $sockB) = stream_socket_pair(STREAM_PF_UNIX, STREAM_SOCK_STREAM, 0); - - $streamA = new DuplexResourceStream($sockA, $loop); - $streamB = new DuplexResourceStream($sockB, $loop); - - // end streamA without writing any data - $streamA->pause(); - $streamA->write('hello'); - $streamA->on('close', $this->expectCallableOnce()); - - $streamB->on('data', $this->expectCallableNever()); - $streamB->close(); - - $loop->run(); - - $streamA->close(); - $streamB->close(); - } - - /** - * @dataProvider loopProvider - */ - public function testDoesNotWriteDataIfServerSideHasBeenClosed($condition, $loopFactory) - { - if (true !== $condition()) { - return $this->markTestSkipped('Loop implementation not available'); - } - - $loop = $loopFactory(); - - $server = stream_socket_server('tcp://127.0.0.1:0'); - - $client = stream_socket_client(stream_socket_get_name($server, false)); - $peer = stream_socket_accept($server); - - $streamA = new DuplexResourceStream($client, $loop); - $streamB = new DuplexResourceStream($peer, $loop); - - // end streamA without writing any data - $streamA->pause(); - $streamA->write('hello'); - $streamA->on('close', $this->expectCallableOnce()); - - $streamB->on('data', $this->expectCallableNever()); - $streamB->close(); - - $loop->run(); - - $streamA->close(); - $streamB->close(); - } - - /** - * @dataProvider loopProvider - */ - public function testDoesNotWriteDataIfClientSideHasBeenClosed($condition, $loopFactory) - { - if (true !== $condition()) { - return $this->markTestSkipped('Loop implementation not available'); - } - - $loop = $loopFactory(); - - $server = stream_socket_server('tcp://127.0.0.1:0'); - - $client = stream_socket_client(stream_socket_get_name($server, false)); - $peer = stream_socket_accept($server); - - $streamA = new DuplexResourceStream($peer, $loop); - $streamB = new DuplexResourceStream($client, $loop); - - // end streamA without writing any data - $streamA->pause(); - $streamA->write('hello'); - $streamA->on('close', $this->expectCallableOnce()); - - $streamB->on('data', $this->expectCallableNever()); - $streamB->close(); - - $loop->run(); - - $streamA->close(); - $streamB->close(); - } - - /** - * @dataProvider loopProvider - */ - public function testReadsSingleChunkFromProcessPipe($condition, $loopFactory) - { - if (true !== $condition()) { - return $this->markTestSkipped('Loop implementation not available'); - } - - $loop = $loopFactory(); - - $stream = new ReadableResourceStream(popen('echo test', 'r'), $loop); - $stream->on('data', $this->expectCallableOnceWith("test\n")); - $stream->on('end', $this->expectCallableOnce()); - $stream->on('error', $this->expectCallableNever()); - - $loop->run(); - } - - /** - * @dataProvider loopProvider - */ - public function testReadsMultipleChunksFromProcessPipe($condition, $loopFactory) - { - if (true !== $condition()) { - return $this->markTestSkipped('Loop implementation not available'); - } - - $loop = $loopFactory(); - - $stream = new ReadableResourceStream(popen('echo a;sleep 0.1;echo b;sleep 0.1;echo c', 'r'), $loop); - - $buffer = ''; - $stream->on('data', function ($chunk) use (&$buffer) { - $buffer .= $chunk; - }); - - $stream->on('end', $this->expectCallableOnce()); - $stream->on('error', $this->expectCallableNever()); - - $loop->run(); - - $this->assertEquals("a\n" . "b\n" . "c\n", $buffer); - } - - /** - * @dataProvider loopProvider - */ - public function testReadsLongChunksFromProcessPipe($condition, $loopFactory) - { - if (true !== $condition()) { - return $this->markTestSkipped('Loop implementation not available'); - } - - $loop = $loopFactory(); - - $stream = new ReadableResourceStream(popen('dd if=/dev/zero bs=12345 count=1234 2>&-', 'r'), $loop); - - $bytes = 0; - $stream->on('data', function ($chunk) use (&$bytes) { - $bytes += strlen($chunk); - }); - - $stream->on('end', $this->expectCallableOnce()); - $stream->on('error', $this->expectCallableNever()); - - $loop->run(); - - $this->assertEquals(12345 * 1234, $bytes); - } - - /** - * @dataProvider loopProvider - */ - public function testReadsNothingFromProcessPipeWithNoOutput($condition, $loopFactory) - { - if (true !== $condition()) { - return $this->markTestSkipped('Loop implementation not available'); - } - - $loop = $loopFactory(); - - $stream = new ReadableResourceStream(popen('true', 'r'), $loop); - $stream->on('data', $this->expectCallableNever()); - $stream->on('end', $this->expectCallableOnce()); - $stream->on('error', $this->expectCallableNever()); - - $loop->run(); - } - - private function loopTick(LoopInterface $loop) - { - $loop->addTimer(0, function () use ($loop) { - $loop->stop(); - }); - $loop->run(); - } -} diff --git a/assets/php/vendor/react/stream/tests/DuplexResourceStreamTest.php b/assets/php/vendor/react/stream/tests/DuplexResourceStreamTest.php deleted file mode 100755 index 3212ae8..0000000 --- a/assets/php/vendor/react/stream/tests/DuplexResourceStreamTest.php +++ /dev/null @@ -1,495 +0,0 @@ -<?php - -namespace React\Tests\Stream; - -use React\Stream\DuplexResourceStream; -use Clue\StreamFilter as Filter; -use React\Stream\WritableResourceStream; - -class DuplexResourceStreamTest extends TestCase -{ - /** - * @covers React\Stream\DuplexResourceStream::__construct - * @doesNotPerformAssertions - */ - public function testConstructor() - { - $stream = fopen('php://temp', 'r+'); - $loop = $this->createLoopMock(); - - new DuplexResourceStream($stream, $loop); - } - - /** - * @covers React\Stream\DuplexResourceStream::__construct - * @doesNotPerformAssertions - */ - public function testConstructorWithExcessiveMode() - { - // excessive flags are ignored for temp streams, so we have to use a file stream - $name = tempnam(sys_get_temp_dir(), 'test'); - $stream = @fopen($name, 'r+eANYTHING'); - unlink($name); - - $loop = $this->createLoopMock(); - $buffer = new DuplexResourceStream($stream, $loop); - $buffer->close(); - } - - /** - * @covers React\Stream\DuplexResourceStream::__construct - * @expectedException InvalidArgumentException - */ - public function testConstructorThrowsExceptionOnInvalidStream() - { - $loop = $this->createLoopMock(); - - new DuplexResourceStream('breakme', $loop); - } - - /** - * @covers React\Stream\DuplexResourceStream::__construct - * @expectedException InvalidArgumentException - */ - public function testConstructorThrowsExceptionOnWriteOnlyStream() - { - if (defined('HHVM_VERSION')) { - $this->markTestSkipped('HHVM does not report fopen mode for STDOUT'); - } - - $loop = $this->createLoopMock(); - - new DuplexResourceStream(STDOUT, $loop); - } - - /** - * @covers React\Stream\DuplexResourceStream::__construct - * @expectedException InvalidArgumentException - */ - public function testConstructorThrowsExceptionOnWriteOnlyStreamWithExcessiveMode() - { - // excessive flags are ignored for temp streams, so we have to use a file stream - $name = tempnam(sys_get_temp_dir(), 'test'); - $stream = fopen($name, 'weANYTHING'); - unlink($name); - - $loop = $this->createLoopMock(); - new DuplexResourceStream($stream, $loop); - } - - /** - * @covers React\Stream\DuplexResourceStream::__construct - * @expectedException RunTimeException - */ - public function testConstructorThrowsExceptionIfStreamDoesNotSupportNonBlocking() - { - if (!in_array('blocking', stream_get_wrappers())) { - stream_wrapper_register('blocking', 'React\Tests\Stream\EnforceBlockingWrapper'); - } - - $stream = fopen('blocking://test', 'r+'); - $loop = $this->createLoopMock(); - - new DuplexResourceStream($stream, $loop); - } - - /** - * @covers React\Stream\DuplexResourceStream::__construct - * @doesNotPerformAssertions - */ - public function testConstructorAcceptsBuffer() - { - $stream = fopen('php://temp', 'r+'); - $loop = $this->createLoopMock(); - - $buffer = $this->getMockBuilder('React\Stream\WritableStreamInterface')->getMock(); - - $conn = new DuplexResourceStream($stream, $loop, null, $buffer); - } - - public function testCloseShouldEmitCloseEvent() - { - $stream = fopen('php://temp', 'r+'); - $loop = $this->createLoopMock(); - - $conn = new DuplexResourceStream($stream, $loop); - $conn->on('close', $this->expectCallableOnce()); - $conn->on('end', $this->expectCallableNever()); - - $conn->close(); - - $this->assertFalse($conn->isReadable()); - } - - public function testEndShouldEndBuffer() - { - $stream = fopen('php://temp', 'r+'); - $loop = $this->createLoopMock(); - - $buffer = $this->getMockBuilder('React\Stream\WritableStreamInterface')->getMock(); - $buffer->expects($this->once())->method('end')->with('foo'); - - $conn = new DuplexResourceStream($stream, $loop, null, $buffer); - $conn->end('foo'); - } - - - public function testEndAfterCloseIsNoOp() - { - $stream = fopen('php://temp', 'r+'); - $loop = $this->createLoopMock(); - - $buffer = $this->getMockBuilder('React\Stream\WritableStreamInterface')->getMock(); - $buffer->expects($this->never())->method('end'); - - $conn = new DuplexResourceStream($stream, $loop); - $conn->close(); - $conn->end(); - } - - /** - * @covers React\Stream\DuplexResourceStream::__construct - * @covers React\Stream\DuplexResourceStream::handleData - */ - public function testDataEvent() - { - $stream = fopen('php://temp', 'r+'); - $loop = $this->createLoopMock(); - - $capturedData = null; - - $conn = new DuplexResourceStream($stream, $loop); - $conn->on('data', function ($data) use (&$capturedData) { - $capturedData = $data; - }); - - fwrite($stream, "foobar\n"); - rewind($stream); - - $conn->handleData($stream); - $this->assertSame("foobar\n", $capturedData); - } - - /** - * @covers React\Stream\DuplexResourceStream::__construct - * @covers React\Stream\DuplexResourceStream::handleData - */ - public function testDataEventDoesEmitOneChunkMatchingBufferSize() - { - $stream = fopen('php://temp', 'r+'); - $loop = $this->createLoopMock(); - - $capturedData = null; - - $conn = new DuplexResourceStream($stream, $loop, 4321); - $conn->on('data', function ($data) use (&$capturedData) { - $capturedData = $data; - }); - - fwrite($stream, str_repeat("a", 100000)); - rewind($stream); - - $conn->handleData($stream); - - $this->assertTrue($conn->isReadable()); - $this->assertEquals(4321, strlen($capturedData)); - } - - /** - * @covers React\Stream\DuplexResourceStream::__construct - * @covers React\Stream\DuplexResourceStream::handleData - */ - public function testDataEventDoesEmitOneChunkUntilStreamEndsWhenBufferSizeIsInfinite() - { - $stream = fopen('php://temp', 'r+'); - $loop = $this->createLoopMock(); - - $capturedData = null; - - $conn = new DuplexResourceStream($stream, $loop, -1); - - $conn->on('data', function ($data) use (&$capturedData) { - $capturedData = $data; - }); - - fwrite($stream, str_repeat("a", 100000)); - rewind($stream); - - $conn->handleData($stream); - - $this->assertTrue($conn->isReadable()); - $this->assertEquals(100000, strlen($capturedData)); - } - - /** - * @covers React\Stream\DuplexResourceStream::handleData - */ - public function testEmptyStreamShouldNotEmitData() - { - $stream = fopen('php://temp', 'r+'); - $loop = $this->createLoopMock(); - - $conn = new DuplexResourceStream($stream, $loop); - $conn->on('data', $this->expectCallableNever()); - - $conn->handleData($stream); - } - - /** - * @covers React\Stream\DuplexResourceStream::write - */ - public function testWrite() - { - $stream = fopen('php://temp', 'r+'); - $loop = $this->createWriteableLoopMock(); - - $conn = new DuplexResourceStream($stream, $loop); - $conn->write("foo\n"); - - rewind($stream); - $this->assertSame("foo\n", fgets($stream)); - } - - /** - * @covers React\Stream\DuplexResourceStream::end - * @covers React\Stream\DuplexResourceStream::isReadable - * @covers React\Stream\DuplexResourceStream::isWritable - */ - public function testEnd() - { - $stream = fopen('php://temp', 'r+'); - $loop = $this->createLoopMock(); - - $conn = new DuplexResourceStream($stream, $loop); - $conn->end(); - - $this->assertFalse(is_resource($stream)); - $this->assertFalse($conn->isReadable()); - $this->assertFalse($conn->isWritable()); - } - - /** - * @covers React\Stream\DuplexResourceStream::end - */ - public function testEndRemovesReadStreamFromLoop() - { - $stream = fopen('php://temp', 'r+'); - $loop = $this->createLoopMock(); - $loop->expects($this->once())->method('addReadStream')->with($stream); - $loop->expects($this->once())->method('removeReadStream')->with($stream); - - $conn = new DuplexResourceStream($stream, $loop); - $conn->end('bye'); - } - - /** - * @covers React\Stream\DuplexResourceStream::pause - */ - public function testPauseRemovesReadStreamFromLoop() - { - $stream = fopen('php://temp', 'r+'); - $loop = $this->createLoopMock(); - $loop->expects($this->once())->method('addReadStream')->with($stream); - $loop->expects($this->once())->method('removeReadStream')->with($stream); - - $conn = new DuplexResourceStream($stream, $loop); - $conn->pause(); - $conn->pause(); - } - - /** - * @covers React\Stream\DuplexResourceStream::pause - */ - public function testResumeDoesAddStreamToLoopOnlyOnce() - { - $stream = fopen('php://temp', 'r+'); - $loop = $this->createLoopMock(); - $loop->expects($this->once())->method('addReadStream')->with($stream); - - $conn = new DuplexResourceStream($stream, $loop); - $conn->resume(); - $conn->resume(); - } - - /** - * @covers React\Stream\DuplexResourceStream::close - */ - public function testCloseRemovesReadStreamFromLoop() - { - $stream = fopen('php://temp', 'r+'); - $loop = $this->createLoopMock(); - $loop->expects($this->once())->method('addReadStream')->with($stream); - $loop->expects($this->once())->method('removeReadStream')->with($stream); - - $conn = new DuplexResourceStream($stream, $loop); - $conn->close(); - } - - /** - * @covers React\Stream\DuplexResourceStream::close - */ - public function testCloseAfterPauseRemovesReadStreamFromLoopOnlyOnce() - { - $stream = fopen('php://temp', 'r+'); - $loop = $this->createLoopMock(); - $loop->expects($this->once())->method('addReadStream')->with($stream); - $loop->expects($this->once())->method('removeReadStream')->with($stream); - - $conn = new DuplexResourceStream($stream, $loop); - $conn->pause(); - $conn->close(); - } - - /** - * @covers React\Stream\DuplexResourceStream::close - */ - public function testResumeAfterCloseDoesAddReadStreamToLoopOnlyOnce() - { - $stream = fopen('php://temp', 'r+'); - $loop = $this->createLoopMock(); - $loop->expects($this->once())->method('addReadStream')->with($stream); - - $conn = new DuplexResourceStream($stream, $loop); - $conn->close(); - $conn->resume(); - } - - public function testEndedStreamsShouldNotWrite() - { - $file = tempnam(sys_get_temp_dir(), 'reactphptest_'); - $stream = fopen($file, 'r+'); - $loop = $this->createWriteableLoopMock(); - - $conn = new DuplexResourceStream($stream, $loop); - $conn->write("foo\n"); - $conn->end(); - - $res = $conn->write("bar\n"); - $stream = fopen($file, 'r'); - - $this->assertSame("foo\n", fgets($stream)); - $this->assertFalse($res); - - unlink($file); - } - - public function testPipeShouldReturnDestination() - { - $stream = fopen('php://temp', 'r+'); - $loop = $this->createLoopMock(); - - $conn = new DuplexResourceStream($stream, $loop); - $dest = $this->getMockBuilder('React\Stream\WritableStreamInterface')->getMock(); - - $this->assertSame($dest, $conn->pipe($dest)); - } - - public function testBufferEventsShouldBubbleUp() - { - $stream = fopen('php://temp', 'r+'); - $loop = $this->createLoopMock(); - - $buffer = new WritableResourceStream($stream, $loop); - $conn = new DuplexResourceStream($stream, $loop, null, $buffer); - - $conn->on('drain', $this->expectCallableOnce()); - $conn->on('error', $this->expectCallableOnce()); - - $buffer->emit('drain'); - $buffer->emit('error', array(new \RuntimeException('Whoops'))); - } - - /** - * @covers React\Stream\DuplexResourceStream::handleData - */ - public function testClosingStreamInDataEventShouldNotTriggerError() - { - $stream = fopen('php://temp', 'r+'); - $loop = $this->createLoopMock(); - - $conn = new DuplexResourceStream($stream, $loop); - $conn->on('error', $this->expectCallableNever()); - $conn->on('data', function ($data) use ($conn) { - $conn->close(); - }); - - fwrite($stream, "foobar\n"); - rewind($stream); - - $conn->handleData($stream); - } - - /** - * @covers React\Stream\DuplexResourceStream::handleData - */ - public function testDataFiltered() - { - $stream = fopen('php://temp', 'r+'); - - // add a filter which removes every 'a' when reading - Filter\append($stream, function ($chunk) { - return str_replace('a', '', $chunk); - }, STREAM_FILTER_READ); - - $loop = $this->createLoopMock(); - - $capturedData = null; - - $conn = new DuplexResourceStream($stream, $loop); - $conn->on('data', function ($data) use (&$capturedData) { - $capturedData = $data; - }); - - fwrite($stream, "foobar\n"); - rewind($stream); - - $conn->handleData($stream); - $this->assertSame("foobr\n", $capturedData); - } - - /** - * @covers React\Stream\DuplexResourceStream::handleData - */ - public function testDataErrorShouldEmitErrorAndClose() - { - $stream = fopen('php://temp', 'r+'); - - // add a filter which returns an error when encountering an 'a' when reading - Filter\append($stream, function ($chunk) { - if (strpos($chunk, 'a') !== false) { - throw new \Exception('Invalid'); - } - return $chunk; - }, STREAM_FILTER_READ); - - $loop = $this->createLoopMock(); - - $conn = new DuplexResourceStream($stream, $loop); - $conn->on('data', $this->expectCallableNever()); - $conn->on('error', $this->expectCallableOnce()); - $conn->on('close', $this->expectCallableOnce()); - - fwrite($stream, "foobar\n"); - rewind($stream); - - $conn->handleData($stream); - } - - private function createWriteableLoopMock() - { - $loop = $this->createLoopMock(); - $loop - ->expects($this->once()) - ->method('addWriteStream') - ->will($this->returnCallback(function ($stream, $listener) { - call_user_func($listener, $stream); - })); - - return $loop; - } - - private function createLoopMock() - { - return $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); - } -} diff --git a/assets/php/vendor/react/stream/tests/EnforceBlockingWrapper.php b/assets/php/vendor/react/stream/tests/EnforceBlockingWrapper.php deleted file mode 100755 index 39c0487..0000000 --- a/assets/php/vendor/react/stream/tests/EnforceBlockingWrapper.php +++ /dev/null @@ -1,35 +0,0 @@ -<?php - -namespace React\Tests\Stream; - -/** - * Used to test dummy stream resources that do not support setting non-blocking mode - * - * @link http://php.net/manual/de/class.streamwrapper.php - */ -class EnforceBlockingWrapper -{ - public function stream_open($path, $mode, $options, &$opened_path) - { - return true; - } - - public function stream_cast($cast_as) - { - return false; - } - - public function stream_eof() - { - return false; - } - - public function stream_set_option($option, $arg1, $arg2) - { - if ($option === STREAM_OPTION_BLOCKING) { - return false; - } - - return true; - } -} diff --git a/assets/php/vendor/react/stream/tests/FunctionalInternetTest.php b/assets/php/vendor/react/stream/tests/FunctionalInternetTest.php deleted file mode 100755 index 4d31e8e..0000000 --- a/assets/php/vendor/react/stream/tests/FunctionalInternetTest.php +++ /dev/null @@ -1,122 +0,0 @@ -<?php - -namespace React\Tests\Stream; - -use React\EventLoop\Factory; -use React\EventLoop\LoopInterface; -use React\Stream\DuplexResourceStream; -use React\Stream\WritableResourceStream; - -/** - * @group internet - */ -class FunctionalInternetTest extends TestCase -{ - public function testUploadKilobytePlain() - { - $size = 1000; - $stream = stream_socket_client('tcp://httpbin.org:80'); - - $loop = Factory::create(); - $stream = new DuplexResourceStream($stream, $loop); - - $buffer = ''; - $stream->on('data', function ($chunk) use (&$buffer) { - $buffer .= $chunk; - }); - - $stream->on('error', $this->expectCallableNever()); - - $stream->write("POST /post HTTP/1.0\r\nHost: httpbin.org\r\nContent-Length: $size\r\n\r\n" . str_repeat('.', $size)); - - $this->awaitStreamClose($stream, $loop); - - $this->assertNotEquals('', $buffer); - } - - public function testUploadBiggerBlockPlain() - { - $size = 50 * 1000; - $stream = stream_socket_client('tcp://httpbin.org:80'); - - $loop = Factory::create(); - $stream = new DuplexResourceStream($stream, $loop); - - $buffer = ''; - $stream->on('data', function ($chunk) use (&$buffer) { - $buffer .= $chunk; - }); - - $stream->on('error', $this->expectCallableNever()); - - $stream->write("POST /post HTTP/1.0\r\nHost: httpbin.org\r\nContent-Length: $size\r\n\r\n" . str_repeat('.', $size)); - - $this->awaitStreamClose($stream, $loop); - - $this->assertNotEquals('', $buffer); - } - - public function testUploadKilobyteSecure() - { - $size = 1000; - $stream = stream_socket_client('tls://httpbin.org:443'); - - $loop = Factory::create(); - $stream = new DuplexResourceStream($stream, $loop); - - $buffer = ''; - $stream->on('data', function ($chunk) use (&$buffer) { - $buffer .= $chunk; - }); - - $stream->on('error', $this->expectCallableNever()); - - $stream->write("POST /post HTTP/1.0\r\nHost: httpbin.org\r\nContent-Length: $size\r\n\r\n" . str_repeat('.', $size)); - - $this->awaitStreamClose($stream, $loop); - - $this->assertNotEquals('', $buffer); - } - - public function testUploadBiggerBlockSecureRequiresSmallerChunkSize() - { - $size = 50 * 1000; - $stream = stream_socket_client('tls://httpbin.org:443'); - - $loop = Factory::create(); - $stream = new DuplexResourceStream( - $stream, - $loop, - null, - new WritableResourceStream($stream, $loop, null, 8192) - ); - - $buffer = ''; - $stream->on('data', function ($chunk) use (&$buffer) { - $buffer .= $chunk; - }); - - $stream->on('error', $this->expectCallableNever()); - - $stream->write("POST /post HTTP/1.0\r\nHost: httpbin.org\r\nContent-Length: $size\r\n\r\n" . str_repeat('.', $size)); - - $this->awaitStreamClose($stream, $loop); - - $this->assertNotEquals('', $buffer); - } - - private function awaitStreamClose(DuplexResourceStream $stream, LoopInterface $loop, $timeout = 10.0) - { - $stream->on('close', function () use ($loop) { - $loop->stop(); - }); - - $that = $this; - $loop->addTimer($timeout, function () use ($loop, $that) { - $loop->stop(); - $that->fail('Timed out while waiting for stream to close'); - }); - - $loop->run(); - } -} diff --git a/assets/php/vendor/react/stream/tests/ReadableResourceStreamTest.php b/assets/php/vendor/react/stream/tests/ReadableResourceStreamTest.php deleted file mode 100755 index 20da96f..0000000 --- a/assets/php/vendor/react/stream/tests/ReadableResourceStreamTest.php +++ /dev/null @@ -1,372 +0,0 @@ -<?php - -namespace React\Tests\Stream; - -use React\Stream\ReadableResourceStream; -use Clue\StreamFilter as Filter; - -class ReadableResourceStreamTest extends TestCase -{ - /** - * @covers React\Stream\ReadableResourceStream::__construct - * @doesNotPerformAssertions - */ - public function testConstructor() - { - $stream = fopen('php://temp', 'r+'); - $loop = $this->createLoopMock(); - - new ReadableResourceStream($stream, $loop); - } - - /** - * @covers React\Stream\ReadableResourceStream::__construct - * @doesNotPerformAssertions - */ - public function testConstructorWithExcessiveMode() - { - // excessive flags are ignored for temp streams, so we have to use a file stream - $name = tempnam(sys_get_temp_dir(), 'test'); - $stream = @fopen($name, 'r+eANYTHING'); - unlink($name); - - $loop = $this->createLoopMock(); - $buffer = new ReadableResourceStream($stream, $loop); - $buffer->close(); - } - - /** - * @covers React\Stream\ReadableResourceStream::__construct - * @expectedException InvalidArgumentException - */ - public function testConstructorThrowsExceptionOnInvalidStream() - { - $loop = $this->createLoopMock(); - - new ReadableResourceStream(false, $loop); - } - - /** - * @covers React\Stream\ReadableResourceStream::__construct - * @expectedException InvalidArgumentException - */ - public function testConstructorThrowsExceptionOnWriteOnlyStream() - { - if (defined('HHVM_VERSION')) { - $this->markTestSkipped('HHVM does not report fopen mode for STDOUT'); - } - - $loop = $this->createLoopMock(); - - new ReadableResourceStream(STDOUT, $loop); - } - - /** - * @covers React\Stream\ReadableResourceStream::__construct - * @expectedException InvalidArgumentException - */ - public function testConstructorThrowsExceptionOnWriteOnlyStreamWithExcessiveMode() - { - // excessive flags are ignored for temp streams, so we have to use a file stream - $name = tempnam(sys_get_temp_dir(), 'test'); - $stream = fopen($name, 'weANYTHING'); - unlink($name); - - $loop = $this->createLoopMock(); - new ReadableResourceStream($stream, $loop); - } - - /** - * @covers React\Stream\ReadableResourceStream::__construct - * @expectedException RuntimeException - */ - public function testConstructorThrowsExceptionIfStreamDoesNotSupportNonBlocking() - { - if (!in_array('blocking', stream_get_wrappers())) { - stream_wrapper_register('blocking', 'React\Tests\Stream\EnforceBlockingWrapper'); - } - - $stream = fopen('blocking://test', 'r+'); - $loop = $this->createLoopMock(); - - new ReadableResourceStream($stream, $loop); - } - - - public function testCloseShouldEmitCloseEvent() - { - $stream = fopen('php://temp', 'r+'); - $loop = $this->createLoopMock(); - - $conn = new ReadableResourceStream($stream, $loop); - $conn->on('close', $this->expectCallableOnce()); - - $conn->close(); - - $this->assertFalse($conn->isReadable()); - } - - public function testCloseTwiceShouldEmitCloseEventOnce() - { - $stream = fopen('php://temp', 'r+'); - $loop = $this->createLoopMock(); - - $conn = new ReadableResourceStream($stream, $loop); - $conn->on('close', $this->expectCallableOnce()); - - $conn->close(); - $conn->close(); - } - - /** - * @covers React\Stream\ReadableResourceStream::__construct - * @covers React\Stream\ReadableResourceStream::handleData - */ - public function testDataEvent() - { - $stream = fopen('php://temp', 'r+'); - $loop = $this->createLoopMock(); - - $capturedData = null; - - $conn = new ReadableResourceStream($stream, $loop); - $conn->on('data', function ($data) use (&$capturedData) { - $capturedData = $data; - }); - - fwrite($stream, "foobar\n"); - rewind($stream); - - $conn->handleData($stream); - $this->assertSame("foobar\n", $capturedData); - } - - /** - * @covers React\Stream\ReadableResourceStream::__construct - * @covers React\Stream\ReadableResourceStream::handleData - */ - public function testDataEventDoesEmitOneChunkMatchingBufferSize() - { - $stream = fopen('php://temp', 'r+'); - $loop = $this->createLoopMock(); - - $capturedData = null; - - $conn = new ReadableResourceStream($stream, $loop, 4321); - $conn->on('data', function ($data) use (&$capturedData) { - $capturedData = $data; - }); - - fwrite($stream, str_repeat("a", 100000)); - rewind($stream); - - $conn->handleData($stream); - - $this->assertTrue($conn->isReadable()); - $this->assertEquals(4321, strlen($capturedData)); - } - - /** - * @covers React\Stream\ReadableResourceStream::__construct - * @covers React\Stream\ReadableResourceStream::handleData - */ - public function testDataEventDoesEmitOneChunkUntilStreamEndsWhenBufferSizeIsInfinite() - { - $stream = fopen('php://temp', 'r+'); - $loop = $this->createLoopMock(); - - $capturedData = null; - - $conn = new ReadableResourceStream($stream, $loop, -1); - - $conn->on('data', function ($data) use (&$capturedData) { - $capturedData = $data; - }); - - fwrite($stream, str_repeat("a", 100000)); - rewind($stream); - - $conn->handleData($stream); - - $this->assertTrue($conn->isReadable()); - $this->assertEquals(100000, strlen($capturedData)); - } - - /** - * @covers React\Stream\ReadableResourceStream::handleData - */ - public function testEmptyStreamShouldNotEmitData() - { - $stream = fopen('php://temp', 'r+'); - $loop = $this->createLoopMock(); - - $conn = new ReadableResourceStream($stream, $loop); - $conn->on('data', $this->expectCallableNever()); - - $conn->handleData($stream); - } - - public function testPipeShouldReturnDestination() - { - $stream = fopen('php://temp', 'r+'); - $loop = $this->createLoopMock(); - - $conn = new ReadableResourceStream($stream, $loop); - $dest = $this->getMockBuilder('React\Stream\WritableStreamInterface')->getMock(); - - $this->assertSame($dest, $conn->pipe($dest)); - } - - /** - * @covers React\Stream\ReadableResourceStream::handleData - */ - public function testClosingStreamInDataEventShouldNotTriggerError() - { - $stream = fopen('php://temp', 'r+'); - $loop = $this->createLoopMock(); - - $conn = new ReadableResourceStream($stream, $loop); - $conn->on('error', $this->expectCallableNever()); - $conn->on('data', function ($data) use ($conn) { - $conn->close(); - }); - - fwrite($stream, "foobar\n"); - rewind($stream); - - $conn->handleData($stream); - } - - /** - * @covers React\Stream\ReadableResourceStream::pause - */ - public function testPauseRemovesReadStreamFromLoop() - { - $stream = fopen('php://temp', 'r+'); - $loop = $this->createLoopMock(); - $loop->expects($this->once())->method('addReadStream')->with($stream); - $loop->expects($this->once())->method('removeReadStream')->with($stream); - - $conn = new ReadableResourceStream($stream, $loop); - $conn->pause(); - $conn->pause(); - } - - /** - * @covers React\Stream\ReadableResourceStream::pause - */ - public function testResumeDoesAddStreamToLoopOnlyOnce() - { - $stream = fopen('php://temp', 'r+'); - $loop = $this->createLoopMock(); - $loop->expects($this->once())->method('addReadStream')->with($stream); - - $conn = new ReadableResourceStream($stream, $loop); - $conn->resume(); - $conn->resume(); - } - - /** - * @covers React\Stream\ReadableResourceStream::close - */ - public function testCloseRemovesReadStreamFromLoop() - { - $stream = fopen('php://temp', 'r+'); - $loop = $this->createLoopMock(); - $loop->expects($this->once())->method('addReadStream')->with($stream); - $loop->expects($this->once())->method('removeReadStream')->with($stream); - - $conn = new ReadableResourceStream($stream, $loop); - $conn->close(); - } - - /** - * @covers React\Stream\ReadableResourceStream::close - */ - public function testCloseAfterPauseRemovesReadStreamFromLoopOnce() - { - $stream = fopen('php://temp', 'r+'); - $loop = $this->createLoopMock(); - $loop->expects($this->once())->method('addReadStream')->with($stream); - $loop->expects($this->once())->method('removeReadStream')->with($stream); - - $conn = new ReadableResourceStream($stream, $loop); - $conn->pause(); - $conn->close(); - } - - /** - * @covers React\Stream\ReadableResourceStream::close - */ - public function testResumeAfterCloseDoesAddReadStreamToLoopOnlyOnce() - { - $stream = fopen('php://temp', 'r+'); - $loop = $this->createLoopMock(); - $loop->expects($this->once())->method('addReadStream')->with($stream); - - $conn = new ReadableResourceStream($stream, $loop); - $conn->close(); - $conn->resume(); - } - - /** - * @covers React\Stream\ReadableResourceStream::handleData - */ - public function testDataFiltered() - { - $stream = fopen('php://temp', 'r+'); - - // add a filter which removes every 'a' when reading - Filter\append($stream, function ($chunk) { - return str_replace('a', '', $chunk); - }, STREAM_FILTER_READ); - - $loop = $this->createLoopMock(); - - $capturedData = null; - - $conn = new ReadableResourceStream($stream, $loop); - $conn->on('data', function ($data) use (&$capturedData) { - $capturedData = $data; - }); - - fwrite($stream, "foobar\n"); - rewind($stream); - - $conn->handleData($stream); - $this->assertSame("foobr\n", $capturedData); - } - - /** - * @covers React\Stream\ReadableResourceStream::handleData - */ - public function testDataErrorShouldEmitErrorAndClose() - { - $stream = fopen('php://temp', 'r+'); - - // add a filter which returns an error when encountering an 'a' when reading - Filter\append($stream, function ($chunk) { - if (strpos($chunk, 'a') !== false) { - throw new \Exception('Invalid'); - } - return $chunk; - }, STREAM_FILTER_READ); - - $loop = $this->createLoopMock(); - - $conn = new ReadableResourceStream($stream, $loop); - $conn->on('data', $this->expectCallableNever()); - $conn->on('error', $this->expectCallableOnce()); - $conn->on('close', $this->expectCallableOnce()); - - fwrite($stream, "foobar\n"); - rewind($stream); - - $conn->handleData($stream); - } - - private function createLoopMock() - { - return $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); - } -} diff --git a/assets/php/vendor/react/stream/tests/Stub/ReadableStreamStub.php b/assets/php/vendor/react/stream/tests/Stub/ReadableStreamStub.php deleted file mode 100755 index 6984f24..0000000 --- a/assets/php/vendor/react/stream/tests/Stub/ReadableStreamStub.php +++ /dev/null @@ -1,61 +0,0 @@ -<?php - -namespace React\Tests\Stream\Stub; - -use Evenement\EventEmitter; -use React\Stream\ReadableStreamInterface; -use React\Stream\WritableStreamInterface; -use React\Stream\Util; - -class ReadableStreamStub extends EventEmitter implements ReadableStreamInterface -{ - public $readable = true; - public $paused = false; - - public function isReadable() - { - return true; - } - - // trigger data event - public function write($data) - { - $this->emit('data', array($data)); - } - - // trigger error event - public function error($error) - { - $this->emit('error', array($error)); - } - - // trigger end event - public function end() - { - $this->emit('end', array()); - } - - public function pause() - { - $this->paused = true; - } - - public function resume() - { - $this->paused = false; - } - - public function close() - { - $this->readable = false; - - $this->emit('close'); - } - - public function pipe(WritableStreamInterface $dest, array $options = array()) - { - Util::pipe($this, $dest, $options); - - return $dest; - } -} diff --git a/assets/php/vendor/react/stream/tests/TestCase.php b/assets/php/vendor/react/stream/tests/TestCase.php deleted file mode 100755 index c8fc1db..0000000 --- a/assets/php/vendor/react/stream/tests/TestCase.php +++ /dev/null @@ -1,54 +0,0 @@ -<?php - -namespace React\Tests\Stream; - -use PHPUnit\Framework\TestCase as BaseTestCase; - -class TestCase extends BaseTestCase -{ - protected function expectCallableExactly($amount) - { - $mock = $this->createCallableMock(); - $mock - ->expects($this->exactly($amount)) - ->method('__invoke'); - - return $mock; - } - - protected function expectCallableOnce() - { - $mock = $this->createCallableMock(); - $mock - ->expects($this->once()) - ->method('__invoke'); - - return $mock; - } - - protected function expectCallableOnceWith($value) - { - $callback = $this->createCallableMock(); - $callback - ->expects($this->once()) - ->method('__invoke') - ->with($value); - - return $callback; - } - - protected function expectCallableNever() - { - $mock = $this->createCallableMock(); - $mock - ->expects($this->never()) - ->method('__invoke'); - - return $mock; - } - - protected function createCallableMock() - { - return $this->getMockBuilder('React\Tests\Stream\CallableStub')->getMock(); - } -} diff --git a/assets/php/vendor/react/stream/tests/ThroughStreamTest.php b/assets/php/vendor/react/stream/tests/ThroughStreamTest.php deleted file mode 100755 index a98badf..0000000 --- a/assets/php/vendor/react/stream/tests/ThroughStreamTest.php +++ /dev/null @@ -1,267 +0,0 @@ -<?php - -namespace React\Tests\Stream; - -use React\Stream\ThroughStream; - -/** - * @covers React\Stream\ThroughStream - */ -class ThroughStreamTest extends TestCase -{ - /** - * @test - * @expectedException InvalidArgumentException - */ - public function itShouldRejectInvalidCallback() - { - new ThroughStream(123); - } - - /** @test */ - public function itShouldReturnTrueForAnyDataWrittenToIt() - { - $through = new ThroughStream(); - $ret = $through->write('foo'); - - $this->assertTrue($ret); - } - - /** @test */ - public function itShouldEmitAnyDataWrittenToIt() - { - $through = new ThroughStream(); - $through->on('data', $this->expectCallableOnceWith('foo')); - $through->write('foo'); - } - - /** @test */ - public function itShouldEmitAnyDataWrittenToItPassedThruFunction() - { - $through = new ThroughStream('strtoupper'); - $through->on('data', $this->expectCallableOnceWith('FOO')); - $through->write('foo'); - } - - /** @test */ - public function itShouldEmitAnyDataWrittenToItPassedThruCallback() - { - $through = new ThroughStream('strtoupper'); - $through->on('data', $this->expectCallableOnceWith('FOO')); - $through->write('foo'); - } - - /** @test */ - public function itShouldEmitErrorAndCloseIfCallbackThrowsException() - { - $through = new ThroughStream(function () { - throw new \RuntimeException(); - }); - $through->on('error', $this->expectCallableOnce()); - $through->on('close', $this->expectCallableOnce()); - $through->on('data', $this->expectCallableNever()); - $through->on('end', $this->expectCallableNever()); - - $through->write('foo'); - - $this->assertFalse($through->isReadable()); - $this->assertFalse($through->isWritable()); - } - - /** @test */ - public function itShouldEmitErrorAndCloseIfCallbackThrowsExceptionOnEnd() - { - $through = new ThroughStream(function () { - throw new \RuntimeException(); - }); - $through->on('error', $this->expectCallableOnce()); - $through->on('close', $this->expectCallableOnce()); - $through->on('data', $this->expectCallableNever()); - $through->on('end', $this->expectCallableNever()); - - $through->end('foo'); - - $this->assertFalse($through->isReadable()); - $this->assertFalse($through->isWritable()); - } - - /** @test */ - public function itShouldReturnFalseForAnyDataWrittenToItWhenPaused() - { - $through = new ThroughStream(); - $through->pause(); - $ret = $through->write('foo'); - - $this->assertFalse($ret); - } - - /** @test */ - public function itShouldEmitDrainOnResumeAfterReturnFalseForAnyDataWrittenToItWhenPaused() - { - $through = new ThroughStream(); - $through->pause(); - $through->write('foo'); - - $through->on('drain', $this->expectCallableOnce()); - $through->resume(); - } - - /** @test */ - public function itShouldReturnTrueForAnyDataWrittenToItWhenResumedAfterPause() - { - $through = new ThroughStream(); - $through->on('drain', $this->expectCallableNever()); - $through->pause(); - $through->resume(); - $ret = $through->write('foo'); - - $this->assertTrue($ret); - } - - /** @test */ - public function pipingStuffIntoItShouldWork() - { - $readable = new ThroughStream(); - - $through = new ThroughStream(); - $through->on('data', $this->expectCallableOnceWith('foo')); - - $readable->pipe($through); - $readable->emit('data', array('foo')); - } - - /** @test */ - public function endShouldEmitEndAndClose() - { - $through = new ThroughStream(); - $through->on('data', $this->expectCallableNever()); - $through->on('end', $this->expectCallableOnce()); - $through->on('close', $this->expectCallableOnce()); - $through->end(); - } - - /** @test */ - public function endShouldCloseTheStream() - { - $through = new ThroughStream(); - $through->on('data', $this->expectCallableNever()); - $through->end(); - - $this->assertFalse($through->isReadable()); - $this->assertFalse($through->isWritable()); - } - - /** @test */ - public function endShouldWriteDataBeforeClosing() - { - $through = new ThroughStream(); - $through->on('data', $this->expectCallableOnceWith('foo')); - $through->end('foo'); - - $this->assertFalse($through->isReadable()); - $this->assertFalse($through->isWritable()); - } - - /** @test */ - public function endTwiceShouldOnlyEmitOnce() - { - $through = new ThroughStream(); - $through->on('data', $this->expectCallableOnce('first')); - $through->end('first'); - $through->end('ignored'); - } - - /** @test */ - public function writeAfterEndShouldReturnFalse() - { - $through = new ThroughStream(); - $through->on('data', $this->expectCallableNever()); - $through->end(); - - $this->assertFalse($through->write('foo')); - } - - /** @test */ - public function writeDataWillCloseStreamShouldReturnFalse() - { - $through = new ThroughStream(); - $through->on('data', array($through, 'close')); - - $this->assertFalse($through->write('foo')); - } - - /** @test */ - public function writeDataToPausedShouldReturnFalse() - { - $through = new ThroughStream(); - $through->pause(); - - $this->assertFalse($through->write('foo')); - } - - /** @test */ - public function writeDataToResumedShouldReturnTrue() - { - $through = new ThroughStream(); - $through->pause(); - $through->resume(); - - $this->assertTrue($through->write('foo')); - } - - /** @test */ - public function itShouldBeReadableByDefault() - { - $through = new ThroughStream(); - $this->assertTrue($through->isReadable()); - } - - /** @test */ - public function itShouldBeWritableByDefault() - { - $through = new ThroughStream(); - $this->assertTrue($through->isWritable()); - } - - /** @test */ - public function closeShouldCloseOnce() - { - $through = new ThroughStream(); - - $through->on('close', $this->expectCallableOnce()); - - $through->close(); - - $this->assertFalse($through->isReadable()); - $this->assertFalse($through->isWritable()); - } - - /** @test */ - public function doubleCloseShouldCloseOnce() - { - $through = new ThroughStream(); - - $through->on('close', $this->expectCallableOnce()); - - $through->close(); - $through->close(); - - $this->assertFalse($through->isReadable()); - $this->assertFalse($through->isWritable()); - } - - /** @test */ - public function pipeShouldPipeCorrectly() - { - $output = $this->getMockBuilder('React\Stream\WritableStreamInterface')->getMock(); - $output->expects($this->any())->method('isWritable')->willReturn(True); - $output - ->expects($this->once()) - ->method('write') - ->with('foo'); - - $through = new ThroughStream(); - $through->pipe($output); - $through->write('foo'); - } -} diff --git a/assets/php/vendor/react/stream/tests/UtilTest.php b/assets/php/vendor/react/stream/tests/UtilTest.php deleted file mode 100755 index 3d113ab..0000000 --- a/assets/php/vendor/react/stream/tests/UtilTest.php +++ /dev/null @@ -1,273 +0,0 @@ -<?php - -namespace React\Tests\Stream; - -use React\Stream\WritableResourceStream; -use React\Stream\Util; -use React\Stream\CompositeStream; -use React\Stream\ThroughStream; - -/** - * @covers React\Stream\Util - */ -class UtilTest extends TestCase -{ - public function testPipeReturnsDestinationStream() - { - $readable = $this->getMockBuilder('React\Stream\ReadableStreamInterface')->getMock(); - - $writable = $this->getMockBuilder('React\Stream\WritableStreamInterface')->getMock(); - - $ret = Util::pipe($readable, $writable); - - $this->assertSame($writable, $ret); - } - - public function testPipeNonReadableSourceShouldDoNothing() - { - $readable = $this->getMockBuilder('React\Stream\ReadableStreamInterface')->getMock(); - $readable - ->expects($this->any()) - ->method('isReadable') - ->willReturn(false); - - $writable = $this->getMockBuilder('React\Stream\WritableStreamInterface')->getMock(); - $writable - ->expects($this->never()) - ->method('isWritable'); - $writable - ->expects($this->never()) - ->method('end'); - - Util::pipe($readable, $writable); - } - - public function testPipeIntoNonWritableDestinationShouldPauseSource() - { - $readable = $this->getMockBuilder('React\Stream\ReadableStreamInterface')->getMock(); - $readable - ->expects($this->any()) - ->method('isReadable') - ->willReturn(true); - $readable - ->expects($this->once()) - ->method('pause'); - - $writable = $this->getMockBuilder('React\Stream\WritableStreamInterface')->getMock(); - $writable - ->expects($this->any()) - ->method('isWritable') - ->willReturn(false); - $writable - ->expects($this->never()) - ->method('end'); - - Util::pipe($readable, $writable); - } - - public function testPipeClosingDestPausesSource() - { - $readable = $this->getMockBuilder('React\Stream\ReadableStreamInterface')->getMock(); - $readable - ->expects($this->any()) - ->method('isReadable') - ->willReturn(true); - $readable - ->expects($this->once()) - ->method('pause'); - - $writable = new ThroughStream(); - - Util::pipe($readable, $writable); - - $writable->close(); - } - - public function testPipeWithEnd() - { - $readable = new Stub\ReadableStreamStub(); - - $writable = $this->getMockBuilder('React\Stream\WritableStreamInterface')->getMock(); - $writable - ->expects($this->any()) - ->method('isWritable') - ->willReturn(true); - $writable - ->expects($this->once()) - ->method('end'); - - Util::pipe($readable, $writable); - - $readable->end(); - } - - public function testPipeWithoutEnd() - { - $readable = new Stub\ReadableStreamStub(); - - $writable = $this->getMockBuilder('React\Stream\WritableStreamInterface')->getMock(); - $writable - ->expects($this->any()) - ->method('isWritable') - ->willReturn(true); - $writable - ->expects($this->never()) - ->method('end'); - - Util::pipe($readable, $writable, array('end' => false)); - - $readable->end(); - } - - public function testPipeWithTooSlowWritableShouldPauseReadable() - { - $readable = new Stub\ReadableStreamStub(); - - $writable = $this->getMockBuilder('React\Stream\WritableStreamInterface')->getMock(); - $writable - ->expects($this->any()) - ->method('isWritable') - ->willReturn(true); - $writable - ->expects($this->once()) - ->method('write') - ->with('some data') - ->will($this->returnValue(false)); - - $readable->pipe($writable); - - $this->assertFalse($readable->paused); - $readable->write('some data'); - $this->assertTrue($readable->paused); - } - - public function testPipeWithTooSlowWritableShouldResumeOnDrain() - { - $readable = new Stub\ReadableStreamStub(); - - $onDrain = null; - - $writable = $this->getMockBuilder('React\Stream\WritableStreamInterface')->getMock(); - $writable - ->expects($this->any()) - ->method('isWritable') - ->willReturn(true); - $writable - ->expects($this->any()) - ->method('on') - ->will($this->returnCallback(function ($name, $callback) use (&$onDrain) { - if ($name === 'drain') { - $onDrain = $callback; - } - })); - - $readable->pipe($writable); - $readable->pause(); - - $this->assertTrue($readable->paused); - $this->assertNotNull($onDrain); - $onDrain(); - $this->assertFalse($readable->paused); - } - - public function testPipeWithWritableResourceStream() - { - $readable = new Stub\ReadableStreamStub(); - - $stream = fopen('php://temp', 'r+'); - $loop = $this->createLoopMock(); - $buffer = new WritableResourceStream($stream, $loop); - - $readable->pipe($buffer); - - $readable->write('hello, I am some '); - $readable->write('random data'); - - $buffer->handleWrite(); - rewind($stream); - $this->assertSame('hello, I am some random data', stream_get_contents($stream)); - } - - public function testPipeSetsUpListeners() - { - $source = new ThroughStream(); - $dest = new ThroughStream(); - - $this->assertCount(0, $source->listeners('data')); - $this->assertCount(0, $source->listeners('end')); - $this->assertCount(0, $dest->listeners('drain')); - - Util::pipe($source, $dest); - - $this->assertCount(1, $source->listeners('data')); - $this->assertCount(1, $source->listeners('end')); - $this->assertCount(1, $dest->listeners('drain')); - } - - public function testPipeClosingSourceRemovesListeners() - { - $source = new ThroughStream(); - $dest = new ThroughStream(); - - Util::pipe($source, $dest); - - $source->close(); - - $this->assertCount(0, $source->listeners('data')); - $this->assertCount(0, $source->listeners('end')); - $this->assertCount(0, $dest->listeners('drain')); - } - - public function testPipeClosingDestRemovesListeners() - { - $source = new ThroughStream(); - $dest = new ThroughStream(); - - Util::pipe($source, $dest); - - $dest->close(); - - $this->assertCount(0, $source->listeners('data')); - $this->assertCount(0, $source->listeners('end')); - $this->assertCount(0, $dest->listeners('drain')); - } - - public function testPipeDuplexIntoSelfEndsOnEnd() - { - $readable = $this->getMockBuilder('React\Stream\ReadableStreamInterface')->getMock(); - $readable->expects($this->any())->method('isReadable')->willReturn(true); - $writable = $this->getMockBuilder('React\Stream\WritableStreamInterface')->getMock(); - $writable->expects($this->any())->method('isWritable')->willReturn(true); - $duplex = new CompositeStream($readable, $writable); - - Util::pipe($duplex, $duplex); - - $writable->expects($this->once())->method('end'); - - $duplex->emit('end'); - } - - /** @test */ - public function forwardEventsShouldSetupForwards() - { - $source = new ThroughStream(); - $target = new ThroughStream(); - - Util::forwardEvents($source, $target, array('data')); - $target->on('data', $this->expectCallableOnce()); - $target->on('foo', $this->expectCallableNever()); - - $source->emit('data', array('hello')); - $source->emit('foo', array('bar')); - } - - private function createLoopMock() - { - return $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); - } - - private function notEqualTo($value) - { - return new \PHPUnit_Framework_Constraint_Not($value); - } -} diff --git a/assets/php/vendor/react/stream/tests/WritableStreamResourceTest.php b/assets/php/vendor/react/stream/tests/WritableStreamResourceTest.php deleted file mode 100755 index 05bce9c..0000000 --- a/assets/php/vendor/react/stream/tests/WritableStreamResourceTest.php +++ /dev/null @@ -1,534 +0,0 @@ -<?php - -namespace React\Tests\Stream; - -use Clue\StreamFilter as Filter; -use React\Stream\WritableResourceStream; - -class WritableResourceStreamTest extends TestCase -{ - /** - * @covers React\Stream\WritableResourceStream::__construct - * @doesNotPerformAssertions - */ - public function testConstructor() - { - $stream = fopen('php://temp', 'r+'); - $loop = $this->createLoopMock(); - - new WritableResourceStream($stream, $loop); - } - - /** - * @covers React\Stream\WritableResourceStream::__construct - * @doesNotPerformAssertions - */ - public function testConstructorWithExcessiveMode() - { - // excessive flags are ignored for temp streams, so we have to use a file stream - $name = tempnam(sys_get_temp_dir(), 'test'); - $stream = @fopen($name, 'w+eANYTHING'); - unlink($name); - - $loop = $this->createLoopMock(); - $buffer = new WritableResourceStream($stream, $loop); - $buffer->close(); - } - - /** - * @covers React\Stream\WritableResourceStream::__construct - * @expectedException InvalidArgumentException - */ - public function testConstructorThrowsIfNotAValidStreamResource() - { - $stream = null; - $loop = $this->createLoopMock(); - - new WritableResourceStream($stream, $loop); - } - - /** - * @covers React\Stream\WritableResourceStream::__construct - * @expectedException InvalidArgumentException - */ - public function testConstructorThrowsExceptionOnReadOnlyStream() - { - $stream = fopen('php://temp', 'r'); - $loop = $this->createLoopMock(); - - new WritableResourceStream($stream, $loop); - } - - /** - * @covers React\Stream\WritableResourceStream::__construct - * @expectedException InvalidArgumentException - */ - public function testConstructorThrowsExceptionOnReadOnlyStreamWithExcessiveMode() - { - // excessive flags are ignored for temp streams, so we have to use a file stream - $name = tempnam(sys_get_temp_dir(), 'test'); - $stream = fopen($name, 'reANYTHING'); - unlink($name); - - $loop = $this->createLoopMock(); - new WritableResourceStream($stream, $loop); - } - - /** - * @covers React\Stream\WritableResourceStream::__construct - * @expectedException RuntimeException - */ - public function testConstructorThrowsExceptionIfStreamDoesNotSupportNonBlocking() - { - if (!in_array('blocking', stream_get_wrappers())) { - stream_wrapper_register('blocking', 'React\Tests\Stream\EnforceBlockingWrapper'); - } - - $stream = fopen('blocking://test', 'r+'); - $loop = $this->createLoopMock(); - - new WritableResourceStream($stream, $loop); - } - - /** - * @covers React\Stream\WritableResourceStream::write - * @covers React\Stream\WritableResourceStream::handleWrite - */ - public function testWrite() - { - $stream = fopen('php://temp', 'r+'); - $loop = $this->createWriteableLoopMock(); - - $buffer = new WritableResourceStream($stream, $loop); - $buffer->on('error', $this->expectCallableNever()); - - $buffer->write("foobar\n"); - rewind($stream); - $this->assertSame("foobar\n", fread($stream, 1024)); - } - - /** - * @covers React\Stream\WritableResourceStream::write - */ - public function testWriteWithDataDoesAddResourceToLoop() - { - $stream = fopen('php://temp', 'r+'); - $loop = $this->createLoopMock(); - $loop->expects($this->once())->method('addWriteStream')->with($this->equalTo($stream)); - - $buffer = new WritableResourceStream($stream, $loop); - - $buffer->write("foobar\n"); - } - - /** - * @covers React\Stream\WritableResourceStream::write - * @covers React\Stream\WritableResourceStream::handleWrite - */ - public function testEmptyWriteDoesNotAddToLoop() - { - $stream = fopen('php://temp', 'r+'); - $loop = $this->createLoopMock(); - $loop->expects($this->never())->method('addWriteStream'); - - $buffer = new WritableResourceStream($stream, $loop); - - $buffer->write(""); - $buffer->write(null); - } - - /** - * @covers React\Stream\WritableResourceStream::write - * @covers React\Stream\WritableResourceStream::handleWrite - */ - public function testWriteReturnsFalseWhenWritableResourceStreamIsFull() - { - $stream = fopen('php://temp', 'r+'); - $loop = $this->createWriteableLoopMock(); - $loop->preventWrites = true; - - $buffer = new WritableResourceStream($stream, $loop, 4); - $buffer->on('error', $this->expectCallableNever()); - - $this->assertTrue($buffer->write("foo")); - $loop->preventWrites = false; - $this->assertFalse($buffer->write("bar\n")); - } - - /** - * @covers React\Stream\WritableResourceStream::write - */ - public function testWriteReturnsFalseWhenWritableResourceStreamIsExactlyFull() - { - $stream = fopen('php://temp', 'r+'); - $loop = $this->createLoopMock(); - - $buffer = new WritableResourceStream($stream, $loop, 3); - - $this->assertFalse($buffer->write("foo")); - } - - /** - * @covers React\Stream\WritableResourceStream::write - * @covers React\Stream\WritableResourceStream::handleWrite - */ - public function testWriteDetectsWhenOtherSideIsClosed() - { - list($a, $b) = stream_socket_pair(STREAM_PF_UNIX, STREAM_SOCK_STREAM, STREAM_IPPROTO_IP); - - $loop = $this->createWriteableLoopMock(); - - $buffer = new WritableResourceStream($a, $loop, 4); - $buffer->on('error', $this->expectCallableOnce()); - - fclose($b); - - $buffer->write("foo"); - } - - /** - * @covers React\Stream\WritableResourceStream::write - * @covers React\Stream\WritableResourceStream::handleWrite - */ - public function testEmitsDrainAfterWriteWhichExceedsBuffer() - { - $stream = fopen('php://temp', 'r+'); - $loop = $this->createLoopMock(); - - $buffer = new WritableResourceStream($stream, $loop, 2); - $buffer->on('error', $this->expectCallableNever()); - $buffer->on('drain', $this->expectCallableOnce()); - - $buffer->write("foo"); - $buffer->handleWrite(); - } - - /** - * @covers React\Stream\WritableResourceStream::write - * @covers React\Stream\WritableResourceStream::handleWrite - */ - public function testWriteInDrain() - { - $stream = fopen('php://temp', 'r+'); - $loop = $this->createLoopMock(); - - $buffer = new WritableResourceStream($stream, $loop, 2); - $buffer->on('error', $this->expectCallableNever()); - - $buffer->once('drain', function () use ($buffer) { - $buffer->write("bar\n"); - $buffer->handleWrite(); - }); - - $this->assertFalse($buffer->write("foo\n")); - $buffer->handleWrite(); - - fseek($stream, 0); - $this->assertSame("foo\nbar\n", stream_get_contents($stream)); - } - - /** - * @covers React\Stream\WritableResourceStream::write - * @covers React\Stream\WritableResourceStream::handleWrite - */ - public function testDrainAfterWrite() - { - $stream = fopen('php://temp', 'r+'); - $loop = $this->createLoopMock(); - - $buffer = new WritableResourceStream($stream, $loop, 2); - - $buffer->on('drain', $this->expectCallableOnce()); - - $buffer->write("foo"); - $buffer->handleWrite(); - } - - /** - * @covers React\Stream\WritableResourceStream::handleWrite - */ - public function testDrainAfterWriteWillRemoveResourceFromLoopWithoutClosing() - { - $stream = fopen('php://temp', 'r+'); - $loop = $this->createLoopMock(); - $loop->expects($this->once())->method('removeWriteStream')->with($stream); - - $buffer = new WritableResourceStream($stream, $loop, 2); - - $buffer->on('drain', $this->expectCallableOnce()); - - $buffer->on('close', $this->expectCallableNever()); - - $buffer->write("foo"); - $buffer->handleWrite(); - } - - /** - * @covers React\Stream\WritableResourceStream::handleWrite - */ - public function testClosingDuringDrainAfterWriteWillRemoveResourceFromLoopOnceAndClose() - { - $stream = fopen('php://temp', 'r+'); - $loop = $this->createLoopMock(); - $loop->expects($this->once())->method('removeWriteStream')->with($stream); - - $buffer = new WritableResourceStream($stream, $loop, 2); - - $buffer->on('drain', function () use ($buffer) { - $buffer->close(); - }); - - $buffer->on('close', $this->expectCallableOnce()); - - $buffer->write("foo"); - $buffer->handleWrite(); - } - - /** - * @covers React\Stream\WritableResourceStream::end - */ - public function testEndWithoutDataClosesImmediatelyIfWritableResourceStreamIsEmpty() - { - $stream = fopen('php://temp', 'r+'); - $loop = $this->createLoopMock(); - - $buffer = new WritableResourceStream($stream, $loop); - $buffer->on('error', $this->expectCallableNever()); - $buffer->on('close', $this->expectCallableOnce()); - - $this->assertTrue($buffer->isWritable()); - $buffer->end(); - $this->assertFalse($buffer->isWritable()); - } - - /** - * @covers React\Stream\WritableResourceStream::end - */ - public function testEndWithoutDataDoesNotCloseIfWritableResourceStreamIsFull() - { - $stream = fopen('php://temp', 'r+'); - $loop = $this->createLoopMock(); - - $buffer = new WritableResourceStream($stream, $loop); - $buffer->on('error', $this->expectCallableNever()); - $buffer->on('close', $this->expectCallableNever()); - - $buffer->write('foo'); - - $this->assertTrue($buffer->isWritable()); - $buffer->end(); - $this->assertFalse($buffer->isWritable()); - } - - /** - * @covers React\Stream\WritableResourceStream::end - */ - public function testEndWithDataClosesImmediatelyIfWritableResourceStreamFlushes() - { - $stream = fopen('php://temp', 'r+'); - $filterBuffer = ''; - $loop = $this->createLoopMock(); - - $buffer = new WritableResourceStream($stream, $loop); - $buffer->on('error', $this->expectCallableNever()); - $buffer->on('close', $this->expectCallableOnce()); - - Filter\append($stream, function ($chunk) use (&$filterBuffer) { - $filterBuffer .= $chunk; - return $chunk; - }); - - $this->assertTrue($buffer->isWritable()); - $buffer->end('final words'); - $this->assertFalse($buffer->isWritable()); - - $buffer->handleWrite(); - $this->assertSame('final words', $filterBuffer); - } - - /** - * @covers React\Stream\WritableResourceStream::end - */ - public function testEndWithDataDoesNotCloseImmediatelyIfWritableResourceStreamIsFull() - { - $stream = fopen('php://temp', 'r+'); - $loop = $this->createLoopMock(); - - $buffer = new WritableResourceStream($stream, $loop); - $buffer->on('error', $this->expectCallableNever()); - $buffer->on('close', $this->expectCallableNever()); - - $buffer->write('foo'); - - $this->assertTrue($buffer->isWritable()); - $buffer->end('final words'); - $this->assertFalse($buffer->isWritable()); - - rewind($stream); - $this->assertSame('', stream_get_contents($stream)); - } - - /** - * @covers React\Stream\WritableResourceStream::isWritable - * @covers React\Stream\WritableResourceStream::close - */ - public function testClose() - { - $stream = fopen('php://temp', 'r+'); - $loop = $this->createLoopMock(); - - $buffer = new WritableResourceStream($stream, $loop); - $buffer->on('error', $this->expectCallableNever()); - $buffer->on('close', $this->expectCallableOnce()); - - $this->assertTrue($buffer->isWritable()); - $buffer->close(); - $this->assertFalse($buffer->isWritable()); - - $this->assertEquals(array(), $buffer->listeners('close')); - } - - /** - * @covers React\Stream\WritableResourceStream::close - */ - public function testClosingAfterWriteRemovesStreamFromLoop() - { - $stream = fopen('php://temp', 'r+'); - $loop = $this->createLoopMock(); - $buffer = new WritableResourceStream($stream, $loop); - - $loop->expects($this->once())->method('removeWriteStream')->with($stream); - - $buffer->write('foo'); - $buffer->close(); - } - - /** - * @covers React\Stream\WritableResourceStream::close - */ - public function testClosingWithoutWritingDoesNotRemoveStreamFromLoop() - { - $stream = fopen('php://temp', 'r+'); - $loop = $this->createLoopMock(); - $buffer = new WritableResourceStream($stream, $loop); - - $loop->expects($this->never())->method('removeWriteStream'); - - $buffer->close(); - } - - /** - * @covers React\Stream\WritableResourceStream::close - */ - public function testDoubleCloseWillEmitOnlyOnce() - { - $stream = fopen('php://temp', 'r+'); - $loop = $this->createLoopMock(); - - $buffer = new WritableResourceStream($stream, $loop); - $buffer->on('close', $this->expectCallableOnce()); - - $buffer->close(); - $buffer->close(); - } - - /** - * @covers React\Stream\WritableResourceStream::write - * @covers React\Stream\WritableResourceStream::close - */ - public function testWritingToClosedWritableResourceStreamShouldNotWriteToStream() - { - $stream = fopen('php://temp', 'r+'); - $filterBuffer = ''; - $loop = $this->createLoopMock(); - - $buffer = new WritableResourceStream($stream, $loop); - - Filter\append($stream, function ($chunk) use (&$filterBuffer) { - $filterBuffer .= $chunk; - return $chunk; - }); - - $buffer->close(); - - $buffer->write('foo'); - - $buffer->handleWrite(); - $this->assertSame('', $filterBuffer); - } - - /** - * @covers React\Stream\WritableResourceStream::handleWrite - */ - public function testErrorWhenStreamResourceIsInvalid() - { - $stream = fopen('php://temp', 'r+'); - $loop = $this->createWriteableLoopMock(); - - $error = null; - - $buffer = new WritableResourceStream($stream, $loop); - $buffer->on('error', function ($message) use (&$error) { - $error = $message; - }); - - // invalidate stream resource - fclose($stream); - - $buffer->write('Attempting to write to bad stream'); - - $this->assertInstanceOf('Exception', $error); - - // the error messages differ between PHP versions, let's just check substrings - $this->assertContains('Unable to write to stream: ', $error->getMessage()); - $this->assertContains(' not a valid stream resource', $error->getMessage(), '', true); - } - - public function testWritingToClosedStream() - { - if ('Darwin' === PHP_OS) { - $this->markTestSkipped('OS X issue with shutting down pair for writing'); - } - - list($a, $b) = stream_socket_pair(STREAM_PF_UNIX, STREAM_SOCK_STREAM, STREAM_IPPROTO_IP); - $loop = $this->createLoopMock(); - - $error = null; - - $buffer = new WritableResourceStream($a, $loop); - $buffer->on('error', function($message) use (&$error) { - $error = $message; - }); - - $buffer->write('foo'); - $buffer->handleWrite(); - stream_socket_shutdown($b, STREAM_SHUT_RD); - stream_socket_shutdown($a, STREAM_SHUT_RD); - $buffer->write('bar'); - $buffer->handleWrite(); - - $this->assertInstanceOf('Exception', $error); - $this->assertSame('Unable to write to stream: fwrite(): send of 3 bytes failed with errno=32 Broken pipe', $error->getMessage()); - } - - private function createWriteableLoopMock() - { - $loop = $this->createLoopMock(); - $loop->preventWrites = false; - $loop - ->expects($this->any()) - ->method('addWriteStream') - ->will($this->returnCallback(function ($stream, $listener) use ($loop) { - if (!$loop->preventWrites) { - call_user_func($listener, $stream); - } - })); - - return $loop; - } - - private function createLoopMock() - { - return $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); - } -} |