BufferedInputStream.class.php

Go to the documentation of this file.
00001 <?php
00002 /***************************************************************************
00003  *   Copyright (C) 2007 by Ivan Y. Khvostishkov                            *
00004  *                                                                         *
00005  *   This program is free software; you can redistribute it and/or modify  *
00006  *   it under the terms of the GNU Lesser General Public License as        *
00007  *   published by the Free Software Foundation; either version 3 of the    *
00008  *   License, or (at your option) any later version.                       *
00009  *                                                                         *
00010  ***************************************************************************/
00011 
00015     final class BufferedInputStream extends InputStream
00016     {
00017         private $runAheadBytes  = 0;
00018         
00019         private $in             = null;
00020         private $closed         = false;
00021         
00022         private $buffer         = null;
00023         private $bufferLength   = 0;
00024         
00025         private $position       = 0;
00026         private $markPosition   = null;
00027         
00028         public function __construct(InputStream $in)
00029         {
00030             $this->in = $in;
00031         }
00032         
00036         public static function create(InputStream $in)
00037         {
00038             return new self($in);
00039         }
00040         
00044         public function close()
00045         {
00046             $this->closed = true;
00047             
00048             return $this;
00049         }
00050         
00051         public function isEof()
00052         {
00053             return $this->in->isEof();
00054         }
00055         
00056         public function markSupported()
00057         {
00058             return true;
00059         }
00060         
00064         public function mark()
00065         {
00066             $this->markPosition = $this->position;
00067             
00068             return $this;
00069         }
00070         
00074         public function reset()
00075         {
00076             $this->position = $this->markPosition;
00077             
00078             return $this;
00079         }
00080         
00081         public function available()
00082         {
00083             if ($this->closed)
00084                 return 0;
00085             
00086             return ($this->bufferLength - $this->position);
00087         }
00088         
00092         public function setRunAheadBytes($runAheadBytes)
00093         {
00094             $this->runAheadBytes = $runAheadBytes;
00095             
00096             return $this;
00097         }
00098         
00099         public function read($count)
00100         {
00101             if ($this->closed)
00102                 return null;
00103             
00104             $remainingCount = $count;
00105             $availableCount = $this->available();
00106             
00107             if ($remainingCount <= $availableCount)
00108                 $readFromBuffer = $count;
00109             else
00110                 $readFromBuffer = $availableCount;
00111             
00112             $result = null;
00113             
00114             if ($readFromBuffer > 0) {
00115                 $result = substr(
00116                     $this->buffer, $this->position, $readFromBuffer
00117                 );
00118                 
00119                 $this->position += $readFromBuffer;
00120                 $remainingCount -= $readFromBuffer;
00121             }
00122             
00123             if ($remainingCount > 0) {
00124                 
00125                 $readAtOnce = ($remainingCount < $this->runAheadBytes)
00126                     ? $this->runAheadBytes
00127                     : $remainingCount;
00128                 
00129                 $readBytes = $this->in->read($readAtOnce);
00130                 $readBytesLength = strlen($readBytes);
00131                 
00132                 if ($readBytesLength > 0) {
00133                     $this->buffer .= $readBytes;
00134                     $this->bufferLength += $readBytesLength;
00135                     
00136                     if ($readBytesLength <= $remainingCount) {
00137                         $this->position += $readBytesLength;
00138                         $result .= $readBytes;
00139                     } else {
00140                         $this->position += $remainingCount;
00141                         $result .= substr($readBytes, 0, $remainingCount);
00142                     }
00143                 }
00144             }
00145             
00146             return $result;
00147         }
00148     }
00149 ?>