SocketInputStream.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 SocketInputStream extends InputStream
00016     {
00026         const READ_ATTEMPTS = 15; // should be enough for everyone (C)
00027         
00028         private $socket = null;
00029         private $eof    = false;
00030         
00031         public function __construct(Socket $socket)
00032         {
00033             $this->socket = $socket;
00034         }
00035         
00036         public function isEof()
00037         {
00038             return $this->eof;
00039         }
00040         
00041         public function read($length)
00042         {
00043             if ($length == 0 || $this->eof)
00044                 return null;
00045             
00046             try {
00047                 $result = $this->socket->read($length);
00048                 
00049                 if ($result === null)
00050                     $this->eof = true;
00051                 
00052                 $i = 0;
00053                 
00054                 while (
00055                     !$this->eof
00056                     && strlen($result) < $length
00057                     && ($i < self::READ_ATTEMPTS)
00058                 ) {
00059                     // 0.1s sleep insurance if something wrong with socket
00060                     usleep(100000);
00061                     
00062                     $remainingLength = $length - strlen($result);
00063                     
00064                     // NOTE: ignoring timeouts here
00065                     $nextPart = $this->socket->read($remainingLength);
00066                     
00067                     if ($nextPart !== null)
00068                         $result .= $nextPart;
00069                     else
00070                         $this->eof = true;
00071                     
00072                     ++$i;
00073                 }
00074             } catch (NetworkException $e) {
00075                 throw new IOException($e->getMessage());
00076             }
00077             
00078             if (!$this->eof && strlen($result) < $length)
00079                 throw new IOException(
00080                     'connection is too slow or length is too large?'
00081                 );
00082             
00083             return $result;
00084         }
00085     }
00086 ?>