Quota.php 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. <?php
  2. /**
  3. * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
  4. * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
  5. * SPDX-License-Identifier: AGPL-3.0-only
  6. */
  7. namespace OC\Files\Stream;
  8. use Icewind\Streams\Wrapper;
  9. /**
  10. * stream wrapper limits the amount of data that can be written to a stream
  11. *
  12. * usage: resource \OC\Files\Stream\Quota::wrap($stream, $limit)
  13. */
  14. class Quota extends Wrapper {
  15. /**
  16. * @var int $limit
  17. */
  18. private $limit;
  19. /**
  20. * @param resource $stream
  21. * @param int $limit
  22. * @return resource|false
  23. */
  24. public static function wrap($stream, $limit) {
  25. $context = stream_context_create([
  26. 'quota' => [
  27. 'source' => $stream,
  28. 'limit' => $limit
  29. ]
  30. ]);
  31. return Wrapper::wrapSource($stream, $context, 'quota', self::class);
  32. }
  33. public function stream_open($path, $mode, $options, &$opened_path) {
  34. $context = $this->loadContext('quota');
  35. $this->source = $context['source'];
  36. $this->limit = $context['limit'];
  37. return true;
  38. }
  39. public function dir_opendir($path, $options) {
  40. return false;
  41. }
  42. public function stream_seek($offset, $whence = SEEK_SET) {
  43. if ($whence === SEEK_END) {
  44. // go to the end to find out last position's offset
  45. $oldOffset = $this->stream_tell();
  46. if (fseek($this->source, 0, $whence) !== 0) {
  47. return false;
  48. }
  49. $whence = SEEK_SET;
  50. $offset = $this->stream_tell() + $offset;
  51. $this->limit += $oldOffset - $offset;
  52. } elseif ($whence === SEEK_SET) {
  53. $this->limit += $this->stream_tell() - $offset;
  54. } else {
  55. $this->limit -= $offset;
  56. }
  57. // this wrapper needs to return "true" for success.
  58. // the fseek call itself returns 0 on succeess
  59. return fseek($this->source, $offset, $whence) === 0;
  60. }
  61. public function stream_read($count) {
  62. $this->limit -= $count;
  63. return fread($this->source, $count);
  64. }
  65. public function stream_write($data) {
  66. $size = strlen($data);
  67. if ($size > $this->limit) {
  68. $data = substr($data, 0, $this->limit);
  69. $size = $this->limit;
  70. }
  71. $this->limit -= $size;
  72. return fwrite($this->source, $data);
  73. }
  74. }