/** * @coroutine * * @param string $path * * @return \Generator * * @resolve int */ public function copy(string $path) : \Generator { $delayed = new Delayed(); \eio_open($path, \EIO_O_WRONLY | \EIO_O_CREAT | \EIO_O_TRUNC, 0644, null, function (Delayed $delayed, $handle, $req) { if (-1 === $handle) { $delayed->reject(new FileException(sprintf('Opening the file failed: %s.', \eio_get_last_error($req)))); } else { $delayed->resolve($handle); } }, $delayed); $this->poll->listen(); try { $handle = (yield $delayed); } finally { $this->poll->done(); } $delayed = new Delayed(); \eio_sendfile($handle, $this->handle, 0, $this->size, null, function (Delayed $delayed, $result, $req) { if (-1 === $result) { $delayed->reject(new FileException(sprintf('Copying the file failed: %s.', \eio_get_last_error($req)))); } else { $delayed->resolve(true); } }, $delayed); $this->poll->listen(); try { (yield $delayed); } finally { $this->poll->done(); \eio_close($handle); } return $this->size; }
/** * sendfile() * @param mixed $outfd File descriptor * @param callable $cb Callback * @param callable $startCb Start callback * @param integer $offset Offset * @param integer $length Length * @param integer $pri Priority * @return boolean Success */ public function sendfile($outfd, $cb, $startCb = null, $offset = 0, $length = null, $pri = EIO_PRI_DEFAULT) { $cb = CallbackWrapper::forceWrap($cb); if (!$this->fd) { if ($cb) { $cb($this, false); } return false; } if (!FileSystem::$supported) { if ($cb) { $cb($this, false); } return false; } static $chunkSize = 1024; $ret = true; $handler = function ($file, $sent = -1) use(&$ret, $outfd, $cb, &$handler, &$offset, &$length, $pri, $chunkSize) { if ($outfd instanceof IOStream) { if ($outfd->isFreed()) { $cb($file, false); return; } $ofd = $outfd->getFd(); } else { $ofd = $outfd; } if (!$ret) { $cb($file, false); return; } if ($sent === -1) { $sent = 0; } $offset += $sent; $length -= $sent; if ($length <= 0) { $cb($file, true); return; } if (!$ofd) { $cb($file, false); return; } $c = min($chunkSize, $length); $ret = eio_sendfile($ofd, $file->fd, $offset, $c, $pri, $handler, $file); }; if ($length !== null) { if ($startCb !== null) { if (!$startCb($this, $length, $handler)) { $handler($this); } } else { $handler($this); } return true; } $this->statRefresh(function ($file, $stat) use($startCb, $handler, &$length) { $length = $stat['size']; if ($startCb !== null) { if (!$startCb($file, $length, $handler)) { $handler($file); } } else { $handler($file); } }, $pri); return true; }
public function sendfile($outfd, $cb, $offset = 0, $length = null, $pri = EIO_PRI_DEFAULT) { if (!FS::$supported) { call_user_func($cb, $this, false); return; } static $chunkSize = 1024; $handler = function ($file, $sent) use($outfd, $cb, &$handler, &$offset, &$length, $pri, $chunkSize) { if ($sent === -1) { $sent = 0; } $offset += $sent; $length -= $sent; if ($length <= 0) { call_user_func($cb, $file, true); return; } if (!is_resource($outfd)) { call_user_func($cb, $file, false); return; } eio_sendfile($outfd, $file->fd, $offset, min($chunkSize, $length), $pri, $handler, $file); }; if ($length !== null) { $handler($this, -1); return; } $this->stat(function ($file, $stat) use($handler, &$length) { $length = $stat['size']; $handler($file, -1); }, $pri); }