3 * A PackageAssembler class to assemble a package content stream fragemented
4 * by PackageFragmenter back to a raw package data array.
6 * @author Roland Haeder <webmaster@ship-simu.org>
8 * @copyright Copyright (c) 2007, 2008 Roland Haeder, 2009 - 2011 Hub Developer Team
9 * @license GNU GPL 3.0 or any newer version
10 * @link http://www.ship-simu.org
12 * This program is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation, either version 3 of the License, or
15 * (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program. If not, see <http://www.gnu.org/licenses/>.
25 class PackageAssembler extends BaseFrameworkSystem implements Assembler, Registerable {
27 * Protected constructor
31 protected function __construct () {
32 // Call parent constructor
33 parent::__construct(__CLASS__);
37 * Creates an instance of this class
39 * @return $assemblerInstance An instance of a Fragmentable class
41 public static final function createPackageAssembler () {
43 $assemblerInstance = new PackageAssembler();
45 // Return the prepared instance
46 return $assemblerInstance;
50 * Assembles the content from $packageContent. This method does only
51 * initialize the whole process by creating a call-back which will then
52 * itself (99.9% of all cases) "explode" the decoded data stream and add
53 * it to a chunk assembler queue.
55 * If the call-back method or this would attempt to assemble the package
56 * chunks and (maybe) re-request some chunks from the sender, this would
57 * take to much time and therefore slow down this node again.
59 * @param $packageContent An array with two elements: 'decoded_data' and 'error_code'
61 * @throws UnsupportedPackageCodeHandlerException If the package code handler is not implemented
63 public function chunkPackageContent (array $packageContent) {
64 // Validate the package content array again
66 (isset($packageContent[BaseRawDataHandler::PACKAGE_DECODED_DATA])) &&
67 (isset($packageContent[BaseRawDataHandler::PACKAGE_ERROR_CODE]))
70 // Construct call-back name from package error code
71 $methodName = 'handlePackageBy' . $this->convertToClassName($packageContent[BaseRawDataHandler::PACKAGE_ERROR_CODE]);
73 // Abort if the call-back method is not there
74 if (!method_exists($this, $methodName)) {
76 throw new UnsupportedPackageCodeHandlerException(array($this, $packageContent, $methodName), BaseListener::EXCEPTION_UNSUPPORTED_PACKAGE_CODE_HANDLER);
80 call_user_func(array($this, $methodName), $packageContent);
84 * Call-back handler to handle unhandled packages
86 * @param $packageContent An array with two elements: 'decoded_data' and 'error_code'
88 * @throws FinalChunkVerificationException If the final chunk does not start with 'EOP:'
90 private function handlePackageByUnhandledPackage (array $packageContent) {
92 * "explode" the string from 'decoded_data' with chunk separator to
93 * get an array of chunks. These chunks must then be verified by
94 * their checksums. Also the final chunk must be handled.
96 $chunks = explode(PackageFragmenter::CHUNK_SEPARATOR, $packageContent[BaseRawDataHandler::PACKAGE_DECODED_DATA]);
98 // Validate final chunk
99 if (substr($chunks[count($chunks) - 1], 0, strlen(PackageFragmenter::END_OF_PACKAGE_IDENTIFIER)) != PackageFragmenter::END_OF_PACKAGE_IDENTIFIER) {
100 // Last chunk is not valid
101 throw new FinalChunkVerificationException(array($this, $packageContent, $chunks), BaseListener::EXCEPTION_FINAL_CHUNK_VERIFICATION);
104 die('chunks='.print_r($chunks,true));