Quota.php 2.7 KB

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