Continued:
authorRoland Häder <roland@mxchange.org>
Thu, 9 Feb 2023 17:32:21 +0000 (18:32 +0100)
committerRoland Häder <roland@mxchange.org>
Thu, 9 Feb 2023 17:32:21 +0000 (18:32 +0100)
- added more checks on parameters
- added mroe debug lines
- converted some old array() to new []

framework/main/classes/file_directories/io_stream/class_FileIoStream.php
framework/main/classes/file_directories/output/raw/class_FrameworkRawFileOutputPointer.php

index 4255f3e68b37b5b8a4d182b113d5aaea9488b706..a5e8f8b5bde92cb1083d8e6015fda77dd42c1b44 100644 (file)
@@ -12,6 +12,8 @@ use Org\Mxchange\CoreFramework\Stream\Filesystem\FileInputStreamer;
 use Org\Mxchange\CoreFramework\Stream\Filesystem\FileOutputStreamer;
 
 // Import SPL stuff
+use \InvalidArgumentException;
+use \OutOfBoundsException;
 use \SplFileInfo;
 
 /**
@@ -86,24 +88,33 @@ class FileIoStream extends BaseFrameworkSystem implements FileInputStreamer, Fil
         * @param       $dataArray      The data we shall store to the file
         * @return      void
         * @see         FileOutputStreamer
-        * @todo        This method needs heavy rewrite
+        * @throws      InvalidArgumentException        If an invalid parameter was given
+        * @throws      OutOfBoundsException    If an expected array element wasn't found
         */
        public final function saveFile (SplFileInfo $fileInfoInstance, array $dataArray) {
-               // Try it five times
-               $dirName = '';
-               $fileInstance = NULL;
+               // Trace message
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('FILE-IO-STREAM: fileInfoInstance=%s,dataArray()=%d - CALLED!', $fileInfoInstance, count($dataArray)));
+               if (count($dataArray) < 2) {
+                       // Not valid array, at least 2 elements must be there!
+                       throw new InvalidArgumentException(sprintf('Parameter "dataArray" should have at least 2 elements, has %d', count($dataArray)));
+               } else if (!isset($dataArray[0])) {
+                       // Array element 0 not found
+                       throw new OutOfBoundsException(sprintf('Array element dataArray[0] not found, dataArray=%s', json_encode($dataArray)));
+               } else if (!isset($dataArray[1])) {
+                       // Array element 1 not found
+                       throw new OutOfBoundsException(sprintf('Array element dataArray[1] not found, dataArray=%s', json_encode($dataArray)));
+               }
 
-               for ($idx = 0; $idx < 5; $idx++) {
+               try {
                        // Get a file output pointer
-                       try {
-                               $fileInstance = ObjectFactory::createObjectByConfiguredName('file_raw_output_class', array($fileInfoInstance, 'wb'));
-                       } catch (FileNotFoundException $e) {
-                               // Bail out
-                               ApplicationEntryPoint::exitApplication('The application has made a fatal error. Exception: ' . $e->__toString() . ' with message: ' . $e->getMessage());
-                       }
+                       $fileInstance = ObjectFactory::createObjectByConfiguredName('file_raw_output_class', [$fileInfoInstance, 'wb']);
+               } catch (FileNotFoundException $e) {
+                       // Bail out
+                       ApplicationEntryPoint::exitApplication('The application has made a fatal error. Exception: ' . $e->__toString() . ' with message: ' . $e->getMessage());
                }
 
                // Write a header information for validation purposes
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('FILE-IO-STREAM: Writing header to fileInstance=%s ...', $fileInstance->__toString()));
                $fileInstance->writeToFile(sprintf('%s%s%s%s%s%s%s%s%s' . PHP_EOL,
                        self::FILE_IO_FILE_HEADER_ID,
                        self::FILE_IO_SEPARATOR,
@@ -117,15 +128,17 @@ class FileIoStream extends BaseFrameworkSystem implements FileInputStreamer, Fil
                ));
 
                // Encode the (maybe) binary stream with Base64
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('FILE-IO-STREAM: Encoding %d bytes to BASE64 string ...', count($dataArray[1])));
                $b64Stream = base64_encode($dataArray[1]);
 
