class_FileIoStream.php

Go to the documentation of this file.
00001 <?php
00024 class FileIoStream extends BaseFrameworkSystem implements FileInputStreamer, FileOutputStreamer {
00028         protected function __construct () {
00029                 // Call parent constructor
00030                 parent::__construct(__CLASS__);
00031 
00032                 // Clean-up a little
00033                 $this->removeNumberFormaters();
00034                 $this->removeSystemArray();
00035         }
00036 
00043         public final static function createFileIoStream () {
00044                 // Create new instance
00045                 $ioInstance = new FileIoStream();
00046 
00047                 // Return the instance
00048                 return $ioInstance;
00049         }
00050 
00059         public final function saveFile ($fileName, $dataArray) {
00060                 // Try it five times
00061                 $dirName = ""; $fileInstance = null;
00062                 for ($idx = 0; $idx < 5; $idx++) {
00063                         // Get a file output pointer
00064                         try {
00065                                 $fileInstance = FrameworkFileOutputPointer::createFrameworkFileOutputPointer($fileName, 'w');
00066                         } catch (FilePointerNotOpenedException $e) {
00067                                 // Create missing directory
00068                                 $dirName = dirname($fileName);
00069                                 for ($idx2 = 0; $idx2 < (2 - $idx); $idx2++) {
00070                                         $dirName = dirname($dirName);
00071                                 }
00072                                 // Try to create it
00073                                 @mkdir($dirName);
00074                         }
00075                 }
00076 
00077                 // Write a header information for validation purposes
00078                 $fileInstance->writeToFile(sprintf("@head^%s:%s:%s:%s\n",
00079                         $dataArray[0],
00080                         time(),
00081                         strlen($dataArray[1]),
00082                         md5($dataArray[1])
00083                 ));
00084 
00085                 // Encode the (maybe) binary stream with Base64
00086                 $b64Stream = base64_encode($dataArray[1]);
00087 
00088                 // write the data line by line
00089                 $line = str_repeat(" ", 50); $idx = 0;
00090                 while (strlen($line) == 50) {
00091                         // Get 50 chars or less
00092                         $line = substr($b64Stream, $idx, 50);
00093 
00094                         // Save it to the stream
00095                         $fileInstance->writeToFile(sprintf("@data^%s:%s\n",
00096                                 $line,
00097                                 md5($line)
00098                         ));
00099 
00100                         // Advance to the next 50-chars block
00101                         $idx += 50;
00102                 }
00103 
00104                 // Close the file
00105                 $fileInstance->closeFile();
00106         }
00107 
00115         public final function loadFileContents ($fqfn) {
00116                 // Initialize some variables and arrays
00117                 $inputBuffer = "";
00118                 $lastBuffer = "";
00119                 $header = array();
00120                 $data = array();
00121                 $readData = ""; // This will contain our read data
00122 
00123                 // Get a file input handler
00124                 $fileInstance = FrameworkFileInputPointer::createFrameworkFileInputPointer($fqfn);
00125 
00126                 // Read all it's contents (we very and transparently decompress it below)
00127                 while ($readRawLine = $fileInstance->readFromFile()) {
00128                         // Add the read line to the buffer
00129                         $inputBuffer .= $readRawLine;
00130 
00131                         // Break infinite loop maybe caused by the input handler
00132                         if ($lastBuffer == $inputBuffer) break;
00133 
00134                         // Remember last read line for avoiding possible infinite loops
00135                         $lastBuffer = $inputBuffer;
00136                 }
00137 
00138                 // Close directory handle
00139                 $fileInstance->closeFile();
00140 
00141                 // Convert it into an array
00142                 $inputBuffer = explode("\n", $inputBuffer);
00143 
00144                 // Now process the read lines and verify it's content
00145                 foreach ($inputBuffer as $rawLine) {
00146                         // Trim it a little but not the leading spaces/tab-stops
00147                         $rawLine = rtrim($rawLine);
00148 
00149                         // Analyze this line
00150                         if (substr($rawLine, 0, 5) == "@head") {
00151                                 // Header found, so let's extract it
00152                                 $header = explode("^", $rawLine);
00153                                 $header = trim($header[1]);
00154 
00155                                 // Now we must convert it again into an array
00156                                 $header = explode(":", $header);
00157 
00158                                 // Is the header (maybe) valid?
00159                                 if (count($header) != 4) {
00160                                         // Throw an exception
00161                                         throw new InvalidArrayCountException(array($this, 'header', count($header), 4), self::EXCEPTION_ARRAY_HAS_INVALID_COUNT);
00162                                 }
00163                         } elseif (substr($rawLine, 0, 5) == "@data") {
00164                                 // Is a data line!
00165                                 $data = explode("^", $rawLine);
00166                                 $data = $data[1];
00167 
00168                                 // First element is the data, second the MD5 checksum
00169                                 $data = explode(":", $data);
00170 
00171                                 // Validate the read line
00172                                 if (count($data) == 2) {
00173                                         if (md5($data[0]) != $data[1]) {
00174                                                 // MD5 hash did not match!
00175                                                 throw new InvalidMD5ChecksumException(array($this, md5($data[0]), $data[1]), self::EXCEPTION_MD5_CHECKSUMS_MISMATCH);
00176                                         }
00177                                 } else {
00178                                         // Invalid count!
00179                                         throw new InvalidArrayCountException(array($this, "data", count($data), 2), self::EXCEPTION_ARRAY_HAS_INVALID_COUNT);
00180                                 }
00181 
00182                                 // Add this to the readData string
00183                                 $readData .= $data[0];
00184                         } else {
00185                                 // Other raw lines than header/data tagged lines and re-add the new-line char
00186                                 $readData .= $rawLine."\n";
00187                         }
00188                 }
00189 
00190                 // Was raw lines read and no header/data?
00191                 if ((!empty($readData)) && (count($header) == 0) && (count($data) == 0)) {
00192                         // Return raw lines back
00193                         return $readData;
00194                 }
00195 
00196                 // Was a header found?
00197                 if (count($header) != 4) {
00198                         // Throw an exception
00199                         throw new InvalidArrayCountException(array($this, 'header', count($header), 4), self::EXCEPTION_ARRAY_HAS_INVALID_COUNT);
00200                 }
00201 
00202                 // Decode all from Base64
00203                 $readData = @base64_decode($readData);
00204 
00205                 // Does the size match?
00206                 if (strlen($readData) != $header[2]) {
00207                         // Size did not match
00208                         throw new InvalidDataLengthException(array($this, strlen($readData), $header[2]), self::EXCEPTION_UNEXPECTED_STRING_SIZE);
00209                 }
00210 
00211                 // Validate the decoded data with the final MD5 hash
00212                 if (md5($readData) != $header[3]) {
00213                         // MD5 hash did not match!
00214                         throw new InvalidMD5ChecksumException(array($this, md5($readData), $header[3]), self::EXCEPTION_MD5_CHECKSUMS_MISMATCH);
00215                 }
00216 
00217                 // Return all in an array
00218                 return array(
00219                         'header' => $header,
00220                         'data'   => $readData
00221                 );
00222         }
00223 }
00224 
00225 // [EOF]
00226 ?>

Generated on Mon Dec 8 01:06:46 2008 for Ship-Simulator by  doxygen 1.5.6