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