Quota.php 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. <?php
  2. /**
  3. * @copyright Copyright (c) 2016, ownCloud, Inc.
  4. *
  5. * @author Christoph Wurst <christoph@winzerhof-wurst.at>
  6. * @author Jörn Friedrich Dreyer <jfd@butonic.de>
  7. * @author Morris Jobke <hey@morrisjobke.de>
  8. * @author Robin Appelman <robin@icewind.nl>
  9. * @author Vincent Petry <vincent@nextcloud.com>
  10. *
  11. * @license AGPL-3.0
  12. *
  13. * This code is free software: you can redistribute it and/or modify
  14. * it under the terms of the GNU Affero General Public License, version 3,
  15. * as published by the Free Software Foundation.
  16. *
  17. * This program is distributed in the hope that it will be useful,
  18. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  19. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  20. * GNU Affero General Public License for more details.
  21. *
  22. * You should have received a copy of the GNU Affero General Public License, version 3,
  23. * along with this program. If not, see <http://www.gnu.org/licenses/>
  24. *
  25. */
  26. namespace OC\Files\Stream;
  27. use Icewind\Streams\Wrapper;
  28. /**
  29. * stream wrapper limits the amount of data that can be written to a stream
  30. *
  31. * usage: resource \OC\Files\Stream\Quota::wrap($stream, $limit)
  32. */
  33. class Quota extends Wrapper {
  34. /**
  35. * @var int $limit
  36. */
  37. private $limit;
  38. /**
  39. * @param resource $stream
  40. * @param int $limit
  41. * @return bool|resource
  42. */
  43. public static function wrap($stream, $limit) {
  44. $context = stream_context_create([
  45. 'quota' => [
  46. 'source' => $stream,
  47. 'limit' => $limit
  48. ]
  49. ]);
  50. return Wrapper::wrapSource($stream, $context, 'quota', self::class);
  51. }
  52. public function stream_open($path, $mode, $options, &$opened_path) {
  53. $context = $this->loadContext('quota');
  54. $this->source = $context['source'];
  55. $this->limit = $context['limit'];
  56. return true;
  57. }
  58. public function dir_opendir($path, $options) {
  59. return false;
  60. }
  61. public function stream_seek($offset, $whence = SEEK_SET) {
  62. if ($whence === SEEK_END) {
  63. // go to the end to find out last position's offset
  64. $oldOffset = $this->stream_tell();
  65. if (fseek($this->source, 0, $whence) !== 0) {
  66. return false;
  67. }
  68. $whence = SEEK_SET;
  69. $offset = $this->stream_tell() + $offset;
  70. $this->limit += $oldOffset - $offset;
  71. } elseif ($whence === SEEK_SET) {
  72. $this->limit += $this->stream_tell() - $offset;
  73. } else {
  74. $this->limit -= $offset;
  75. }
  76. // this wrapper needs to return "true" for success.
  77. // the fseek call itself returns 0 on succeess
  78. return fseek($this->source, $offset, $whence) === 0;
  79. }
  80. public function stream_read($count) {
  81. $this->limit -= $count;
  82. return fread($this->source, $count);
  83. }
  84. public function stream_write($data) {
  85. $size = strlen($data);
  86. if ($size > $this->limit) {
  87. $data = substr($data, 0, $this->limit);
  88. $size = $this->limit;
  89. }
  90. $this->limit -= $size;
  91. return fwrite($this->source, $data);
  92. }
  93. }