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;
}