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