friendship ended with social-app. php is my new best friend
1<?php 2 3namespace React\Http\Io; 4 5use Psr\Http\Message\StreamInterface; 6 7/** 8 * [Internal] PSR-7 message body implementation using an in-memory buffer 9 * 10 * @internal 11 */ 12class BufferedBody implements StreamInterface 13{ 14 private $buffer = ''; 15 private $position = 0; 16 private $closed = false; 17 18 /** 19 * @param string $buffer 20 */ 21 public function __construct($buffer) 22 { 23 $this->buffer = $buffer; 24 } 25 26 public function __toString() 27 { 28 if ($this->closed) { 29 return ''; 30 } 31 32 $this->seek(0); 33 34 return $this->getContents(); 35 } 36 37 public function close() 38 { 39 $this->buffer = ''; 40 $this->position = 0; 41 $this->closed = true; 42 } 43 44 public function detach() 45 { 46 $this->close(); 47 48 return null; 49 } 50 51 public function getSize() 52 { 53 return $this->closed ? null : \strlen($this->buffer); 54 } 55 56 public function tell() 57 { 58 if ($this->closed) { 59 throw new \RuntimeException('Unable to tell position of closed stream'); 60 } 61 62 return $this->position; 63 } 64 65 public function eof() 66 { 67 return $this->position >= \strlen($this->buffer); 68 } 69 70 public function isSeekable() 71 { 72 return !$this->closed; 73 } 74 75 public function seek($offset, $whence = \SEEK_SET) 76 { 77 if ($this->closed) { 78 throw new \RuntimeException('Unable to seek on closed stream'); 79 } 80 81 $old = $this->position; 82 83 if ($whence === \SEEK_SET) { 84 $this->position = $offset; 85 } elseif ($whence === \SEEK_CUR) { 86 $this->position += $offset; 87 } elseif ($whence === \SEEK_END) { 88 $this->position = \strlen($this->buffer) + $offset; 89 } else { 90 throw new \InvalidArgumentException('Invalid seek mode given'); 91 } 92 93 if (!\is_int($this->position) || $this->position < 0) { 94 $this->position = $old; 95 throw new \RuntimeException('Unable to seek to position'); 96 } 97 } 98 99 public function rewind() 100 { 101 $this->seek(0); 102 } 103 104 public function isWritable() 105 { 106 return !$this->closed; 107 } 108 109 public function write($string) 110 { 111 if ($this->closed) { 112 throw new \RuntimeException('Unable to write to closed stream'); 113 } 114 115 if ($string === '') { 116 return 0; 117 } 118 119 if ($this->position > 0 && !isset($this->buffer[$this->position - 1])) { 120 $this->buffer = \str_pad($this->buffer, $this->position, "\0"); 121 } 122 123 $len = \strlen($string); 124 $this->buffer = \substr($this->buffer, 0, $this->position) . $string . \substr($this->buffer, $this->position + $len); 125 $this->position += $len; 126 127 return $len; 128 } 129 130 public function isReadable() 131 { 132 return !$this->closed; 133 } 134 135 public function read($length) 136 { 137 if ($this->closed) { 138 throw new \RuntimeException('Unable to read from closed stream'); 139 } 140 141 if ($length < 1) { 142 throw new \InvalidArgumentException('Invalid read length given'); 143 } 144 145 if ($this->position + $length > \strlen($this->buffer)) { 146 $length = \strlen($this->buffer) - $this->position; 147 } 148 149 if (!isset($this->buffer[$this->position])) { 150 return ''; 151 } 152 153 $pos = $this->position; 154 $this->position += $length; 155 156 return \substr($this->buffer, $pos, $length); 157 } 158 159 public function getContents() 160 { 161 if ($this->closed) { 162 throw new \RuntimeException('Unable to read from closed stream'); 163 } 164 165 if (!isset($this->buffer[$this->position])) { 166 return ''; 167 } 168 169 $pos = $this->position; 170 $this->position = \strlen($this->buffer); 171 172 return \substr($this->buffer, $pos); 173 } 174 175 public function getMetadata($key = null) 176 { 177 return $key === null ? array() : null; 178 } 179}