]> git.mxchange.org Git - hub.git/blobdiff - application/hub/main/package/assembler/class_PackageAssembler.php
Updated 'core' + renamed 'main' -> 'classes'.
[hub.git] / application / hub / main / package / assembler / class_PackageAssembler.php
diff --git a/application/hub/main/package/assembler/class_PackageAssembler.php b/application/hub/main/package/assembler/class_PackageAssembler.php
deleted file mode 100644 (file)
index 192c54f..0000000
+++ /dev/null
@@ -1,322 +0,0 @@
-<?php
-/**
- * A PackageAssembler class to assemble a package content stream fragemented
- * by PackageFragmenter back to a raw package data array.
- *
- * @author             Roland Haeder <webmaster@shipsimu.org>
- * @version            0.0.0
- * @copyright  Copyright (c) 2007, 2008 Roland Haeder, 2009 - 2015 Hub Developer Team
- * @license            GNU GPL 3.0 or any newer version
- * @link               http://www.shipsimu.org
- *
- * 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
- * (at your option) 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, see <http://www.gnu.org/licenses/>.
- */
-class PackageAssembler extends BaseHubSystem implements Assembler, Registerable, Visitable {
-       /**
-        * Name for stacker holding raw data of multiple messages
-        */
-       const STACKER_NAME_MULTIPLE_MESSAGE = 'multiple_message';
-
-       /**
-        * Pending data
-        */
-       private $pendingData = '';
-
-       /**
-        * Private call-back methods
-        */
-       private $callbacks = array();
-
-       /**
-        * Protected constructor
-        *
-        * @return      void
-        */
-       protected function __construct () {
-               // Call parent constructor
-               parent::__construct(__CLASS__);
-       }
-
-       /**
-        * Creates an instance of this class
-        *
-        * @param       $packageInstance        An instance of a Receivable class
-        * @return      $assemblerInstance      An instance of an Assembler class
-        */
-       public static final function createPackageAssembler (Receivable $packageInstance) {
-               // Get new instance
-               $assemblerInstance = new PackageAssembler();
-
-               // Set package instance here
-               $assemblerInstance->setPackageInstance($packageInstance);
-
-               // Create an instance of a raw data input stream
-               $streamInstance = ObjectFactory::createObjectByConfiguredName('node_raw_data_input_stream_class');
-
-               // And set it
-               $assemblerInstance->setInputStreamInstance($streamInstance);
-
-               // Now get a chunk handler instance
-               $handlerInstance = ChunkHandlerFactory::createChunkHandlerInstance();
-
-               // Set handler instance
-               $assemblerInstance->setHandlerInstance($handlerInstance);
-
-               // Get stacker instance
-               $stackInstance = ObjectFactory::createObjectByConfiguredName('multiple_message_stacker_class');
-
-               // Initialize the only one stack
-               $stackInstance->initStack(self::STACKER_NAME_MULTIPLE_MESSAGE);
-
-               // And add it
-               $assemblerInstance->setStackInstance($stackInstance);
-
-               // Return the prepared instance
-               return $assemblerInstance;
-       }
-
-       /**
-        * Checks whether the input buffer (stacker to be more preceise) is empty.
-        *
-        * @return      $isInputBufferEmpty             Whether the input buffer is empty
-        */
-       private function ifInputBufferIsEmpty () {
-               // Check it
-               $isInputBufferEmpty = $this->getPackageInstance()->getStackInstance()->isStackEmpty(NetworkPackage::STACKER_NAME_DECODED_HANDLED);
-
-               // Debug message
-               //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('PACKAGE-ASSEMBLER[' . __METHOD__ . ':' . __LINE__ . ']: isInputBufferEmpty=' . intval($isInputBufferEmpty));
-
-               // Return it
-               return $isInputBufferEmpty;
-       }
-
-       /**
-        * Checks whether given package content is completed (start/end markers are found)
-        *
-        * @param       $packageContent         An array with two elements: 'raw_data' and 'error_code'
-        * @return      $isCompleted            Whether the given package content is completed
-        */
-       private function isPackageContentCompleted (array $packageContent) {
-               // Check both
-               $isCompleted = $this->ifStartEndMarkersSet($packageContent[BaseRawDataHandler::PACKAGE_RAW_DATA]);
-
-               // Return status
-               return $isCompleted;
-       }
-
-       /**
-        * Assembles the content from $packageContent. This method does only
-        * initialize the whole process by creating a call-back which will then
-        * itself (99.9% of all cases) "explode" the decoded data stream and add
-        * it to a chunk assembler queue.
-        *
-        * If the call-back method or this would attempt to assemble the package
-        * chunks and (maybe) re-request some chunks from the sender, this would
-        * take to much time and therefore slow down this node again.
-        *
-        * @param       $packageContent         An array with two elements: 'raw_data' and 'error_code'
-        * @return      void
-        * @throws      UnsupportedPackageCodeHandlerException  If the package code handler is not implemented
-        */
-       public function chunkPackageContent (array $packageContent) {
-               // Validate the package content array again
-               assert(
-                       (isset($packageContent[BaseRawDataHandler::PACKAGE_RAW_DATA])) &&
-                       (isset($packageContent[BaseRawDataHandler::PACKAGE_ERROR_CODE]))
-               );
-
-               // Construct call-back name from package error code
-               $this->callbacks[$packageContent[BaseRawDataHandler::PACKAGE_ERROR_CODE]] = 'handlePackageBy' . self::convertToClassName($packageContent[BaseRawDataHandler::PACKAGE_ERROR_CODE]);
-
-               // Abort if the call-back method is not there
-               if (!method_exists($this, $this->callbacks[$packageContent[BaseRawDataHandler::PACKAGE_ERROR_CODE]])) {
-                       // Throw an exception
-                       throw new UnsupportedPackageCodeHandlerException(array($this, $this->callbacks[$packageContent[BaseRawDataHandler::PACKAGE_ERROR_CODE]], $packageContent), BaseListener::EXCEPTION_UNSUPPORTED_PACKAGE_CODE_HANDLER);
-               } // END - if
-
-               // Call it back
-               call_user_func(array($this, $this->callbacks[$packageContent[BaseRawDataHandler::PACKAGE_ERROR_CODE]]), $packageContent);
-       }
-
-       /**************************************************************************
-        *                 Call-back methods for above method                     *
-        **************************************************************************/
-
-       /**
-        * Call-back handler to handle unhandled package data. This method
-        * "explodes" the string with the chunk separator from PackageFragmenter
-        * class, does some low checks on it and feeds it into another queue for
-        * verification and re-request for bad chunks.
-        *
-        * @param       $packageContent         An array with two elements: 'raw_data' and 'error_code'
-        * @return      void
-        */
-       private function handlePackageByUnhandledPackage (array $packageContent) {
-               // Debug message
-               //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('PACKAGE-ASSEMBLER[' . __METHOD__ . ':' . __LINE__ . ']: packageData[' . BaseRawDataHandler::PACKAGE_RAW_DATA . ']=' . $packageContent[BaseRawDataHandler::PACKAGE_RAW_DATA]);
-
-               // Check for some conditions
-               if ((!$this->ifInputBufferIsEmpty()) || (!$this->isPackageContentCompleted($packageContent))) {
-                       // Last chunk is not valid, so wait for more
-                       $this->pendingData .= $packageContent[BaseRawDataHandler::PACKAGE_RAW_DATA];
-
-                       // Debug message
-                       //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('PACKAGE-ASSEMBLER[' . __METHOD__ . ':' . __LINE__ . ']: Partial data received. Waiting for more ... ( ' . strlen($packageContent[BaseRawDataHandler::PACKAGE_RAW_DATA]) . ' bytes)');
-               } else {
-                       // Debug message
-                       //* DEBUG */ self::createDebugInstance(__CLASS__)->debugOutput('PACKAGE-ASSEMBLER[' . __METHOD__ . ':' . __LINE__ . ': packageContent=' . print_r($packageContent, TRUE) . ',chunks='.print_r($chunks, TRUE));
-               }
-       }
-
-       /**
-        * Checks whether the assembler's pending data is empty which means it has
-        * no pending data left for handling ... ;-)
-        *
-        * @return      $ifPendingDataIsEmpty   Whether pending data is empty
-        */
-       public function isPendingDataEmpty () {
-               // A simbple check
-               $ifPendingDataIsEmpty = empty($this->pendingData);
-
-               // Return it
-               return $ifPendingDataIsEmpty;
-       }
-
-       /**
-        * Checks whether the assembler has multiple messages pending
-        *
-        * @return      $isPending      Whether the assembler has multiple messages pending
-        */
-       public function ifMultipleMessagesPending () {
-               // Determine it
-               $isPending = (!$this->getStackInstance()->isStackEmpty(self::STACKER_NAME_MULTIPLE_MESSAGE));
-
-               // Return it
-               //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('PACKAGE-ASSEMBLER[' . __METHOD__ . ':' . __LINE__ . ': isPending=' . intval($isPending));
-               return $isPending;
-       }
-
-       /**
-        * Handles the assembler's pending data
-        *
-        * @return      void
-        */
-       public function handlePendingData () {
-               // Debug output
-               //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('PACKAGE-ASSEMBLER[' . __METHOD__ . ':' . __LINE__ . ']: Going to decode ' . strlen($this->pendingData) . ' Bytes of pending data. pendingData=' . $this->pendingData);
-
-               // Assert on condition
-               assert(!$this->isPendingDataEmpty());
-
-               // No markers set?
-               if (!$this->ifStartEndMarkersSet($this->pendingData)) {
-                       // This will cause an assertition in next call, so simply wait for more data
-                       //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('PACKAGE-ASSEMBLER[' . __METHOD__ . ':' . __LINE__ . ']: Pending data of ' . strlen($this->pendingData) . ' Bytes are incomplete, waiting for more ...');
-                       //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('PACKAGE-ASSEMBLER[' . __METHOD__ . ':' . __LINE__ . ']: this->pendingData=' . $this->pendingData);
-                       return;
-               } elseif (substr_count($this->pendingData, BaseRawDataHandler::STREAM_START_MARKER) > 1) {
-                       /*
-                        * Multiple messages found, so split off first message as the input
-                        * stream can only handle one message per time.
-                        */
-                       foreach (explode(BaseRawDataHandler::STREAM_START_MARKER, $this->pendingData) as $message) {
-                               // Prepend start marker again as it is needed to decode the message.
-                               $message = BaseRawDataHandler::STREAM_START_MARKER . $message;
-
-                               // Push it on stack
-                               $this->getStackInstance()->pushNamed(self::STACKER_NAME_MULTIPLE_MESSAGE, $message);
-                       } // END - foreach
-
-                       // Clear pending data
-                       $this->clearPendingData();
-
-                       // ... and exit here
-                       return;
-               }
-
-               // Init fake array
-               $packageContent = array(
-                       BaseRawDataHandler::PACKAGE_RAW_DATA   => $this->getInputStreamInstance()->streamData($this->pendingData),
-                       BaseRawDataHandler::PACKAGE_ERROR_CODE => BaseRawDataHandler::SOCKET_ERROR_UNHANDLED
-               );
-
-               /*
-                * Clear pending data as it has been processed and will be handled some
-                * lines below.
-                */
-               $this->clearPendingData();
-
-               // Debug message
-               //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('PACKAGE-ASSEMBLER[' . __METHOD__ . ':' . __LINE__ . ']: Last block of partial data received. A total of ' . strlen($packageContent[BaseRawDataHandler::PACKAGE_RAW_DATA]) . ' bytes has been received.');
-
-               // Make sure last CHUNK_SEPARATOR is not there
-               if (substr($packageContent[BaseRawDataHandler::PACKAGE_RAW_DATA], -1, 1) == PackageFragmenter::CHUNK_SEPARATOR) {
-                       // Remove it
-                       $packageContent[BaseRawDataHandler::PACKAGE_RAW_DATA] = substr($packageContent[BaseRawDataHandler::PACKAGE_RAW_DATA], 0, -1);
-               } // END - if
-
-               /*
-                * "explode" the string from 'raw_data' with chunk separator to get an
-                * array of chunks. These chunks must then be verified by their
-                * checksums. Also the final chunk must be handled.
-                */
-               $chunks = explode(PackageFragmenter::CHUNK_SEPARATOR, $packageContent[BaseRawDataHandler::PACKAGE_RAW_DATA]);
-
-               // Add all chunks because the last final chunk is found
-               //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('PACKAGE-ASSEMBLER[' . __METHOD__ . ':' . __LINE__ . ']: Going to add ' . count($chunks) . ' to chunk handler ...');
-               $this->getHandlerInstance()->addAllChunksWithFinal($chunks);
-       }
-
-       /**
-        * Handles multiple messages.
-        *
-        * @return      void
-        */
-       public function handleMultipleMessages () {
-               // Assert on condition
-               assert($this->ifMultipleMessagesPending());
-               assert($this->isPendingDataEmpty());
-
-               // "Pop" next entry from stack and set it as new pending data
-               $this->pendingData = $this->getStackInstance()->popNamed(self::STACKER_NAME_MULTIPLE_MESSAGE);
-
-               // And handle it
-               $this->handlePendingData();
-       }
-
-       /**
-        * Accepts the visitor to process the visit "request"
-        *
-        * @param       $visitorInstance        An instance of a Visitor class
-        * @return      void
-        */
-       public function accept (Visitor $visitorInstance) {
-               // Visit the assembler
-               $visitorInstance->visitAssembler($this);
-       }
-
-       /**
-        * Clears pending data
-        *
-        * @return      void
-        */
-       public function clearPendingData () {
-               // Clear it
-               $this->pendingData = '';
-       }
-}
-
-// [EOF]
-?>