-               // write the data line by line
+               // write the data line-by-line
                $line = str_repeat(' ', 50); $idx = 0;
                while (strlen($line) == 50) {
                        // Get 50 chars or less
                        $line = substr($b64Stream, $idx, 50);
 
                        // Save it to the stream
+                       /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('FILE-IO-STREAM: Writing %d bytes to file ...', strlen($line)));
                        $fileInstance->writeToFile(sprintf('%s%s%s%s%s' . PHP_EOL,
                                self::FILE_IO_DATA_BLOCK_ID,
                                self::FILE_IO_SEPARATOR,
@@ -140,6 +153,9 @@ class FileIoStream extends BaseFrameworkSystem implements FileInputStreamer, Fil
 
                // Close the file
                unset($fileInstance);
+
+               // Trace message
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('FILE-IO-STREAM: EXIT!');
        }
 
        /**
@@ -151,6 +167,7 @@ class FileIoStream extends BaseFrameworkSystem implements FileInputStreamer, Fil
         */
        public final function loadFileContents (SplFileInfo $infoInstance) {
                // Initialize some variables and arrays
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('FILE-IO-STREAM: infoInstance=%s - CALLED!', $infoInstance));
                $inputBuffer = '';
                $lastBuffer = '';
                $header = [];
@@ -161,12 +178,16 @@ class FileIoStream extends BaseFrameworkSystem implements FileInputStreamer, Fil
                $fileInstance = ObjectFactory::createObjectByConfiguredName('file_raw_input_class', array($infoInstance));
 
                // Read all it's contents (we very and transparently decompress it below)
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('FILE-IO-STREAM: fileInstance=%s', $fileInstance->__toString()));
                while ($readRawLine = $fileInstance->readFromFile()) {
                        // Add the read line to the buffer
+                       /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('FILE-IO-STREAM: Adding %d read bytes to input buffer.', strlen($readRawLine)));
                        $inputBuffer .= $readRawLine;
 
                        // Break infinite loop maybe caused by the input handler
                        if ($lastBuffer == $inputBuffer) {
+                               // Break out of loop, EOF reached?
+                               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('FILE-IO-STREAM: EOF reached!');
                                break;
                        }
 
@@ -178,40 +199,52 @@ class FileIoStream extends BaseFrameworkSystem implements FileInputStreamer, Fil
                unset($fileInstance);
 
                // Convert it into an array
-               $inputBuffer = explode(chr(10), $inputBuffer);
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('FILE-IO-STREAM: Read inputBuffer=%d bytes from infoInstance=%s', strlen($inputBuffer), $infoInstance));
+               $inputArray = explode(chr(10), $inputBuffer);
 
                // Now process the read lines and verify it's content
-               foreach ($inputBuffer as $rawLine) {
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('FILE-IO-STREAM: inputArray()=%d', count($inputArray)));
+               foreach ($inputArray as $rawLine) {
                        // Trim it a little but not the leading spaces/tab-stops
                        $rawLine = rtrim($rawLine);
 
                        // Analyze this line
+                       /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('FILE-IO-STREAM: rawLine()=%d', strlen($rawLine)));
                        if (substr($rawLine, 0, 5) == self::FILE_IO_FILE_HEADER_ID) {
                                // Header found, so let's extract it
+                               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('FILE-IO-STREAM: Found header, rawLine=%s', $rawLine));
                                $header = explode(self::FILE_IO_SEPARATOR, $rawLine);
-                               $header = trim($header[1]);
+                               $headerLine = trim($header[1]);
 
                                // Now we must convert it again into an array
-                               $header = explode(self::FILE_IO_CHUNKER, $header);
+                               $header = explode(self::FILE_IO_CHUNKER, $headerLine);
 
                                // Is the header (maybe) valid?
+                               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('FILE-IO-STREAM: header()=%d', count($header)));
                                if (count($header) != 4) {
                                        // Throw an exception
                                        throw new InvalidArrayCountException(array($this, 'header', count($header), 4), self::EXCEPTION_ARRAY_HAS_INVALID_COUNT);
                                }
                        } elseif (substr($rawLine, 0, 5) == self::FILE_IO_DATA_BLOCK_ID) {
                                // Is a data line!
+                               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('FILE-IO-STREAM: Data line found rawLine=%s', $rawLine));
                                $data = explode(self::FILE_IO_SEPARATOR, $rawLine);
-                               $data = $data[1];
+                               $dataLine = $data[1];
 
                                // First element is the data, second the MD5 checksum
-                               $data = explode(self::FILE_IO_CHUNKER, $data);
+                               $data = explode(self::FILE_IO_CHUNKER, $dataLine);
 
                                // Validate the read line
