00001 <?php
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00016 final class BufferedReader extends Reader
00017 {
00018 private $in = null;
00019 private $closed = false;
00020
00021 private $buffer = null;
00022 private $bufferLength = 0;
00023
00024 private $position = 0;
00025 private $markPosition = null;
00026
00027 public function __construct(Reader $in)
00028 {
00029 $this->in = $in;
00030 }
00031
00035 public static function create(Reader $in)
00036 {
00037 return new self($in);
00038 }
00039
00043 public function close()
00044 {
00045 $this->closed = true;
00046
00047 return $this;
00048 }
00049
00050 public function isEof()
00051 {
00052 return $this->in->isEof();
00053 }
00054
00055 public function markSupported()
00056 {
00057 return true;
00058 }
00059
00063 public function mark()
00064 {
00065 $this->markPosition = $this->position;
00066
00067 return $this;
00068 }
00069
00073 public function reset()
00074 {
00075 $this->position = $this->markPosition;
00076
00077 return $this;
00078 }
00079
00080 public function available()
00081 {
00082 $this->ensureOpen();
00083
00084 return ($this->bufferLength - $this->position);
00085 }
00086
00087 public function read($count)
00088 {
00089 $this->ensureOpen();
00090
00091 $remainingCount = $count;
00092 $availableCount = $this->available();
00093
00094 if ($remainingCount <= $availableCount)
00095 $readFromBuffer = $count;
00096 else
00097 $readFromBuffer = $availableCount;
00098
00099 $result = null;
00100
00101 if ($readFromBuffer > 0) {
00102 $result = mb_substr(
00103 $this->buffer,
00104 $this->position,
00105 $readFromBuffer
00106 );
00107
00108 $this->position += $readFromBuffer;
00109 $remainingCount -= $readFromBuffer;
00110 }
00111
00112 if ($remainingCount > 0) {
00113 $remaining = $this->in->read($remainingCount);
00114
00115 if ($this->markPosition !== null) {
00116 $this->buffer .= $remaining;
00117 $remainingLength = mb_strlen($remaining);
00118
00119 $this->bufferLength += $remainingLength;
00120 $this->position += $remainingLength;
00121 }
00122
00123 if ($remaining !== null)
00124 $result .= $remaining;
00125 }
00126
00127 return $result;
00128 }
00129
00130 private function ensureOpen()
00131 {
00132 if ($this->closed)
00133 throw new IOException('stream has been closed');
00134 }
00135 }
00136 ?>