1<?php 2namespace GuzzleHttp\Psr7; 3 4use Psr\Http\Message\StreamInterface; 5 6/** 7 * Provides a buffer stream that can be written to to fill a buffer, and read 8 * from to remove bytes from the buffer. 9 * 10 * This stream returns a "hwm" metadata value that tells upstream consumers 11 * what the configured high water mark of the stream is, or the maximum 12 * preferred size of the buffer. 13 */ 14class BufferStream implements StreamInterface 15{ 16 private $hwm; 17 private $buffer = ''; 18 19 /** 20 * @param int $hwm High water mark, representing the preferred maximum 21 * buffer size. If the size of the buffer exceeds the high 22 * water mark, then calls to write will continue to succeed 23 * but will return false to inform writers to slow down 24 * until the buffer has been drained by reading from it. 25 */ 26 public function __construct($hwm = 16384) 27 { 28 $this->hwm = $hwm; 29 } 30 31 public function __toString() 32 { 33 return $this->getContents(); 34 } 35 36 public function getContents() 37 { 38 $buffer = $this->buffer; 39 $this->buffer = ''; 40 41 return $buffer; 42 } 43 44 public function close() 45 { 46 $this->buffer = ''; 47 } 48 49 public function detach() 50 { 51 $this->close(); 52 } 53 54 public function getSize() 55 { 56 return strlen($this->buffer); 57 } 58 59 public function isReadable() 60 { 61 return true; 62 } 63 64 public function isWritable() 65 { 66 return true; 67 } 68 69 public function isSeekable() 70 { 71 return false; 72 } 73 74 public function rewind() 75 { 76 $this->seek(0); 77 } 78 79 public function seek($offset, $whence = SEEK_SET) 80 { 81 throw new \RuntimeException('Cannot seek a BufferStream'); 82 } 83 84 public function eof() 85 { 86 return strlen($this->buffer) === 0; 87 } 88 89 public function tell() 90 { 91 throw new \RuntimeException('Cannot determine the position of a BufferStream'); 92 } 93 94 /** 95 * Reads data from the buffer. 96 */ 97 public function read($length) 98 { 99 $currentLength = strlen($this->buffer); 100 101 if ($length >= $currentLength) { 102 // No need to slice the buffer because we don't have enough data. 103 $result = $this->buffer; 104 $this->buffer = ''; 105 } else { 106 // Slice up the result to provide a subset of the buffer. 107 $result = substr($this->buffer, 0, $length); 108 $this->buffer = substr($this->buffer, $length); 109 } 110 111 return $result; 112 } 113 114 /** 115 * Writes data to the buffer. 116 */ 117 public function write($string) 118 { 119 $this->buffer .= $string; 120 121 // TODO: What should happen here? 122 if (strlen($this->buffer) >= $this->hwm) { 123 return false; 124 } 125 126 return strlen($string); 127 } 128 129 public function getMetadata($key = null) 130 { 131 if ($key == 'hwm') { 132 return $this->hwm; 133 } 134 135 return $key ? null : []; 136 } 137} 138