]> git.mxchange.org Git - hub.git/blobdiff - application/hub/main/package/fragmenter/class_PackageFragmenter.php
Also check for node id to have full match, this requires you to remove all *.serializ...
[hub.git] / application / hub / main / package / fragmenter / class_PackageFragmenter.php
index a7fee59b3108128adb09f9dad55f1f21dceae3c8..3a9adc3edee46c04181e77e40805c845fdbf5bd4 100644 (file)
@@ -13,7 +13,7 @@
  *
  * @author             Roland Haeder <webmaster@ship-simu.org>
  * @version            0.0.0
- * @copyright  Copyright (c) 2007, 2008 Roland Haeder, 2009 - 2011 Hub Developer Team
+ * @copyright  Copyright (c) 2007, 2008 Roland Haeder, 2009 - 2012 Hub Developer Team
  * @license            GNU GPL 3.0 or any newer version
  * @link               http://www.ship-simu.org
  *
@@ -30,7 +30,7 @@
  * You should have received a copy of the GNU General Public License
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
-class PackageFragmenter extends BaseFrameworkSystem implements Fragmentable, Registerable {
+class PackageFragmenter extends BaseHubSystem implements Fragmentable, Registerable {
        /**
         * Cached chunk size in bits
         */
@@ -62,7 +62,7 @@ class PackageFragmenter extends BaseFrameworkSystem implements Fragmentable, Reg
        private $serialNumber = 0x00000000;
 
        /**
-        * Maximum possible serial number
+        * Maximum possible serial number, "cache" for speeding up things
         */
        private $maxSerialNumber  = 0;
 
@@ -118,7 +118,7 @@ class PackageFragmenter extends BaseFrameworkSystem implements Fragmentable, Reg
                // Get new instance
                $fragmenterInstance = new PackageFragmenter();
 
-               // And also a crypto instance (for our encrypted messages)
+               // Get a crypto instance and set it here
                $cryptoInstance = ObjectFactory::createObjectByConfiguredName('crypto_class');
                $fragmenterInstance->setCryptoInstance($cryptoInstance);
 
@@ -165,10 +165,10 @@ class PackageFragmenter extends BaseFrameworkSystem implements Fragmentable, Reg
        }
 
        /**
-        * Checks wether the given package data is already processed by this fragmenter
+        * Checks whether the given package data is already processed by this fragmenter
         *
         * @param       $packageData    Raw package data array
-        * @return      $isProcessed    Wether the package has been fragmented
+        * @return      $isProcessed    Whether the package has been fragmented
         */
        private function isPackageProcessed (array $packageData) {
                // Get array index
@@ -220,7 +220,7 @@ class PackageFragmenter extends BaseFrameworkSystem implements Fragmentable, Reg
                assert(strlen($finalHash) > 0);
 
                // Is the pointer already initialized?
-               //* NOISY-DEBUG: */ $this->debugOutput('FRAGMENTER: finalHash=' . $finalHash);
+               //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(__METHOD__ . ': finalHash[' . gettype($finalHash) . ']=' . $finalHash);
                assert(isset($this->chunkPointers[$finalHash]));
 
                // Return it
@@ -237,6 +237,7 @@ class PackageFragmenter extends BaseFrameworkSystem implements Fragmentable, Reg
                assert(isset($this->chunkPointers[$finalHash]));
 
                // Count one up
+               //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(__METHOD__ . ': finalHash[' . gettype($finalHash) . ']=' . $finalHash);
                $this->chunkPointers[$finalHash]++;
        }
 
@@ -284,40 +285,24 @@ class PackageFragmenter extends BaseFrameworkSystem implements Fragmentable, Reg
                return $hash;
        }
 
