PHP Classes

File: cfile.class.php

Recommend this page to a friend!
  Classes of Alessandro Rosa   CFile   cfile.class.php   Download  
File: cfile.class.php
Role: Class source
Content type: text/plain
Description: whole package
Class: CFile
Read and write values to binary files
Author: By
Last change:
Date: 13 years ago
Size: 27,266 bytes
 

Contents

Class file image Download
<?php # CFile # coded by Alessandro Rosa # e-mail : zandor_zz@yahoo.it # site : http://alessandrorosa.altervista.org # Copyright (C) 2011 Alessandro Rosa # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software Foundation, # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA # Compiled with PHP 5 define( CFILE_BINARY_WRITEMODE, 1, true ) ; define( CFILE_TEXT_WRITEMODE, 2, true ) ; define( CFILE_MOVE_FROM_START, SEEK_SET, true ) ; define( CFILE_MOVE_FROM_END, SEEK_END, true ) ; define( CFILE_MOVE_FROM_CURRENT, SEEK_CUR, true ) ; define( CFILE_MOVE_BEGIN, 0, true ) ; define( CFILE_LITTLE_ENDIAN, 1, true ); define( CFILE_BIG_ENDIAN, 2, true ); define( CFILE_READ_MODE, "r", true ) ; define( CFILE_WRITE_MODE, "c", true ) ; define( CFILE_READWRITE_NO_CREATE_MODE, "c+", true ) ; define( CFILE_READWRITE_CREATE_MODE, "w+", true ) ; define( CFILE_BINARY_INT_MODE, 1, true ) ; define( CFILE_BINARY_FLOAT_MODE, 2, true ) ; define( CFILE_BINARY_DOUBLE_MODE, 3, true ) ; define( CFILE_TEXT_MODE, 4, true ) ; define( CFILE_INT_LITTLE_ENDIAN_PACK_MODE_READ, "h", true ) ; define( CFILE_INT_LITTLE_ENDIAN_PACK_MODE_WRITE, "i", true ) ; define( CFILE_INT_BIG_ENDIAN_PACK_MODE_READ, "H", true ) ; define( CFILE_INT_BIG_ENDIAN_PACK_MODE_WRITE, "I", true ) ; define( CFILE_INT_PACK_MODE, "i", true ) ; define( CFILE_DOUBLE_PACK_MODE, "d", true ) ; define( CFILE_FLOAT_PACK_MODE, "f", true ) ; define( CFILE_TEXT_PACK_MODE, "a", true ) ; define( CFILE_FLOAT_ROUND_DIGITS, 4, true ); define( CFILE_DOUBLE_ROUND_DIGITS, 7, true ); // giving an example of a integer variable to compute its memory size $INT_VAL = (integer)32 ; $H = pack( CFILE_INT_PACK_MODE."*", $INT_VAL ); define( CFILE_SIZE_OF_INT, strlen($H), true ) ; // giving an example of a float variable to compute its memory size $FLOAT_VAL = (float)32 ; $H = pack( CFILE_FLOAT_PACK_MODE."*", $FLOAT_VAL ); define( CFILE_SIZE_OF_FLOAT, strlen($H), true ) ; // giving an example of a double variable to compute its memory size $DOUBLE_VAL = (double)32 ; $H = pack( CFILE_DOUBLE_PACK_MODE."*", $DOUBLE_VAL ); define( CFILE_SIZE_OF_DOUBLE, strlen($H), true ) ; class cfile { var $FILE_HANDLE = false ; var $FILE_PATH = "" ; var $FILE_SIZE = 0 ; var $bERROR = false ; var $error_no = 0 ; var $error_msg = "" ; var $byte_order = 0 ; function cfile( $FP, $BYTE_ORDER = CFILE_BIG_ENDIAN ) { $FP = trim( $FP ); $this->FILE_PATH = $FP ; if ( strlen( $FP ) == 0 ) { $this->bERROR = true ; $this->error_no = 1.1 ; } else { $this->byte_order = $BYTE_ORDER ; $REG_EXP = '/^([A-Za-z]:)|[a-z0-9_.\/\\\]*$/i' ; $bRET = preg_match( $REG_EXP, $FP ) ; if ( !$bRET ) { $this->bERROR = true ; $this->error_no = 1.3 ; } } } function open( $OPEN_MODE = CFILE_READ_MODE ) { $this->FILE_SIZE = ( file_exists( $this->FILE_PATH ) ) ? filesize( $this->FILE_PATH ) : 0 ; $this->FILE_SIZE = intval( $this->FILE_SIZE ); if ( is_nan( $this->FILE_SIZE ) ) $this->FILE_SIZE = 0 ; $this->FILE_HANDLE = ( $this->bERROR ) ? false : @fopen( $this->FILE_PATH, $OPEN_MODE ); if ( !( $this->FILE_HANDLE ) ) { $this->bERROR = true ; $this->error_no = 1.4 ; } return ( $this->FILE_HANDLE !== false ) ? true : false ; } function move_to_beginning() { return $this->move( 0, 0 ); } function move_to_end() { return $this->move( 0, $this->FILE_SIZE - 1 ); } function move_backward( $nbytes = 0 ) { $bRET = true ; if ( $this->FILE_HANDLE !== false ) { $nbytes = abs( $nbytes ); $nbytes = -$nbytes ; $SEEK = @fseek( $this->FILE_HANDLE, $nbytes, SEEK_CUR ); $SEEK = intval( $SEEK ); if ( is_nan( $SEEK ) ) $SEEK = 0 ; $bRET = ( $SEEK == 0 ) ? true : false ; if ( $bRET ) { $this->bERROR = true ; $this->error_no = 5.2 ; } } else $bRET = false ; return $bRET ; } function move_forward( $nbytes = 0 ) { $bRET = true ; if ( $this->FILE_HANDLE !== false ) { $nbytes = abs( $nbytes ); $SEEK = @fseek( $this->FILE_HANDLE, $nbytes, SEEK_CUR ); $SEEK = intval( $SEEK ); if ( is_nan( $SEEK ) ) $SEEK = 0 ; $bRET = ( $SEEK == 0 ) ? true : false ; if ( $bRET ) { $this->bERROR = true ; $this->error_no = 5.2 ; } } else $bRET = false ; return $bRET ; } function move( $start, $nbytes = 0 ) // minus and plus for backward and forward direction respectively { $FS = $this->FILE_SIZE ; $nbytes = intval( $nbytes ); if ( is_nan( $nbytes ) ) $nbytes = 0 ; $newpos = $start + $nbytes ; if ( $newpos > $FS || $newpos < 0 ) { $this->bERROR = true ; $this->error_no = 5.3 ; return false ; } else { if ( $this->FILE_HANDLE !== false ) { // move to start point first if ( $start >= 0 ) @fseek( $this->FILE_HANDLE, $start, SEEK_SET ); $SEEK = @fseek( $this->FILE_HANDLE, $nbytes, SEEK_CUR ); $SEEK = intval( $SEEK ); if ( is_nan( $SEEK ) ) $SEEK = 0 ; $bRET = ( $SEEK == 0 ) ? true : false ; if ( $bRET ) { $this->bERROR = true ; $this->error_no = 5.2 ; } return $bRET ; } else { $this->bERROR = true ; $this->error_no = 5.1 ; return false ; } } } public function read_array( &$item, $BYTE_ORDER = CFILE_BIG_ENDIAN, $bREVERSE_BYTE_ORDER = true ) { if ( is_array( $item ) ) { $bRET = true ; $nitems = count( $item ); $readmode = 0 ; foreach( $item AS $key => $chunk ) { if ( is_array( $chunk ) ) { $cast = key( $chunk ); $cast_array = ( strpos( $cast, "@", 0 ) !== false ) ? explode( "@", $cast ) : array( $cast, 0 ) ; $cast_type = strtolower( $cast_array[0] ) ; $cast_bytes = intval( $cast_array[1] ) ; $writemode = 0 ; switch( $cast_type ) { case "string" : $readmode = CFILE_TEXT_MODE ; if ( is_nan( $cast_bytes ) || $cast_bytes == 0 ) $cast_bytes = 0 ; break ; case "float" : $readmode = CFILE_BINARY_FLOAT_MODE ; if ( is_nan( $cast_bytes ) || $cast_bytes == 0 ) $cast_bytes = CFILE_SIZE_OF_FLOAT ; break ; case "double" : $readmode = CFILE_BINARY_DOUBLE_MODE ; if ( is_nan( $cast_bytes ) || $cast_bytes == 0 ) $cast_bytes = CFILE_SIZE_OF_DOUBLE ; break ; case "int" : case "integer" : $readmode = CFILE_BINARY_INT_MODE ; if ( is_nan( $cast_bytes ) || $cast_bytes == 0 ) $cast_bytes = CFILE_SIZE_OF_INT ; break ; default : $readmode = CFILE_BINARY_INT_MODE ; if ( is_nan( $cast_bytes ) || $cast_bytes == 0 ) $cast_bytes = CFILE_SIZE_OF_INT ; break ; } if ( $cast_bytes == 0 ) { $this->bERROR = true ; $this->error_no = 2.5 ; return false ; } else { $val = $this->read( $cast_bytes, $readmode, $BYTE_ORDER, $bREVERSE_BYTE_ORDER ) ; if ( $val !== false ) $item["$key"] = array( $cast => $val ) ; } } } return true ; } else { $this->bERROR = true ; $this->error_no = 2.4 ; return false ; } } function read( $nbytes, $mode = CFILE_TEXT_MODE, $BYTE_ORDER = CFILE_BIG_ENDIAN, $bREVERSE_BYTE_ORDER = true ) { $original_bytes = $nbytes ; $mode = intval( $mode ); if ( is_nan( $mode ) ) $mode = CFILE_BINARY_INT_MODE ; $nbytes = intval( $nbytes ); if ( is_nan( $nbytes ) ) $nbytes = 0 ; $FS = $this->FILE_SIZE ; $start = @ftell( $this->FILE_HANDLE ); $newpos = $start + $nbytes ; if ( $mode == CFILE_TEXT_MODE ) $bREVERSE_BYTE_ORDER = false ; if ( $newpos > $FS || $newpos < 0 ) { $this->bERROR = true ; $this->error_no = 2.3 ; return false ; } else { if ( $this->FILE_HANDLE !== false && $nbytes > 0 ) { $F = "" ; $READ = @fread( $this->FILE_HANDLE, $nbytes ) ; if ( $READ === false ) { $this->bERROR = true ; $this->error_no = 2.2 ; return false ; } else { $INPUT_LEN = 0 ; if ( $mode != CFILE_TEXT_MODE ) { if ( $mode == CFILE_BINARY_INT_MODE ) { $F = CFILE_INT_PACK_MODE ; $F = "h*" ; $INPUT_LEN = CFILE_SIZE_OF_INT ; } else if ( $mode == CFILE_BINARY_FLOAT_MODE ) { $F = CFILE_FLOAT_PACK_MODE ; $F = "$F*" ; $INPUT_LEN = CFILE_SIZE_OF_FLOAT ; } else if ( $mode == CFILE_BINARY_DOUBLE_MODE ) { $F = CFILE_DOUBLE_PACK_MODE ; $F = "$F*" ; $INPUT_LEN = CFILE_SIZE_OF_DOUBLE ; } } else if ( $mode == CFILE_TEXT_MODE ) { $F = CFILE_TEXT_PACK_MODE ; $F = "$F*" ; $INPUT_LEN = strlen( $READ ) ; } $RET = unpack( "$F", $READ ) ; if ( $mode == CFILE_TEXT_MODE ) $bRET = $RET[1] ; else { if ( $mode == CFILE_BINARY_INT_MODE ) { if ( $bREVERSE_BYTE_ORDER ) $RET[1] = cfile::reverse_byte_order( $RET[1] ) ; $RET[1] = ltrim( $RET[1], 0 ); $bRET = hexdec( $RET[1] ) ; } else $bRET = $RET[1] ; } return $bRET ; } } else { $this->bERROR = true ; $this->error_no = 2.1 ; return false ; } } } private function write_binary( $FH, $chunk, $nbytes, $writemode ) { if ( is_array( $chunk ) ) { $bRET = true ; foreach( $chunk AS $key => $val ) { $b = strlen( $val ) ; $bRET &= $this->write_binary( $FH, $val, $b ) ; } return $bRET ; } else { $IN = null ; $F = "" ; if ( is_numeric( $chunk ) ) { if ( $writemode == CFILE_BINARY_INT_MODE ) { switch( $this->byte_order ) { case CFILE_LITTLE_ENDIAN : $F = CFILE_INT_LITTLE_ENDIAN_PACK_MODE_WRITE ; break ; case CFILE_BIG_ENDIAN : $F = CFILE_INT_BIG_ENDIAN_PACK_MODE_WRITE ; break ; default : $this->byte_order = CFILE_BIG_ENDIAN ; $F = CFILE_INT_BIG_ENDIAN_PACK_MODE_WRITE ; break ; } } else if ( $writemode == CFILE_BINARY_FLOAT_MODE ) { $chunk = round( $chunk, CFILE_FLOAT_ROUND_DIGITS ); $F = CFILE_FLOAT_PACK_MODE ; } else if ( $writemode == CFILE_BINARY_DOUBLE_MODE ) { $chunk = round( $chunk, CFILE_DOUBLE_ROUND_DIGITS ); $F = CFILE_DOUBLE_PACK_MODE ; } } else $F = CFILE_TEXT_PACK_MODE ; $IN = pack( "$F*", $chunk ) ; if ( $nbytes == 0 ) $nbytes = strlen( $IN ); $O = @fwrite( $FH, $IN, $nbytes ); if ( $O === false ) { $this->bERROR = true ; $this->error_no = 3.3 ; } else $this->bERROR = false ; return $this->bERROR ; } } private function write_array( $item ) { if ( is_array( $item ) ) { $bRET = true ; foreach( $item AS $key => $chunk ) { $cast = key( $chunk ); $val = current( $chunk ); $cast_array = ( strpos( $cast, "@", 0 ) !== false ) ? explode( "@", $cast ) : array( $cast, 0 ) ; $cast_type = strtolower( $cast_array[0] ) ; $cast_bytes = intval( $cast_array[1] ) ; $writemode = 0 ; switch( $cast_type ) { case "string" : $val = "$val" ; $writemode = CFILE_TEXT_MODE ; if ( is_nan( $cast_bytes ) || $cast_bytes == 0 ) $cast_bytes = strlen( $val ); break ; case "float" : $writemode = CFILE_BINARY_FLOAT_MODE ; if ( is_nan( $cast_bytes ) || $cast_bytes == 0 ) $cast_bytes = CFILE_SIZE_OF_FLOAT ; break ; case "double" : $writemode = CFILE_BINARY_DOUBLE_MODE ; if ( is_nan( $cast_bytes ) || $cast_bytes == 0 ) $cast_bytes = CFILE_SIZE_OF_DOUBLE ; break ; case "int" : case "integer" : $writemode = CFILE_BINARY_INT_MODE ; if ( is_nan( $cast_bytes ) || $cast_bytes == 0 ) $cast_bytes = CFILE_SIZE_OF_INT ; break ; default : $writemode = CFILE_BINARY_INT_MODE ; if ( is_nan( $cast_bytes ) || $cast_bytes == 0 ) $cast_bytes = CFILE_SIZE_OF_INT ; break ; } $this->write( $val, $cast_bytes, $writemode ) ; } } else { $this->bERROR = true ; $this->error_no = 3.4 ; return false ; } } function write( $chunk, $nbytes = 0, $writemode = CFILE_BINARY_INT_MODE ) { if ( is_array( $chunk ) ) $this->write_array( $chunk ) ; else { if ( $this->FILE_HANDLE !== false ) { if ( !is_numeric( $chunk ) ) $writemode = CFILE_TEXT_MODE ; else { if ( is_int( $chunk ) ) $writemode = CFILE_BINARY_INT_MODE ; else if ( is_double( $chunk ) ) $writemode = CFILE_BINARY_DOUBLE_MODE ; else if ( is_float( $chunk ) ) $writemode = CFILE_BINARY_FLOAT_MODE ; } if ( $writemode == CFILE_BINARY_INT_MODE ) { if ( $nbytes == 0 ) $nbytes = CFILE_SIZE_OF_INT ; return $this->write_binary( $this->FILE_HANDLE, $chunk, $nbytes, CFILE_BINARY_INT_MODE ) ; } else if ( $writemode == CFILE_BINARY_FLOAT_MODE ) { if ( $nbytes == 0 ) $nbytes = CFILE_SIZE_OF_FLOAT ; return $this->write_binary( $this->FILE_HANDLE, $chunk, $nbytes, CFILE_BINARY_FLOAT_MODE ) ; } else if ( $writemode == CFILE_BINARY_DOUBLE_MODE ) { if ( $nbytes == 0 ) $nbytes = CFILE_SIZE_OF_DOUBLE ; return $this->write_binary( $this->FILE_HANDLE, $chunk, $nbytes, CFILE_BINARY_DOUBLE_MODE ) ; } else if ( $writemode == CFILE_TEXT_MODE ) { if ( $nbytes == 0 ) $nbytes = ( is_array( $chunk ) ) ? count( $chunk ) : strlen( $chunk ) ; return $this->write_binary( $this->FILE_HANDLE, $chunk, $nbytes, CFILE_TEXT_MODE ) ; } else { $this->bERROR = true ; $this->error_no = 3.2 ; return false ; } } else { $this->bERROR = true ; $this->error_no = 3.1 ; return false ; } } } function close() { if ( $this->FILE_HANDLE !== false ) { $bRET = @fclose( $this->FILE_HANDLE ) ; if ( $bRET === false ) { $this->bERROR = true ; $this->error_no = 4.1 ; } else $this->FILE_HANDLE = false ; } else { $this->bERROR = true ; $this->error_no = 4.2 ; $bRET = false ; } return $bRET ; } function reset() { if ( $this->FILE_HANDLE !== false ) { $bCLOSE = $this->close(); if ( $bCLOSE ) { $this->FILE_PATH = "" ; $this->FILE_HANDLE = false ; $this->FILE_SIZE = 0 ; $this->bERROR = false ; $this->error_no = 0 ; $this->error_msg = "" ; $this->byte_order = 0 ; } return $bCLOSE ; } } ////////////////// ADDITIONAL MEMBER FUNCTIONS ///////////////////////////// public function get_pointer_position() { return ( $this->FILE_HANDLE !== false ) ? @ftell( $this->FILE_HANDLE ) : false ; } public function feof() { return ( $this->FILE_HANDLE !== false ) ? feof( $this->FILE_HANDLE ) : -1 ; } ////////////////// ERROR HANDLING ////////////////////////////////////////// public function is_error() { return $this->bERROR ; } public function get_error_string() { $error_no = intval( $this->error_no ); if ( is_nan( $error_no ) ) $error_no = -1 ; switch( $error_no ) { case -1: $this->error_msg = "Error $error_no : unknown" ; break ; case 0: $this->error_msg = "No error" ; break ; case 0.1: $this->error_msg = "Error $error_no : reset" ; break ; case 1.1 : $this->error_msg = "Error $error_no : no filepath" ; break ; case 1.2 : $this->error_msg = "Error $error_no : filepath does not exists" ; break ; case 1.3 : $this->error_msg = "Error $error_no : filepath incorrect syntax" ; break ; case 1.4 : $this->error_msg = "Error $error_no : can't open file" ; break ; case 2.1 : $this->error_msg = "Error $error_no : no read: file access failure" ; break ; case 2.2 : $this->error_msg = "Error $error_no : no read: operational error" ; break ; case 2.3 : $this->error_msg = "Error $error_no : no read: pointer position exceeding file length" ; break ; case 2.4 : $this->error_msg = "Error $error_no : no read: data input is not of array type" ; break ; case 2.5 : $this->error_msg = "Error $error_no : no read: some array field was not casted properly" ; break ; case 3.1 : $this->error_msg = "Error $error_no : no write: file access failure" ; break ; case 3.2 : $this->error_msg = "Error $error_no : no write: select mode" ; break ; case 3.3 : $this->error_msg = "Error $error_no : no write: operational error" ; break ; case 3.4 : $this->error_msg = "Error $error_no : no write: data container is not of array type" ; break ; case 4.1 : $this->error_msg = "Error $error_no : no close: file access failure" ; break ; case 4.2 : $this->error_msg = "Error $error_no : no close: operational error" ; break ; case 5.1 : $this->error_msg = "Error $error_no : no move: file access failure" ; break ; case 5.2 : $this->error_msg = "Error $error_no : no move: unknown" ; break ; case 5.3 : $this->error_msg = "Error $error_no : no move: pointer position exceeding file length" ; break ; default: $this->error_msg = "Error $error_no : unknown" ; break ; } return $this->error_msg ; } ////////////////// STATIC FUNCTIONS //////////////////////////////////////// public static function reverse_byte_order( $input, $chunk_length = 1, $bHEXinput = true, $bretrieveHEXstring = false, $pad_to = 2 ) { if ( $bHEXinput || is_string( $input ) ) { $v = $input ; if ( strlen( $v ) % 2 == 1 ) $v = "0$v" ; // reverse byte read order $A = str_split( $v, $chunk_length ); $A = array_reverse( $A ); $v = implode( "", $A ) ; return $v ; } else { $F = "" ; if ( is_numeric( $input ) ) { if ( is_double( $input ) ) $F = "d*" ; else if ( is_int( $input ) ) $F = "i*" ; else $F = "a*" ; // it might be a string containing numbers only } else $F = "a*" ; $packedINPUT = pack( "$F", $input ); $RET = unpack( "H*", $packedINPUT ); $v = $RET[1] ; // no reversion for trailing zeros on the right $temp_v_01 = rtrim( $v, "0" ); $n_trimmed_zeros = strlen( $v ) - strlen( $temp_v_01 ) ; $temp_v_02 = strrev( $temp_v_01 ).( str_repeat( "0", $n_trimmed_zeros ) ) ; $v = $temp_v_02 ; if ( $bretrieveHEXstring && $pad_to > 0 ) return substr( $v, -$pad_to ) ; else { if ( is_int( $input ) ) $F = "i*" ; else if ( is_double( $input ) ) $F = "d*" ; else $F = "a*" ; $I = pack( "H*", $v ) ; $v = $I ; $I = unpack( "$F", $v ) ; return $I[1] ; } } } public static function swap_nibble( $byte ) { $low_nibble = 0x0F & $byte ; $high_nibble = ( 0xF0 & $byte ) / 0x0F ; return ( ( $low_nibble ) * 0x0F ) | $high_nibble ; } public static function get_nbytes( $input, &$nbits = 0 ) { $nbits = ( $input > 0 ) ? log10( $input ) / log10( 2 ) : 0 ; $nbytes = $nbits / 8 ; if ( fmod( $nbits, 8 ) == 0 ) $nbytes++ ; return ceil( $nbytes ); } public static function float_to_hex( $f ) { $f = (float)$f ; $v = pack( "f*", $f ); $v = unpack( "h*", $v ); return $v[1] ; } public static function hex_to_float( $h ) { $v = pack( "h*", $h ); $f = unpack( "f*", $v ); return $f[1] ; } public static function double_to_hex( $d ) { $d = (double)$d ; $v = pack( "d*", $d ); $v = unpack( "h*", $v ); return $v[1] ; } public static function hex_to_double( $h ) { $v = pack( "h*", $h ); $d = unpack( "d*", $v ); return $d[1] ; } } ?>