+                               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('FILE-IO-STREAM: data()=%d', count($data)));
                                if (count($data) == 2) {
-                                       if (md5($data[0]) != $data[1]) {
+                                       // Generate checksum (MD5 is okay here)
+                                       $checksum = md5($data[0]);
+
+                                       // Check if it matches provided one
+                                       /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('FILE-IO-STREAM: checksum=%s,data[1]=%s', $checksum, $data[1]));
+                                       if ($checksum != $data[1]) {
                                                // MD5 hash did not match!
-                                               throw new InvalidMD5ChecksumException(array($this, md5($data[0]), $data[1]), self::EXCEPTION_MD5_CHECKSUMS_MISMATCH);
+                                               throw new InvalidMD5ChecksumException(array($this, $checksum, $data[1]), self::EXCEPTION_MD5_CHECKSUMS_MISMATCH);
                                        }
                                } else {
                                        // Invalid count!
@@ -219,16 +252,20 @@ class FileIoStream extends BaseFrameworkSystem implements FileInputStreamer, Fil
                                }
 
                                // Add this to the readData string
+                               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('FILE-IO-STREAM: Adding %d raw data to input stream', strlen($data[0])));
                                $readData .= $data[0];
                        } else {
                                // Other raw lines than header/data tagged lines and re-add the new-line char
+                               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('FILE-IO-STREAM: Adding rawLine=%s(%d) + PHP_EOL to input stream', $rawLine, strlen($rawLine)));
                                $readData .= $rawLine . PHP_EOL;
                        }
                }
 
                // Was raw lines read and no header/data?
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('FILE-IO-STREAM: readData()=%d,header()=%d,data()=%d', strlen($readData), count($header), count($data)));
                if ((!empty($readData)) && (count($header) == 0) && (count($data) == 0)) {
                        // Return raw lines back
+                       /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('FILE-IO-STREAM: readData()=%d - EXIT!', strlen($readData)));
                        return $readData;
                }
 
@@ -239,25 +276,31 @@ class FileIoStream extends BaseFrameworkSystem implements FileInputStreamer, Fil
                }
 
                // Decode all from Base64
-               $readData = @base64_decode($readData);
+               $decodedData = @base64_decode($readData);
 
                // Does the size match?
-               if (strlen($readData) != $header[2]) {
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('FILE-IO-STREAM: decodedData()=%d,header[2]=%d', strlen($decodedData), $header[2]));
+               if (strlen($decodedData) != $header[2]) {
                        // Size did not match
-                       throw new InvalidDataLengthException(array($this, strlen($readData), $header[2]), self::EXCEPTION_UNEXPECTED_STRING_SIZE);
+                       throw new InvalidDataLengthException(array($this, strlen($decodedData), $header[2]), self::EXCEPTION_UNEXPECTED_STRING_SIZE);
                }
 
+               // Generate checksum from whole read data
+               $checksum = md5($decodedData);
+
                // Validate the decoded data with the final MD5 hash
-               if (md5($readData) != $header[3]) {
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('FILE-IO-STREAM: checksum=%s,header[3]=%s', $checksum, $header[3]));
+               if ($checksum != $header[3]) {
                        // MD5 hash did not match!
-                       throw new InvalidMD5ChecksumException(array($this, md5($readData), $header[3]), self::EXCEPTION_MD5_CHECKSUMS_MISMATCH);
+                       throw new InvalidMD5ChecksumException(array($this, $checksum, $header[3]), self::EXCEPTION_MD5_CHECKSUMS_MISMATCH);
                }
 
                // Return all in an array
-               return array(
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('FILE-IO-STREAM: header()=%d,decodedData()=%d - EXIT!', count($header), strlen($decodedData)));
+               return [
                        'header' => $header,
-                       'data'   => $readData
-               );
+                       'data'   => $decodedData,
+               ];
        }
 
        /**
index abdc30bcb0a294df5e0c5bc81d7052a9b8337e2a..fa7243762c6394bb28d21b7893fe76be485fd033 100644 (file)
@@ -65,6 +65,7 @@ class FrameworkRawFileOutputPointer extends BaseFileIo implements OutputPointer
                }
 
                // Try to open a handler
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('RAW-FILE-OUTPUT-POINTER: Invoking fileInstance->openFile(%s) ...', $mode));
                $fileObject = $fileInstance->openFile($mode);
 
                // Is it valid?