-       /**
-        * "Getter" for the next hexadecimal-encoded serial number
-        *
-        * @return      $encodedSerialNumber    The next hexadecimal-encoded serial number
-        */
-       private function getNextHexSerialNumber () {
-               // Assert on maximum serial number length
-               assert($this->serialNumber <= $this->maxSerialNumber);
-
-               // Encode the current serial number
-               $encodedSerialNumber = $this->dec2Hex($this->serialNumber, self::MAX_SERIAL_LENGTH);
-
-               // Count one up
-               $this->serialNumber++;
-
-               // Return the encoded serial number
-               return $encodedSerialNumber;
-       }
-
        /**
         * Appends an end-of-package chunk to the chunk list for given chunk and
         * final hash. As of 23-March-2012 the format of this chunk will be as any
         * regular one to keep things easy (KISS) in ChunkHandler class.
         *
-        * @param       $chunkHash      Last chunk's hash
+        * @param       $lastChunk      Last chunk raw data
         * @param       $finalHash      Final hash for raw (unencoded) data
         * @return      void
         */
-       private function appendEndOfPackageChunk ($chunkHash, $finalHash) {
+       private function appendEndOfPackageChunk ($lastChunk, $finalHash) {
                // Generate end-of-package marker
                $chunkData =
                        self::END_OF_PACKAGE_IDENTIFIER .
                        $finalHash . self::CHUNK_HASH_SEPARATOR .
-                       $chunkHash . self::CHUNK_SEPARATOR;
+                       $this->generateHashFromRawData($lastChunk);
+
+               // Debug message
+               //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(__METHOD__ . ': Adding EOP chunk with size of ' . strlen($chunkData) . ',finalHash=' . $finalHash . ' ...');
 
                // Add it as regular chunk
                $this->addChunkData($finalHash, $chunkData);
@@ -338,10 +323,11 @@ class PackageFragmenter extends BaseFrameworkSystem implements Fragmentable, Reg
 
                // Calculate real (data) chunk size
                $dataChunkSize = $this->getDataChunkSizeFromHash($finalHash);
-               //* NOISY-DEBUG: */ $this->debugOutput('FRAGMENTER: dataChunkSize=' . $dataChunkSize);
+               //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(__METHOD__ . ': dataChunkSize=' . $dataChunkSize);
 
                // Init variables
                $chunkHash = '';
+               $chunkData = '';
 
                // Now split it up
                for ($idx = 0; $idx < strlen($rawData); $idx += $dataChunkSize) {
@@ -353,10 +339,10 @@ class PackageFragmenter extends BaseFrameworkSystem implements Fragmentable, Reg
                } // END - for
 
                // Debug output
-               //* NOISY-DEBUG: */ $this->debugOutput('FRAGMENTER: Raw data of ' . strlen($rawData) . ' bytes has been fragmented into ' . count($this->chunks[$finalHash]) . ' chunk(s).');
+               //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(__METHOD__ . ': Raw data of ' . strlen($rawData) . ' bytes has been fragmented into ' . count($this->chunks[$finalHash]) . ' chunk(s).');
 
                // Add end-of-package chunk
-               $this->appendEndOfPackageChunk($chunkHash, $finalHash);
+               $this->appendEndOfPackageChunk($chunkData, $finalHash);
        }
 
        /**
@@ -365,9 +351,10 @@ class PackageFragmenter extends BaseFrameworkSystem implements Fragmentable, Reg
         *
         * @param       $finalHash      Final hash for faster processing
         * @param       $chunkData      Raw chunk data
+        * @param       $prepend        Whether append (default) or prepend the chunk
         * @return      void
         */
-       private function addChunkData ($finalHash, $chunkData) {
+       private function addChunkData ($finalHash, $chunkData, $prepend = false) {
                // Hash it
                $rawDataHash = $this->getCryptoInstance()->hashString($chunkData, '', false);
 
@@ -379,54 +366,54 @@ class PackageFragmenter extends BaseFrameworkSystem implements Fragmentable, Reg
                );
 
                // Make sure the chunk is not larger than a TCP package can hold
-               assert(strlen($rawData) <= NetworkPackage::TCP_PACKAGE_SIZE);
+               //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(__METHOD__ . ': assert: ' . strlen($rawData) . '/' . NetworkPackage::TCP_PACKAGE_SIZE . ' ...');
+               // @TODO This assert broke packages where the hash chunk was very large: assert(strlen($rawData) <= NetworkPackage::TCP_PACKAGE_SIZE);
 
                // Add it to the array
-               //* NOISY-DEBUG: */ $this->debugOutput('FRAGMENTER: Adding ' . strlen($rawData) . ' bytes of a chunk.');
-               $this->chunks[$finalHash][]      = $rawData;
-               $this->chunkHashes[$finalHash][] = $rawDataHash;
+               if ($prepend === true) {
+                       // Debug message
+                       //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(__METHOD__ . ': Prepending ' . strlen($rawData) . ' bytes of a chunk, finalHash=' . $finalHash . ' ...');
+                       array_unshift($this->chunkHashes[$finalHash], $rawDataHash);
+                       array_unshift($this->chunks[$finalHash]     , $rawData);
+               } else {
+                       // Debug message
+                       //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(__METHOD__ . ': Appending ' . strlen($rawData) . ' bytes of a chunk, finalHash=' . $finalHash . ' ...');
+                       $this->chunks[$finalHash][]      = $rawData;
+                       $this->chunkHashes[$finalHash][] = $rawDataHash;
+               }
        }
 
        /**
         * Prepends a chunk (or more) with all hashes from all chunks + final chunk.
         *
-        * @param       $rawData        Raw data string
         * @param       $finalHash      Final hash from the raw data
         * @return      void
         */
-       private function prependHashChunk ($rawData, $finalHash) {
+       private function prependHashChunk ($finalHash) {
                // "Implode" the whole array of hashes into one string
                $rawData = self::HASH_CHUNK_IDENTIFIER . implode(self::CHUNK_HASH_SEPARATOR, $this->chunkHashes[$finalHash]);
 
-               // Also get a hash from it
-               $chunkHash = $this->generateHashFromRawData($rawData);
-
-               // Calulcate chunk size
-               $dataChunkSize = $this->getDataChunkSizeFromHash($chunkHash);
-
-               // Now array_unshift() it to the two chunk arrays
-               for ($idx = 0; $idx < strlen($rawData); $idx += $dataChunkSize) {
-                       // Get the next chunk
-                       $chunk = substr($rawData, $idx, $dataChunkSize);
+               // Prepend chunk
+               $this->addChunkData($finalHash, $rawData, true);
+       }
 
-                       // Hash it and remember it in seperate array
-                       $chunkHash = $this->getCryptoInstance()->hashString($chunk, '', false);
-                       array_unshift($this->chunkHashes[$finalHash], $chunkHash);
+       /**
+        * "Getter" for the next hexadecimal-encoded serial number
+        *
+        * @return      $encodedSerialNumber    The next hexadecimal-encoded serial number
+        */
+       public function getNextHexSerialNumber () {
+               // Assert on maximum serial number length
+               assert($this->serialNumber <= $this->maxSerialNumber);
 
-                       // Prepend the hash to the chunk
-                       $chunk =
-                               $chunkHash . self::CHUNK_DATA_HASH_SEPARATOR .
-                               $this->getNextHexSerialNumber() . self::CHUNK_DATA_HASH_SEPARATOR .
-                               $chunk . self::CHUNK_SEPARATOR
-                       ;
+               // Encode the current serial number
+               $encodedSerialNumber = $this->dec2Hex($this->serialNumber, self::MAX_SERIAL_LENGTH);
 
-                       // Make sure the chunk is not larger than a TCP package can hold
-                       assert(strlen($chunk) <= NetworkPackage::TCP_PACKAGE_SIZE);
+               // Count one up
+               $this->serialNumber++;
 
-                       // Add it to the array
-                       //* NOISY-DEBUG: */ $this->debugOutput('FRAGMENTER: Adding ' . strlen($chunk) . ' bytes of a chunk.');
-                       array_unshift($this->chunks[$finalHash], $chunk);
-               } // END - for
+               // Return the encoded serial number
+               return $encodedSerialNumber;
        }
 
        /**
@@ -443,8 +430,9 @@ class PackageFragmenter extends BaseFrameworkSystem implements Fragmentable, Reg
        public function fragmentPackageArray (array $packageData, ConnectionHelper $helperInstance) {
                // Is this package already fragmented?
                if (!$this->isPackageProcessed($packageData)) {
-                       // Remove package status, the recipient doesn't need this
+                       // Remove package status and protocol, the recipient doesn't need this
                        unset($packageData[NetworkPackage::PACKAGE_DATA_STATUS]);
+                       unset($packageData[NetworkPackage::PACKAGE_DATA_PROTOCOL]);
 
                        // First we need to "implode" the array
                        $rawData = implode(NetworkPackage::PACKAGE_DATA_SEPARATOR, $packageData);
@@ -462,7 +450,7 @@ class PackageFragmenter extends BaseFrameworkSystem implements Fragmentable, Reg
                        $this->splitEncodedDataIntoChunks($rawData, $finalHash);
 
                        // Prepend a chunk with all hashes together
-                       $this->prependHashChunk($rawData, $finalHash);
+                       $this->prependHashChunk($finalHash);
 
                        // Mark the package as fragmented
                        $this->markPackageDataProcessed($packageData);
@@ -472,7 +460,7 @@ class PackageFragmenter extends BaseFrameworkSystem implements Fragmentable, Reg
                }
 
                // Return final hash
-               //* NOISY-DEBUG: */ $this->debugOutput('FRAGMENTER: finalHash[' . gettype($finalHash) . ']=' . $finalHash);
+               //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(__METHOD__ . ': finalHash[' . gettype($finalHash) . ']=' . $finalHash);
                return $finalHash;
        }
 
@@ -486,6 +474,9 @@ class PackageFragmenter extends BaseFrameworkSystem implements Fragmentable, Reg
         * @throws      AssertionException      If $finalHash was not 'true'
         */
        public function getNextRawDataChunk ($finalHash) {
+               // Debug message
+               //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(__METHOD__ . ': finalHash[' . gettype($finalHash) . ']=' . $finalHash);
+
                try {
                        // Get current chunk index
                        $current = $this->getCurrentChunkPointer($finalHash);
@@ -503,9 +494,13 @@ class PackageFragmenter extends BaseFrameworkSystem implements Fragmentable, Reg
                // If there is no entry left, return an empty array
                if ((!isset($this->chunkHashes[$finalHash][$current])) || (!isset($this->chunks[$finalHash][$current]))) {
                        // No more entries found
+                       //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(__METHOD__. ': finalHash=' . $finalHash . ',current=' . $current . ' - No more entries found!');
                        return array();
                } // END - if
 
+               // Debug message
+               //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(__METHOD__. ': finalHash=' . $finalHash . ',current=' . $current . ',chunkHashes()=' . count($this->chunkHashes[$finalHash]) .' - Entry choosen ...');
+
                // Generate the array
                $rawDataChunk = array(
                        $this->chunkHashes[$finalHash][$current] => $this->chunks[$finalHash][$current]
@@ -517,6 +512,19 @@ class PackageFragmenter extends BaseFrameworkSystem implements Fragmentable, Reg
                // Return the chunk array
                return $rawDataChunk;
        }
+
+       /**
+        * Resets the serial number to zero
+        *
+        * @return      void
+        */
+       public function resetSerialNumber () {
+               // Debug message
+               //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('FRAGMENTER: Resetting serial number, previous=' . $this->serialNumber);
+
+               // Reset serial number
+               $this->serialNumber = 0;
+       }
 }
 
 // [EOF]