<?php
# class : handle
# desc : work with file handles in OO in several different modes
# usage : work it out for yourself
# written : 2007, good for php4/5/( 6 )
class handle
{
var $chunk ; # Size of data to read / write
var $zopen ; # File open function
var $zwrite ; # File write function
var $zread ; # File read function
var $zclose ; # File close function
var $zeof ; # File eof function
var $errors ; # Object errors
var $handle ; # File handle
var $rw ; # File read / write mode
var $file ; # File name
var $buffer ; # Data buffer
var $bwritten ; # Bytes written to $this->handle
var $bread ; # Bytes read from $this->handle
var $active ; # Handle in use
# __construct( object mode, chunk size )
# $mode : null for normal file, else gz or bz
# $chunk : 4096 by default, line size
function handle( $mode = 'f', $chunk = 4096 )
{
$this->chunk = $chunk ;
$this->mode = $mode ;
$this->active = false ;
$this->zopen = sprintf( '%sopen', $this->mode );
$this->zwrite = sprintf( '%swrite', $this->mode );
$this->zread = sprintf( '%sread', $this->mode );
$this->zclose = sprintf( '%sclose', $this->mode );
$this->zeof = sprintf( '%seof', $this->mode );
$this->ztell = sprintf( '%stell', $this->mode );
if( !function_exists( $this->zopen ) )
{
$this->errors[ ] = sprintf( 'Cannot find a suitable %s function', $this->zopen );
}
elseif( !function_exists( $this->zwrite ) )
{
$this->errors[ ] = sprintf( 'Cannot find a suitable %s function', $this->zwrite );
}
elseif( !function_exists( $this->zread ) )
{
$this->errors[ ] = sprintf( 'Cannot find a suitable %s function', $this->zread );
}
elseif( !function_exists( $this->zclose ) )
{
$this->errors[ ] = sprintf( 'Cannot find a suitable %s function', $this->zclose );
}
if( !function_exists( $this->zeof ) )
{
$this->zeof = 'feof';
}
if( !function_exists( $this->ztell ) )
{
$this->ztell = 'ftell';
}
}
# handle::open( filename, read / write mode )
# $file : the filename to open
# $rw : the read / write mode to use, read by default
# open a file to $rw in $this->mode
function open( $file, $rw = 'r' )
{
if( !$this->active )
{
if( ( $this->handle = call_user_func( $this->zopen, $file, $rw ) ) )
{
$this->rw = $rw ;
$this->file = $file ;
$this->active = true ;
return true ;
}
else $this->errors[ ] = sprintf( 'Failed to open %s in %s mode', $file, $rw );
}
else $this->errors[ ] = sprintf( 'Cannot open %s because %s is active on this handle', $file, $this->file );
}
# handle::read( )
# retrieve a chunk of data $this->chunk long
function read( )
{
unset( $this->buffer );
if( $this->active )
{
if( substr( $this->rw, 0, 1 ) == 'r' )
{
while( !call_user_func( $this->zeof, $this->handle ) )
{
if( ( $this->buffer = call_user_func( $this->zread, $this->handle, $this->chunk ) ) )
{
$this->bread += strlen( $this->buffer );
return $this->buffer ;
}
elseif( ftell( $this->handle ) != filesize( $this->file ) )
{
$this->errors[ ] = sprintf( 'Cannot read data from %s at byte %d of %d bytes', $this->file, ftell( $this->handle ), filesize( $this->file ) );
}
}
}
else $this->errors[ ] = sprintf( '%s was opened in %s mode', $this->file, $this->rw );
}
else $this->errors[ ] = sprintf( '%s is not actively open, cannot read', $this->file );
}
# handle::write( data to write )
# $data : data to write to $this->handle
# write data to $this->handle
function write( $data )
{
if( $this->active )
{
if( $data )
{
if( substr( $this->rw, 0, 1 ) == 'w' )
{
if( call_user_func( $this->zwrite, $this->handle, $data, strlen( $data ) ) )
{
$this->bwritten += strlen( $data );
return true ;
}
else $this->errors[ ] = sprintf( 'Cannot write %d bytes to %s at byte %d', strlen( $data ), $this->file, ftell( $this->handle ) );
}
else $this->errors[ ] = sprintf( '%s was opened in %s mode', $this->file, $this->rw );
}
}
else $this->errors[ ] = sprintf( '%s is not actively open, cannot write', $this->file );
}
# handle::eof( )
# tell if a file is at the eof pointer
function eof( )
{
if( $this->active )
{
if( $this->rw )
{
if( call_user_func( $this->zeof, $this->handle ) or count( $this->errors ) > 0 )
{
return true ;
}
}
}
else $this->errors[ ] = sprintf( '%s is not actively open', $this->file );
}
# handle::tell( )
# get file offset
function tell( )
{
if( $this->active )
{
return call_user_func( $this->ztell, $this->handle );
}
else $this->errors[ ] = sprintf( '%s is not actively open', $this->file );
}
# handle::close( )
function close( )
{
if( $this->active )
{
if( call_user_func( $this->zclose, $this->handle ) )
{
$this->active = false ;
return true ;
}
}
else $this->errors[ ] = 'attempt to destroy an already destroyed handle';
}
# handle::bwritten( )
# retrieve number of bytes written to $this->handle
function bwritten( )
{
return $this->bwritten ;
}
# handle::bread( )
# retrieve number of bytes read from $this->handle
function bread( )
{
return $this->bread ;
}
# handle::rhandle( )
# retrieve raw handle
function rhandle( )
{
return $this->handle ;
}
# handle::errors( )
# will return array of errors if there are any
function errors( )
{
return $this->errors ;
}
}
?>