SocketOutputStream.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 SocketOutputStream extends OutputStream
00016     {
00026         const WRITE_ATTEMPTS = 15; // should be enough for everyone (C)
00027         
00028         private $socket = null;
00029         
00030         public function __construct(Socket $socket)
00031         {
00032             $this->socket = $socket;
00033         }
00034         
00038         public function write($buffer)
00039         {
00040             if ($buffer === null)
00041                 return $this;
00042             
00043             $totalBytes = strlen($buffer);
00044             
00045             try {
00046                 $writtenBytes = $this->socket->write($buffer);
00047                 
00048                 if ($writtenBytes === false)
00049                     throw new IOTimedOutException(
00050                         'writing to socket timed out'
00051                     );
00052                 
00053                 $i = 0;
00054                 
00055                 while (
00056                     $writtenBytes < $totalBytes
00057                     && ($i < self::WRITE_ATTEMPTS)
00058                 ) {
00059                     // 0.1s sleep insurance if something wrong with socket
00060                     usleep(100000);
00061                     
00062                     $remainingBuffer = substr($buffer, $writtenBytes);
00063                     
00064                     // NOTE: ignoring timeouts here
00065                     $writtenBytes += $this->socket->write($remainingBuffer);
00066                     
00067                     ++$i;
00068                 }
00069             } catch (NetworkException $e) {
00070                 throw new IOException($e->getMessage());
00071             }
00072             
00073             if ($writtenBytes < $totalBytes)
00074                 throw new IOException(
00075                     'connection is too slow or buffer is too large?'
00076                 );
00077             
00078             return $this;
00079         }
00080     }
00081 ?>