public function writeData(WritableStream $stream, string $data) : Generator { // Apply "dot-stuffing" to problematic lines. $raw = str_replace("\r\n.\r\n", "\r\n..\r\n", $data); // Send the data along with a terminator. if (substr($raw, -2) !== "\r\n") { $raw = $raw . "\r\n"; } yield from $stream->write($raw . ".\r\n"); }
/** * @coroutine * * @param \Icicle\Stream\ReadableStream $source * @param \Icicle\Stream\WritableStream $destination * @param bool $end If true, calls end() on the destination stream when piping ends. * @param int $length The number of bytes to pipe. Use 0 for any number of bytes. * @param string|null $byte Stop piping when the given byte is read from the source stream. Use null to ignore * this parameter. * @param float|int $timeout Number of seconds to wait while reading from the source or writing to the destination * before failing. Use 0 for no timeout. * * @return \Generator * * @resolve int * * @throws \Icicle\Awaitable\Exception\TimeoutException If the operation times out. * @throws \Icicle\Exception\InvalidArgumentError If the length is invalid. * @throws \Icicle\Stream\Exception\UnreadableException If the stream is no longer readable. * @throws \Icicle\Stream\Exception\UnwritableException If the stream is no longer writable. * @throws \Icicle\Stream\Exception\ClosedException If the stream is unexpectedly closed. */ function pipe(ReadableStream $source, WritableStream $destination, bool $end = true, int $length = 0, string $byte = null, float $timeout = 0) : \Generator { if (!$destination->isWritable()) { throw new UnwritableException('The stream is not writable.'); } if (0 > $length) { throw new InvalidArgumentError('The length should be a non-negative integer.'); } $byte = strlen($byte) ? $byte[0] : null; $bytes = 0; do { $data = (yield from $source->read($length, $byte, $timeout)); $count = strlen($data); $bytes += $count; if ($count) { yield from $destination->write($data, $timeout); } } while ($source->isReadable() && $destination->isWritable() && (null === $byte || $data[$count - 1] !== $byte) && (0 === $length || 0 < ($length -= $count))); if ($end && $destination->isWritable()) { yield from $destination->end('', $timeout); } return $bytes; }