Visitor instances can now be stored in all objects for speeding up the code.
[core.git] / inc / classes / main / class_BaseFrameworkSystem.php
1 <?php
2 /**
3  * The simulator system class is the super class of all other classes. This
4  * class handles saving of games etc.
5  *
6  * @author              Roland Haeder <webmaster@ship-simu.org>
7  * @version             0.0.0
8  * @copyright   Copyright (c) 2007, 2008 Roland Haeder, 2009 - 2011 Core Developer Team
9  * @license             GNU GPL 3.0 or any newer version
10  * @link                http://www.ship-simu.org
11  *
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.
16  *
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.
21  *
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/>.
24  */
25 class BaseFrameworkSystem extends stdClass implements FrameworkInterface {
26         /**
27          * Instance of a request class
28          */
29         private $requestInstance = null;
30
31         /**
32          * Instance of a response class
33          */
34         private $responseInstance = null;
35
36         /**
37          * Search criteria instance
38          */
39         private $searchInstance = null;
40
41         /**
42          * Update criteria instance
43          */
44         private $updateInstance = null;
45
46         /**
47          * The file I/O instance for the template loader
48          */
49         private $fileIoInstance = null;
50
51         /**
52          * Resolver instance
53          */
54         private $resolverInstance = null;
55
56         /**
57          * Template engine instance
58          */
59         private $templateInstance = null;
60
61         /**
62          * Database result instance
63          */
64         private $resultInstance = null;
65
66         /**
67          * Instance for user class
68          */
69         private $userInstance = null;
70
71         /**
72          * A controller instance
73          */
74         private $controllerInstance = null;
75
76         /**
77          * Instance of a RNG
78          */
79         private $rngInstance = null;
80
81         /**
82          * Instance of a crypto helper
83          */
84         private $cryptoInstance = null;
85
86         /**
87          * Instance of an Iterator class
88          */
89         private $iteratorInstance = null;
90
91         /**
92          * Instance of the list
93          */
94         private $listInstance = null;
95
96         /**
97          * Instance of a menu
98          */
99         private $menuInstance = null;
100
101         /**
102          * Instance of the image
103          */
104         private $imageInstance = null;
105
106         /**
107          * Instance of the stacker
108          */
109         private $stackerInstance = null;
110
111         /**
112          * A Compressor instance
113          */
114         private $compressorInstance = null;
115
116         /**
117          * A Parseable instance
118          */
119         private $parserInstance = null;
120
121         /**
122          * A ProtocolHandler instance
123          */
124         private $protocolInstance = null;
125
126         /**
127          * A database wrapper instance
128          */
129         private $databaseInstance = null;
130
131         /**
132          * A helper instance for the form
133          */
134         private $helperInstance = null;
135
136         /**
137          * An instance of a Sourceable class
138          */
139         private $sourceInstance = null;
140
141         /**
142          * An instance of a InputStreamable class
143          */
144         private $inputStreamInstance = null;
145
146         /**
147          * An instance of a OutputStreamable class
148          */
149         private $outputStreamInstance = null;
150
151         /**
152          * Networkable handler instance
153          */
154         private $handlerInstance = null;
155
156         /**
157          * Visitor handler instance
158          */
159         private $visitorInstance = null;
160
161         /**
162          * The real class name
163          */
164         private $realClass = 'BaseFrameworkSystem';
165
166         /**
167          * An instance of a database wrapper class
168          */
169         private $wrapperInstance = null;
170
171         /**
172          * Thousands seperator
173          */
174         private $thousands = '.'; // German
175
176         /**
177          * Decimal seperator
178          */
179         private $decimals  = ','; // German
180
181         /**
182          * Socket resource
183          */
184         private $socketResource = false;
185
186         /**
187          * Package data
188          */
189         private $packageData = array();
190
191         /***********************
192          * Exception codes.... *
193          ***********************/
194
195         // @todo Try to clean these constants up
196         const EXCEPTION_IS_NULL_POINTER              = 0x001;
197         const EXCEPTION_IS_NO_OBJECT                 = 0x002;
198         const EXCEPTION_IS_NO_ARRAY                  = 0x003;
199         const EXCEPTION_MISSING_METHOD               = 0x004;
200         const EXCEPTION_CLASSES_NOT_MATCHING         = 0x005;
201         const EXCEPTION_INDEX_OUT_OF_BOUNDS          = 0x006;
202         const EXCEPTION_DIMENSION_ARRAY_INVALID      = 0x007;
203         const EXCEPTION_ITEM_NOT_TRADEABLE           = 0x008;
204         const EXCEPTION_ITEM_NOT_IN_PRICE_LIST       = 0x009;
205         const EXCEPTION_GENDER_IS_WRONG              = 0x00a;
206         const EXCEPTION_BIRTH_DATE_IS_INVALID        = 0x00b;
207         const EXCEPTION_EMPTY_STRUCTURES_ARRAY       = 0x00c;
208         const EXCEPTION_HAS_ALREADY_PERSONELL_LIST   = 0x00d;
209         const EXCEPTION_NOT_ENOUGTH_UNEMPLOYEES      = 0x00e;
210         const EXCEPTION_TOTAL_PRICE_NOT_CALCULATED   = 0x00f;
211         const EXCEPTION_HARBOR_HAS_NO_SHIPYARDS      = 0x010;
212         const EXCEPTION_CONTRACT_PARTNER_INVALID     = 0x011;
213         const EXCEPTION_CONTRACT_PARTNER_MISMATCH    = 0x012;
214         const EXCEPTION_CONTRACT_ALREADY_SIGNED      = 0x013;
215         const EXCEPTION_UNEXPECTED_EMPTY_STRING      = 0x014;
216         const EXCEPTION_PATH_NOT_FOUND               = 0x015;
217         const EXCEPTION_INVALID_PATH_NAME            = 0x016;
218         const EXCEPTION_READ_PROTECED_PATH           = 0x017;
219         const EXCEPTION_WRITE_PROTECED_PATH          = 0x018;
220         const EXCEPTION_DIR_POINTER_INVALID          = 0x019;
221         const EXCEPTION_FILE_POINTER_INVALID         = 0x01a;
222         const EXCEPTION_INVALID_RESOURCE             = 0x01b;
223         const EXCEPTION_UNEXPECTED_OBJECT            = 0x01c;
224         const EXCEPTION_LIMIT_ELEMENT_IS_UNSUPPORTED = 0x01d;
225         const EXCEPTION_GETTER_IS_MISSING            = 0x01e;
226         const EXCEPTION_ARRAY_EXPECTED               = 0x01f;
227         const EXCEPTION_ARRAY_HAS_INVALID_COUNT      = 0x020;
228         const EXCEPTION_ID_IS_INVALID_FORMAT         = 0x021;
229         const EXCEPTION_MD5_CHECKSUMS_MISMATCH       = 0x022;
230         const EXCEPTION_UNEXPECTED_STRING_SIZE       = 0x023;
231         const EXCEPTION_SIMULATOR_ID_INVALID         = 0x024;
232         const EXCEPTION_MISMATCHING_COMPRESSORS      = 0x025;
233         const EXCEPTION_CONTAINER_ITEM_IS_NULL       = 0x026;
234         const EXCEPTION_ITEM_IS_NO_ARRAY             = 0x027;
235         const EXCEPTION_CONTAINER_MAYBE_DAMAGED      = 0x028;
236         const EXCEPTION_INVALID_STRING               = 0x029;
237         const EXCEPTION_VARIABLE_NOT_SET             = 0x02a;
238         const EXCEPTION_ATTRIBUTES_ARE_MISSING       = 0x02b;
239         const EXCEPTION_ARRAY_ELEMENTS_MISSING       = 0x02c;
240         const EXCEPTION_TEMPLATE_ENGINE_UNSUPPORTED  = 0x02d;
241         const EXCEPTION_UNSPPORTED_OPERATION         = 0x02e;
242         const EXCEPTION_MISSING_ELEMENT              = 0x030;
243         const EXCEPTION_HEADERS_ALREADY_SENT         = 0x031;
244         const EXCEPTION_DEFAULT_CONTROLLER_GONE      = 0x032;
245         const EXCEPTION_CLASS_NOT_FOUND              = 0x033;
246         const EXCEPTION_REQUIRED_INTERFACE_MISSING   = 0x034;
247         const EXCEPTION_FATAL_ERROR                  = 0x035;
248         const EXCEPTION_FILE_NOT_FOUND               = 0x036;
249         const EXCEPTION_ASSERTION_FAILED             = 0x037;
250         const EXCEPTION_FILE_CANNOT_BE_READ          = 0x038;
251         const EXCEPTION_DATABASE_UPDATED_NOT_ALLOWED = 0x039;
252         const EXCEPTION_FILTER_CHAIN_INTERCEPTED     = 0x040;
253
254         // Hexadecimal->Decimal translation array
255         private static $hexdec = array(
256                 '0' => 0,
257                 '1' => 1,
258                 '2' => 2,
259                 '3' => 3,
260                 '4' => 4,
261                 '5' => 5,
262                 '6' => 6,
263                 '7' => 7,
264                 '8' => 8,
265                 '9' => 9,
266                 'a' => 10,
267                 'b' => 11,
268                 'c' => 12,
269                 'd' => 13,
270                 'e' => 14,
271                 'f' => 15
272         );
273
274         // Decimal->hexadecimal translation array
275         private static $dechex = array(
276                  0 => '0',
277                  1 => '1',
278                  2 => '2',
279                  3 => '3',
280                  4 => '4',
281                  5 => '5',
282                  6 => '6',
283                  7 => '7',
284                  8 => '8',
285                  9 => '9',
286                 10 => 'a',
287                 11 => 'b',
288                 12 => 'c',
289                 13 => 'd',
290                 14 => 'e',
291                 15 => 'f'
292         );
293
294         /**
295          * Protected super constructor
296          *
297          * @param       $className      Name of the class
298          * @return      void
299          */
300         protected function __construct ($className) {
301                 // Set real class
302                 $this->setRealClass($className);
303
304                 // Set configuration instance if no registry ...
305                 if (!$this instanceof Register) {
306                         // ... because registries doesn't need to be configured
307                         $this->setConfigInstance(FrameworkConfiguration::getInstance());
308                 } // END - if
309         }
310
311         /**
312          * Destructor reached...
313          *
314          * @return      void
315          */
316         public function __destruct() {
317                 // Flush any updated entries to the database
318                 $this->flushPendingUpdates();
319
320                 // Is this object already destroyed?
321                 if ($this->__toString() != 'DestructedObject') {
322                         // Destroy all informations about this class but keep some text about it alive
323                         $this->setRealClass('DestructedObject');
324                 } elseif ((defined('DEBUG_DESTRUCTOR')) && (is_object($this->getDebugInstance()))) {
325                         // Already destructed object
326                         $this->debugOutput(sprintf("[%s:] The object <span class=\"object_name\">%s</span> is already destroyed.",
327                                 __CLASS__,
328                                 $this->__toString()
329                         ));
330                 }
331         }
332
333         /**
334          * The __call() method where all non-implemented methods end up
335          *
336          * @param       $methodName             Name of the missing method
337          * @args        $args                   Arguments passed to the method
338          * @return      void
339          */
340         public final function __call ($methodName, $args) {
341                 // Implode all given arguments
342                 $argsString = '';
343                 if (empty($args)) {
344                         // No arguments
345                         $argsString = 'NULL';
346                 } elseif (is_array($args)) {
347                         // Some arguments are there
348                         foreach ($args as $arg) {
349                                 // Add the type
350                                 $argsString .= $this->replaceControlCharacters($arg) . ' (' . gettype($arg);
351
352                                 // Add length if type is string
353                                 if (is_string($arg)) {
354                                         $argsString .= ', '.strlen($arg);
355                                 } // END - if
356
357                                 // Closing bracket
358                                 $argsString .= '), ';
359                         } // END - foreach
360
361                         // Remove last comma
362                         if (substr($argsString, -2, 1) == ',') {
363                                 $argsString = substr($argsString, 0, -2);
364                         } // END - if
365                 } else {
366                         // Invalid arguments!
367                         $argsString = '!INVALID:' . gettype($args) . '!';
368                 }
369
370                 // Output stub message
371                 $this->debugOutput(sprintf("[%s-&gt;%s] Stub! Args: %s",
372                         $this->__toString(),
373                         $methodName,
374                         $argsString
375                 ));
376
377                 // Return nothing
378                 return null;
379         }
380
381         /**
382          * Getter for $realClass
383          *
384          * @return      $realClass The name of the real class (not BaseFrameworkSystem)
385          */
386         public function __toString () {
387                 return $this->realClass;
388         }
389
390         /**
391          * Magic function to catch setting of missing but set class fields/attributes
392          *
393          * @param       $name   Name of the field/attribute
394          * @param       $value  Value to store
395          * @return      void
396          */
397         public final function __set ($name, $value) {
398                 $this->debugBackTrace(sprintf("Tried to set a missing field. name=%s, value[%s]=%s",
399                         $name,
400                         gettype($value),
401                         $value
402                 ));
403         }
404
405         /**
406          * Magic function to catch getting of missing fields/attributes
407          *
408          * @param       $name   Name of the field/attribute
409          * @return      void
410          */
411         public final function __get ($name) {
412                 $this->debugBackTrace(sprintf("Tried to get a missing field. name=%s",
413                         $name
414                 ));
415         }
416
417         /**
418          * Magic function to catch unsetting of missing fields/attributes
419          *
420          * @param       $name   Name of the field/attribute
421          * @return      void
422          */
423         public final function __unset ($name) {
424                 $this->debugBackTrace(sprintf("Tried to unset a missing field. name=%s",
425                         $name
426                 ));
427         }
428
429         /**
430          * Setter for database result instance
431          *
432          * @param       $resultInstance         An instance of a database result class
433          * @return      void
434          * @todo        SearchableResult and UpdateableResult shall have a super interface to use here
435          */
436         protected final function setResultInstance (SearchableResult $resultInstance) {
437                 $this->resultInstance =  $resultInstance;
438         }
439
440         /**
441          * Getter for database result instance
442          *
443          * @return      $resultInstance         An instance of a database result class
444          */
445         public final function getResultInstance () {
446                 return $this->resultInstance;
447         }
448
449         /**
450          * Setter for template engine instances
451          *
452          * @param       $templateInstance       An instance of a template engine class
453          * @return      void
454          */
455         protected final function setTemplateInstance (CompileableTemplate $templateInstance) {
456                 $this->templateInstance = $templateInstance;
457         }
458
459         /**
460          * Getter for template engine instances
461          *
462          * @return      $templateInstance       An instance of a template engine class
463          */
464         protected final function getTemplateInstance () {
465                 return $this->templateInstance;
466         }
467
468         /**
469          * Setter for search instance
470          *
471          * @param       $searchInstance         Searchable criteria instance
472          * @return      void
473          */
474         public final function setSearchInstance (LocalSearchCriteria $searchInstance) {
475                 $this->searchInstance = $searchInstance;
476         }
477
478         /**
479          * Getter for search instance
480          *
481          * @return      $searchInstance         Searchable criteria instance
482          */
483         public final function getSearchInstance () {
484                 return $this->searchInstance;
485         }
486
487         /**
488          * Setter for update instance
489          *
490          * @param       $updateInstance         Searchable criteria instance
491          * @return      void
492          */
493         public final function setUpdateInstance (LocalUpdateCriteria $updateInstance) {
494                 $this->updateInstance = $updateInstance;
495         }
496
497         /**
498          * Getter for update instance
499          *
500          * @return      $updateInstance         Updateable criteria instance
501          */
502         public final function getUpdateInstance () {
503                 return $this->updateInstance;
504         }
505
506         /**
507          * Setter for resolver instance
508          *
509          * @param       $resolverInstance       Instance of a command resolver class
510          * @return      void
511          */
512         public final function setResolverInstance (Resolver $resolverInstance) {
513                 $this->resolverInstance = $resolverInstance;
514         }
515
516         /**
517          * Getter for resolver instance
518          *
519          * @return      $resolverInstance       Instance of a command resolver class
520          */
521         public final function getResolverInstance () {
522                 return $this->resolverInstance;
523         }
524
525         /**
526          * Setter for language instance
527          *
528          * @param       $configInstance         The configuration instance which shall
529          *                                                              be FrameworkConfiguration
530          * @return      void
531          */
532         public final function setConfigInstance (FrameworkConfiguration $configInstance) {
533                 Registry::getRegistry()->addInstance('config', $configInstance);
534         }
535
536         /**
537          * Getter for configuration instance
538          *
539          * @return      $configInstance         Configuration instance
540          */
541         public final function getConfigInstance () {
542                 $configInstance = Registry::getRegistry()->getInstance('config');
543                 return $configInstance;
544         }
545
546         /**
547          * Setter for debug instance
548          *
549          * @param       $debugInstance  The instance for debug output class
550          * @return      void
551          */
552         public final function setDebugInstance (DebugMiddleware $debugInstance) {
553                 Registry::getRegistry()->addInstance('debug', $debugInstance);
554         }
555
556         /**
557          * Getter for debug instance
558          *
559          * @return      $debugInstance  Instance to class DebugConsoleOutput or DebugWebOutput
560          */
561         public final function getDebugInstance () {
562                 // Get debug instance
563                 $debugInstance = Registry::getRegistry()->getInstance('debug');
564
565                 // Return it
566                 return $debugInstance;
567         }
568
569         /**
570          * Setter for web output instance
571          *
572          * @param               $webInstance    The instance for web output class
573          * @return      void
574          */
575         public final function setWebOutputInstance (OutputStreamer $webInstance) {
576                 Registry::getRegistry()->addInstance('web_output', $webInstance);
577         }
578
579         /**
580          * Getter for web output instance
581          *
582          * @return      $webOutputInstance - Instance to class WebOutput
583          */
584         public final function getWebOutputInstance () {
585                 $webOutputInstance = Registry::getRegistry()->getInstance('web_output');
586                 return $webOutputInstance;
587         }
588
589         /**
590          * Setter for database instance
591          *
592          * @param               $dbInstance     The instance for the database connection (forced DatabaseConnection)
593          * @return      void
594          */
595         public final function setDatabaseInstance (DatabaseConnection $dbInstance) {
596                 Registry::getRegistry()->addInstance('db_instance', $dbInstance);
597         }
598
599         /**
600          * Getter for database layer
601          *
602          * @return      $dbInstance     The database layer instance
603          */
604         public final function getDatabaseInstance () {
605                 // Get instance
606                 $dbInstance = Registry::getRegistry()->getInstance('db_instance');
607
608                 // Return instance
609                 return $dbInstance;
610         }
611
612         /**
613          * Setter for compressor channel
614          *
615          * @param               $compressorInstance             An instance of CompressorChannel
616          * @return      void
617          */
618         public final function setCompressorChannel (CompressorChannel $compressorInstance) {
619                 Registry::getRegistry()->addInstance('compressor', $compressorInstance);
620         }
621
622         /**
623          * Getter for compressor channel
624          *
625          * @return      $compressorInstance             The compressor channel
626          */
627         public final function getCompressorChannel () {
628                 $compressorInstance = Registry::getRegistry()->getInstance('compressor');
629                 return $compressorInstance;
630         }
631
632         /**
633          * Protected getter for a manageable application helper class
634          *
635          * @return      $applicationInstance    An instance of a manageable application helper class
636          */
637         protected final function getApplicationInstance () {
638                 $applicationInstance = Registry::getRegistry()->getInstance('application');
639                 return $applicationInstance;
640         }
641
642         /**
643          * Setter for a manageable application helper class
644          *
645          * @param       $applicationInstance    An instance of a manageable application helper class
646          * @return      void
647          */
648         public final function setApplicationInstance (ManageableApplication $applicationInstance) {
649                 Registry::getRegistry()->addInstance('application', $applicationInstance);
650         }
651
652         /**
653          * Setter for request instance
654          *
655          * @param       $requestInstance        An instance of a Requestable class
656          * @return      void
657          */
658         public final function setRequestInstance (Requestable $requestInstance) {
659                 $this->requestInstance = $requestInstance;
660         }
661
662         /**
663          * Getter for request instance
664          *
665          * @return      $requestInstance        An instance of a Requestable class
666          */
667         public final function getRequestInstance () {
668                 return $this->requestInstance;
669         }
670
671         /**
672          * Setter for response instance
673          *
674          * @param       $responseInstance       An instance of a Responseable class
675          * @return      void
676          */
677         public final function setResponseInstance (Responseable $responseInstance) {
678                 $this->responseInstance = $responseInstance;
679         }
680
681         /**
682          * Getter for response instance
683          *
684          * @return      $responseInstance       An instance of a Responseable class
685          */
686         public final function getResponseInstance () {
687                 return $this->responseInstance;
688         }
689
690         /**
691          * Setter for the real class name
692          *
693          * @param               $realClass      Class name (string)
694          * @return      void
695          */
696         public final function setRealClass ($realClass) {
697                 // Cast to string
698                 $realClass = (string) $realClass;
699
700                 // Set real class
701                 $this->realClass = $realClass;
702         }
703
704         /**
705          * Checks wether an object equals this object. You should overwrite this
706          * method to implement own equality checks
707          *
708          * @param       $objectInstance         An instance of a FrameworkInterface object
709          * @return      $equals                         Wether both objects equals
710          */
711         public function equals (FrameworkInterface $objectInstance) {
712                 // Now test it
713                 $equals = ((
714                         $this->__toString() == $objectInstance->__toString()
715                 ) && (
716                         $this->hashCode() == $objectInstance->hashCode()
717                 ));
718
719                 // Return the result
720                 return $equals;
721         }
722
723         /**
724          * Generates a generic hash code of this class. You should really overwrite
725          * this method with your own hash code generator code. But keep KISS in mind.
726          *
727          * @return      $hashCode       A generic hash code respresenting this whole class
728          */
729         public function hashCode () {
730                 // Simple hash code
731                 return crc32($this->__toString());
732         }
733
734         /**
735          * Formats computer generated price values into human-understandable formats
736          * with thousand and decimal seperators.
737          *
738          * @param       $value          The in computer format value for a price
739          * @param       $currency       The currency symbol (use HTML-valid characters!)
740          * @param       $decNum         Number of decimals after commata
741          * @return      $price          The for the current language formated price string
742          * @throws      MissingDecimalsThousandsSeperatorException      If decimals or
743          *                                                                                              thousands seperator
744          *                                                                                              is missing
745          */
746         public function formatCurrency ($value, $currency = '&euro;', $decNum = 2) {
747                 // Are all required attriutes set?
748                 if ((!isset($this->decimals)) || (!isset($this->thousands))) {
749                         // Throw an exception
750                         throw new MissingDecimalsThousandsSeperatorException($this, self::EXCEPTION_ATTRIBUTES_ARE_MISSING);
751                 } // END - if
752
753                 // Cast the number
754                 $value = (float) $value;
755
756                 // Reformat the US number
757                 $price = number_format($value, $decNum, $this->decimals, $this->thousands) . $currency;
758
759                 // Return as string...
760                 return $price;
761         }
762
763         /**
764          * Private getter for language instance
765          *
766          * @return      $langInstance   An instance to the language sub-system
767          */
768         protected final function getLanguageInstance () {
769                 $langInstance = Registry::getRegistry()->getInstance('language');
770                 return $langInstance;
771         }
772
773         /**
774          * Setter for language instance
775          *
776          * @param       $langInstance   An instance to the language sub-system
777          * @return      void
778          * @see         LanguageSystem
779          */
780         public final function setLanguageInstance (ManageableLanguage $langInstance) {
781                 Registry::getRegistry()->addInstance('language', $langInstance);
782         }
783
784         /**
785          * Appends a trailing slash to a string
786          *
787          * @param       $str            A string (maybe) without trailing slash
788          * @return      $str            A string with an auto-appended trailing slash
789          */
790         public final function addMissingTrailingSlash ($str) {
791                 // Is there a trailing slash?
792                 if (substr($str, -1, 1) != '/') {
793                         $str .= '/';
794                 } // END - if
795
796                 // Return string with trailing slash
797                 return $str;
798         }
799
800         /**
801          * Private getter for file IO instance
802          *
803          * @return      $fileIoInstance An instance to the file I/O sub-system
804          */
805         protected final function getFileIoInstance () {
806                 return $this->fileIoInstance;
807         }
808
809         /**
810          * Setter for file I/O instance
811          *
812          * @param       $fileIoInstance An instance to the file I/O sub-system
813          * @return      void
814          */
815         public final function setFileIoInstance (FileIoHandler $fileIoInstance) {
816                 $this->fileIoInstance = $fileIoInstance;
817         }
818
819         /**
820          * Prepare the template engine (WebTemplateEngine by default) for a given
821          * application helper instance (ApplicationHelper by default).
822          *
823          * @param               $applicationInstance    An application helper instance or
824          *                                                                              null if we shall use the default
825          * @return              $templateInstance               The template engine instance
826          * @throws              NullPointerException    If the discovered application
827          *                                                                              instance is still null
828          */
829         protected function prepareTemplateInstance (ManageableApplication $applicationInstance = null) {
830                 // Is the application instance set?
831                 if (is_null($applicationInstance)) {
832                         // Get the current instance
833                         $applicationInstance = $this->getApplicationInstance();
834
835                         // Still null?
836                         if (is_null($applicationInstance)) {
837                                 // Thrown an exception
838                                 throw new NullPointerException($this, self::EXCEPTION_IS_NULL_POINTER);
839                         } // END - if
840                 } // END - if
841
842                 // Initialize the template engine
843                 $templateInstance = ObjectFactory::createObjectByConfiguredName('web_template_class');
844
845                 // Return the prepared instance
846                 return $templateInstance;
847         }
848
849         /**
850          * Debugs this instance by putting out it's full content
851          *
852          * @param       $message        Optional message to show in debug output
853          * @return      void
854          */
855         public final function debugInstance ($message = '') {
856                 // Restore the error handler to avoid trouble with missing array elements or undeclared variables
857                 restore_error_handler();
858
859                 // Init content
860                 $content = '';
861
862                 // Is a message set?
863                 if (!empty($message)) {
864                         // Construct message
865                         $content = sprintf("<div class=\"debug_message\">Message: %s</div>\n", $message);
866                 } // END - if
867
868                 // Generate the output
869                 $content .= sprintf("<pre>%s</pre>",
870                         trim(
871                                 htmlentities(
872                                         print_r($this, true)
873                                 )
874                         )
875                 );
876
877                 // Output it
878                 ApplicationEntryPoint::app_die(sprintf("<div class=\"debug_header\">%s debug output:</div><div class=\"debug_content\">%s</div>\nLoaded includes: <div class=\"debug_include_list\">%s</div>",
879                         $this->__toString(),
880                         $content,
881                         ClassLoader::getInstance()->getPrintableIncludeList()
882                 ));
883         }
884
885         /**
886          * Replaces control characters with printable output
887          *
888          * @param       $str    String with control characters
889          * @return      $str    Replaced string
890          */
891         protected function replaceControlCharacters ($str) {
892                 // Replace them
893                 $str = str_replace(
894                         "\r", '[r]', str_replace(
895                         "\n", '[n]', str_replace(
896                         "\t", '[t]',
897                         $str
898                 )));
899
900                 // Return it
901                 return $str;
902         }
903
904         /**
905          * Output a partial stub message for the caller method
906          *
907          * @param       $message        An optional message to display
908          * @return      void
909          */
910         protected function partialStub ($message = '') {
911                 // Get the backtrace
912                 $backtrace = debug_backtrace();
913
914                 // Generate the class::method string
915                 $methodName = 'UnknownClass-&gt;unknownMethod';
916                 if ((isset($backtrace[1]['class'])) && (isset($backtrace[1]['function']))) {
917                         $methodName = $backtrace[1]['class'] . '-&gt;' . $backtrace[1]['function'];
918                 } // END - if
919
920                 // Construct the full message
921                 $stubMessage = sprintf("[%s:] Partial stub!",
922                         $methodName
923                 );
924
925                 // Is the extra message given?
926                 if (!empty($message)) {
927                         // Then add it as well
928                         $stubMessage .= sprintf(" Message: <span id=\"stub_message\">%s</span>", $message);
929                 } // END - if
930
931                 // Debug instance is there?
932                 if (!is_null($this->getDebugInstance())) {
933                         // Output stub message
934                         $this->debugOutput($stubMessage);
935                 } else {
936                         // Trigger an error
937                         trigger_error($stubMessage . "<br />\n");
938                 }
939         }
940
941         /**
942          * Outputs a debug backtrace and stops further script execution
943          *
944          * @param       $message        An optional message to output
945          * @return      void
946          */
947         public function debugBackTrace ($message = '') {
948                 // Sorry, there is no other way getting this nice backtrace
949                 if (!empty($message)) {
950                         // Output message
951                         printf("Message: %s<br />\n", $message);
952                 } // END - if
953
954                 print("<pre>\n");
955                 debug_print_backtrace();
956                 print("</pre>");
957                 exit();
958         }
959
960         /**
961          * Outputs a debug message wether to debug instance (should be set!) or dies with or pints the message
962          *
963          * @param       $message        Message we shall send out...
964          * @param       $doPrint        Wether we shall print or die here which first is the default
965          * @return      void
966          */
967         public function debugOutput ($message, $doPrint = true) {
968                 // Get debug instance
969                 $debugInstance = $this->getDebugInstance();
970
971                 // Is the debug instance there?
972                 if (is_object($debugInstance)) {
973                         // Use debug output handler
974                         $debugInstance->output($message);
975
976                         if ($doPrint === false) {
977                                 // Die here if not printed
978                                 die();
979                         } // END - if
980                 } else {
981                         // Put directly out
982                         if ($doPrint === true) {
983                                 print($message);
984                         } else {
985                                 // DO NOT REWRITE THIS TO app_die() !!!
986                                 die($message);
987                         }
988                 }
989         }
990
991         /**
992          * Converts e.g. a command from URL to a valid class by keeping out bad characters
993          *
994          * @param       $str            The string, what ever it is needs to be converted
995          * @return      $className      Generated class name
996          */
997         public function convertToClassName ($str) {
998                 // Init class name
999                 $className = '';
1000
1001                 // Convert all dashes in underscores
1002                 $str = $this->convertDashesToUnderscores($str);
1003
1004                 // Now use that underscores to get classname parts for hungarian style
1005                 foreach (explode('_', $str) as $strPart) {
1006                         // Make the class name part lower case and first upper case
1007                         $className .= ucfirst(strtolower($strPart));
1008                 } // END - foreach
1009
1010                 // Return class name
1011                 return $className;
1012         }
1013
1014         /**
1015          * Converts dashes to underscores, e.g. useable for configuration entries
1016          *
1017          * @param       $str    The string with maybe dashes inside
1018          * @return      $str    The converted string with no dashed, but underscores
1019          */
1020         public final function convertDashesToUnderscores ($str) {
1021                 // Convert them all
1022                 $str = str_replace('-', '_', $str);
1023
1024                 // Return converted string
1025                 return $str;
1026         }
1027
1028         /**
1029          * Marks up the code by adding e.g. line numbers
1030          *
1031          * @param       $phpCode                Unmarked PHP code
1032          * @return      $markedCode             Marked PHP code
1033          */
1034         public function markupCode ($phpCode) {
1035                 // Init marked code
1036                 $markedCode = '';
1037
1038                 // Get last error
1039                 $errorArray = error_get_last();
1040
1041                 // Init the code with error message
1042                 if (is_array($errorArray)) {
1043                         // Get error infos
1044                         $markedCode = sprintf("<div id=\"error_header\">File: <span id=\"error_data\">%s</span>, Line: <span id=\"error_data\">%s</span>, Message: <span id=\"error_data\">%s</span>, Type: <span id=\"error_data\">%s</span></div>",
1045                                 basename($errorArray['file']),
1046                                 $errorArray['line'],
1047                                 $errorArray['message'],
1048                                 $errorArray['type']
1049                         );
1050                 } // END - if
1051
1052                 // Add line number to the code
1053                 foreach (explode("\n", $phpCode) as $lineNo => $code) {
1054                         // Add line numbers
1055                         $markedCode .= sprintf("<span id=\"code_line\">%s</span>: %s\n",
1056                                 ($lineNo + 1),
1057                                 htmlentities($code, ENT_QUOTES)
1058                         );
1059                 } // END - foreach
1060
1061                 // Return the code
1062                 return $markedCode;
1063         }
1064
1065         /**
1066          * Filter a given GMT timestamp (non Uni* stamp!) to make it look more
1067          * beatiful for web-based front-ends. If null is given a message id
1068          * null_timestamp will be resolved and returned.
1069          *
1070          * @param       $timestamp      Timestamp to prepare (filter) for display
1071          * @return      $readable       A readable timestamp
1072          */
1073         public function doFilterFormatTimestamp ($timestamp) {
1074                 // Default value to return
1075                 $readable = '???';
1076
1077                 // Is the timestamp null?
1078                 if (is_null($timestamp)) {
1079                         // Get a message string
1080                         $readable = $this->getLanguageInstance()->getMessage('null_timestamp');
1081                 } else {
1082                         switch ($this->getLanguageInstance()->getLanguageCode()) {
1083                                 case 'de': // German format is a bit different to default
1084                                         // Split the GMT stamp up
1085                                         $dateTime  = explode(' ', $timestamp  );
1086                                         $dateArray = explode('-', $dateTime[0]);
1087                                         $timeArray = explode(':', $dateTime[1]);
1088
1089                                         // Construct the timestamp
1090                                         $readable = sprintf($this->getConfigInstance()->getConfigEntry('german_date_time'),
1091                                                 $dateArray[0],
1092                                                 $dateArray[1],
1093                                                 $dateArray[2],
1094                                                 $timeArray[0],
1095                                                 $timeArray[1],
1096                                                 $timeArray[2]
1097                                         );
1098                                         break;
1099
1100                                 default: // Default is pass-through
1101                                         $readable = $timestamp;
1102                                         break;
1103                         } // END - switch
1104                 }
1105
1106                 // Return the stamp
1107                 return $readable;
1108         }
1109
1110         /**
1111          * Filter a given number into a localized number
1112          *
1113          * @param       $value          The raw value from e.g. database
1114          * @return      $localized      Localized value
1115          */
1116         public function doFilterFormatNumber ($value) {
1117                 // Generate it from config and localize dependencies
1118                 switch ($this->getLanguageInstance()->getLanguageCode()) {
1119                         case 'de': // German format is a bit different to default
1120                                 $localized = number_format($value, $this->getConfigInstance()->getConfigEntry('decimals'), ',', '.');
1121                                 break;
1122
1123                         default: // US, etc.
1124                                 $localized = number_format($value, $this->getConfigInstance()->getConfigEntry('decimals'), '.', ',');
1125                                 break;
1126                 } // END - switch
1127
1128                 // Return it
1129                 return $localized;
1130         }
1131
1132         /**
1133          * "Getter" for databse entry
1134          *
1135          * @return      $entry  An array with database entries
1136          * @throws      NullPointerException    If the database result is not found
1137          * @throws      InvalidDatabaseResultException  If the database result is invalid
1138          */
1139         protected final function getDatabaseEntry () {
1140                 // Is there an instance?
1141                 if (is_null($this->getResultInstance())) {
1142                         // Throw an exception here
1143                         throw new NullPointerException($this, self::EXCEPTION_IS_NULL_POINTER);
1144                 } // END - if
1145
1146                 // Rewind it
1147                 $this->getResultInstance()->rewind();
1148
1149                 // Do we have an entry?
1150                 if ($this->getResultInstance()->valid() === false) {
1151                         throw new InvalidDatabaseResultException(array($this, $this->getResultInstance()), DatabaseResult::EXCEPTION_INVALID_DATABASE_RESULT);
1152                 } // END - if
1153
1154                 // Get next entry
1155                 $this->getResultInstance()->next();
1156
1157                 // Fetch it
1158                 $entry = $this->getResultInstance()->current();
1159
1160                 // And return it
1161                 return $entry;
1162         }
1163
1164         /**
1165          * Getter for field name
1166          *
1167          * @param       $fieldName              Field name which we shall get
1168          * @return      $fieldValue             Field value from the user
1169          * @throws      NullPointerException    If the result instance is null
1170          */
1171         public final function getField ($fieldName) {
1172                 // Default field value
1173                 $fieldValue = null;
1174
1175                 // Get result instance
1176                 $resultInstance = $this->getResultInstance();
1177
1178                 // Is this instance null?
1179                 if (is_null($resultInstance)) {
1180                         // Then the user instance is no longer valid (expired cookies?)
1181                         throw new NullPointerException($this, self::EXCEPTION_IS_NULL_POINTER);
1182                 } // END - if
1183
1184                 // Get current array
1185                 $fieldArray = $resultInstance->current();
1186                 //* DEBUG: */ $this->debugOutput($fieldName.':<pre>'.print_r($fieldArray, true).'</pre>');
1187
1188                 // Does the field exist?
1189                 if (isset($fieldArray[$fieldName])) {
1190                         // Get it
1191                         $fieldValue = $fieldArray[$fieldName];
1192                 } // END - if
1193
1194                 // Return it
1195                 return $fieldValue;
1196         }
1197
1198         /**
1199          * Protected setter for user instance
1200          *
1201          * @param       $userInstance   An instance of a user class
1202          * @return      void
1203          */
1204         protected final function setUserInstance (ManageableAccount $userInstance) {
1205                 $this->userInstance = $userInstance;
1206         }
1207
1208         /**
1209          * Getter for user instance
1210          *
1211          * @return      $userInstance   An instance of a user class
1212          */
1213         public final function getUserInstance () {
1214                 return $this->userInstance;
1215         }
1216
1217         /**
1218          * Setter for controller instance (this surely breaks a bit the MVC patterm)
1219          *
1220          * @param       $controllerInstance             An instance of the controller
1221          * @return      void
1222          */
1223         public final function setControllerInstance (Controller $controllerInstance) {
1224                 $this->controllerInstance = $controllerInstance;
1225         }
1226
1227         /**
1228          * Getter for controller instance (this surely breaks a bit the MVC patterm)
1229          *
1230          * @return      $controllerInstance             An instance of the controller
1231          */
1232         public final function getControllerInstance () {
1233                 return $this->controllerInstance;
1234         }
1235
1236         /**
1237          * Flushs all pending updates to the database layer
1238          *
1239          * @return      void
1240          */
1241         public function flushPendingUpdates () {
1242                 // Get result instance
1243                 $resultInstance = $this->getResultInstance();
1244
1245                 // Do we have data to update?
1246                 if ((is_object($resultInstance)) && ($resultInstance->ifDataNeedsFlush())) {
1247                         // Get wrapper class name config entry
1248                         $configEntry = $resultInstance->getUpdateInstance()->getWrapperConfigEntry();
1249
1250                         // Create object instance
1251                         $wrapperInstance = ObjectFactory::createObjectByConfiguredName($configEntry);
1252
1253                         // Yes, then send the whole result to the database layer
1254                         $wrapperInstance->doUpdateByResult($this->getResultInstance());
1255                 } // END - if
1256         }
1257
1258         /**
1259          * Outputs a deprecation warning to the developer.
1260          *
1261          * @param       $message        The message we shall output to the developer
1262          * @return      void
1263          * @todo        Write a logging mechanism for productive mode
1264          */
1265         public function deprecationWarning ($message) {
1266                 // Is developer mode active?
1267                 if (defined('DEVELOPER')) {
1268                         // Debug instance is there?
1269                         if (!is_null($this->getDebugInstance())) {
1270                                 // Output stub message
1271                                 $this->debugOutput($message);
1272                         } else {
1273                                 // Trigger an error
1274                                 trigger_error($message . "<br />\n");
1275                         }
1276                 } else {
1277                         // @TODO Finish this part!
1278                         $this->partialStub('Developer mode inactive. Message:' . $message);
1279                 }
1280         }
1281
1282         /**
1283          * Checks wether the given PHP extension is loaded
1284          *
1285          * @param       $phpExtension   The PHP extension we shall check
1286          * @return      $isLoaded       Wether the PHP extension is loaded
1287          */
1288         public final function isPhpExtensionLoaded ($phpExtension) {
1289                 // Is it loaded?
1290                 $isLoaded = in_array($phpExtension, get_loaded_extensions());
1291
1292                 // Return result
1293                 return $isLoaded;
1294         }
1295
1296         /**
1297          * Setter for RNG instance
1298          *
1299          * @param       $rngInstance    An instance of a random number generator (RNG)
1300          * @return      void
1301          */
1302         protected final function setRngInstance (RandomNumberGenerator $rngInstance) {
1303                 $this->rngInstance = $rngInstance;
1304         }
1305
1306         /**
1307          * Getter for RNG instance
1308          *
1309          * @return      $rngInstance    An instance of a random number generator (RNG)
1310          */
1311         public final function getRngInstance () {
1312                 return $this->rngInstance;
1313         }
1314
1315         /**
1316          * Setter for Cryptable instance
1317          *
1318          * @param       $cryptoInstance An instance of a Cryptable class
1319          * @return      void
1320          */
1321         protected final function setCryptoInstance (Cryptable $cryptoInstance) {
1322                 $this->cryptoInstance = $cryptoInstance;
1323         }
1324
1325         /**
1326          * Getter for Cryptable instance
1327          *
1328          * @return      $cryptoInstance An instance of a Cryptable class
1329          */
1330         public final function getCryptoInstance () {
1331                 return $this->cryptoInstance;
1332         }
1333
1334         /**
1335          * Setter for Iterator instance
1336          *
1337          * @param       $iteratorInstance       An instance of an Iterator
1338          * @return      void
1339          */
1340         protected final function setIteratorInstance (Iterator $iteratorInstance) {
1341                 $this->iteratorInstance = $iteratorInstance;
1342         }
1343
1344         /**
1345          * Getter for Iterator instance
1346          *
1347          * @return      $iteratorInstance       An instance of an Iterator
1348          */
1349         public final function getIteratorInstance () {
1350                 return $this->iteratorInstance;
1351         }
1352
1353         /**
1354          * "Getter" as a time() replacement but with milliseconds. You should use this
1355          * method instead of the encapsulated getimeofday() function.
1356          *
1357          * @return      $milliTime      Timestamp with milliseconds
1358          */
1359         public function getMilliTime () {
1360                 // Get the time of day as float
1361                 $milliTime = gettimeofday(true);
1362
1363                 // Return it
1364                 return $milliTime;
1365         }
1366
1367         /**
1368          * Idles (sleeps) for given milliseconds
1369          *
1370          * @return      $hasSlept       Wether it goes fine
1371          */
1372         public function idle ($milliSeconds) {
1373                 // Sleep is fine by default
1374                 $hasSlept = true;
1375
1376                 // Idle so long with found function
1377                 if (function_exists('time_sleep_until')) {
1378                         // Get current time and add idle time
1379                         $sleepUntil = $this->getMilliTime() + abs($milliSeconds) / 1000;
1380
1381                         // New PHP 5.1.0 function found, ignore errors
1382                         $hasSlept = @time_sleep_until($sleepUntil);
1383                 } else {
1384                         // My Sun Station doesn't have that function even with latest PHP
1385                         // package. :(
1386                         usleep($milliSeconds * 1000);
1387                 }
1388
1389                 // Return result
1390                 return $hasSlept;
1391         }
1392
1393         /**
1394          * Setter for the list instance
1395          *
1396          * @param       $listInstance   A list of Listable
1397          * @return      void
1398          */
1399         protected final function setListInstance (Listable $listInstance) {
1400                 $this->listInstance = $listInstance;
1401         }
1402
1403         /**
1404          * Getter for the list instance
1405          *
1406          * @return      $listInstance   A list of Listable
1407          */
1408         protected final function getListInstance () {
1409                 return $this->listInstance;
1410         }
1411
1412         /**
1413          * Setter for the menu instance
1414          *
1415          * @param       $menuInstance   A RenderableMenu instance
1416          * @return      void
1417          */
1418         protected final function setMenuInstance (RenderableMenu $menuInstance) {
1419                 $this->menuInstance = $menuInstance;
1420         }
1421
1422         /**
1423          * Getter for the menu instance
1424          *
1425          * @return      $menuInstance   A RenderableMenu instance
1426          */
1427         protected final function getMenuInstance () {
1428                 return $this->menuInstance;
1429         }
1430
1431         /**
1432          * Setter for image instance
1433          *
1434          * @param       $imageInstance  An instance of an image
1435          * @return      void
1436          */
1437         public final function setImageInstance (BaseImage $imageInstance) {
1438                 $this->imageInstance = $imageInstance;
1439         }
1440
1441         /**
1442          * Getter for image instance
1443          *
1444          * @return      $imageInstance  An instance of an image
1445          */
1446         public final function getImageInstance () {
1447                 return $this->imageInstance;
1448         }
1449
1450         /**
1451          * Setter for stacker instance
1452          *
1453          * @param       $stackerInstance        An instance of an stacker
1454          * @return      void
1455          */
1456         public final function setStackerInstance (Stackable $stackerInstance) {
1457                 $this->stackerInstance = $stackerInstance;
1458         }
1459
1460         /**
1461          * Getter for stacker instance
1462          *
1463          * @return      $stackerInstance        An instance of an stacker
1464          */
1465         public final function getStackerInstance () {
1466                 return $this->stackerInstance;
1467         }
1468
1469         /**
1470          * Setter for compressor instance
1471          *
1472          * @param       $compressorInstance     An instance of an compressor
1473          * @return      void
1474          */
1475         public final function setCompressorInstance (Compressor $compressorInstance) {
1476                 $this->compressorInstance = $compressorInstance;
1477         }
1478
1479         /**
1480          * Getter for compressor instance
1481          *
1482          * @return      $compressorInstance     An instance of an compressor
1483          */
1484         public final function getCompressorInstance () {
1485                 return $this->compressorInstance;
1486         }
1487
1488         /**
1489          * Setter for Parseable instance
1490          *
1491          * @param       $parserInstance An instance of an Parseable
1492          * @return      void
1493          */
1494         public final function setParserInstance (Parseable $parserInstance) {
1495                 $this->parserInstance = $parserInstance;
1496         }
1497
1498         /**
1499          * Getter for Parseable instance
1500          *
1501          * @return      $parserInstance An instance of an Parseable
1502          */
1503         public final function getParserInstance () {
1504                 return $this->parserInstance;
1505         }
1506
1507         /**
1508          * Setter for ProtocolHandler instance
1509          *
1510          * @param       $protocolInstance       An instance of an ProtocolHandler
1511          * @return      void
1512          */
1513         public final function setProtocolInstance (ProtocolHandler $protocolInstance) {
1514                 $this->protocolInstance = $protocolInstance;
1515         }
1516
1517         /**
1518          * Getter for ProtocolHandler instance
1519          *
1520          * @return      $protocolInstance       An instance of an ProtocolHandler
1521          */
1522         public final function getProtocolInstance () {
1523                 return $this->protocolInstance;
1524         }
1525
1526         /**
1527          * Setter for BaseDatabaseWrapper instance
1528          *
1529          * @param       $wrapperInstance        An instance of an BaseDatabaseWrapper
1530          * @return      void
1531          */
1532         public final function setWrapperInstance (BaseDatabaseWrapper $wrapperInstance) {
1533                 $this->wrapperInstance = $wrapperInstance;
1534         }
1535
1536         /**
1537          * Getter for BaseDatabaseWrapper instance
1538          *
1539          * @return      $wrapperInstance        An instance of an BaseDatabaseWrapper
1540          */
1541         public final function getWrapperInstance () {
1542                 return $this->wrapperInstance;
1543         }
1544
1545         /**
1546          * Setter for socket resource
1547          *
1548          * @param       $socketResource         A valid socket resource
1549          * @return      void
1550          */
1551         public final function setSocketResource ($socketResource) {
1552                 $this->socketResource = $socketResource;
1553         }
1554
1555         /**
1556          * Getter for socket resource
1557          *
1558          * @return      $socketResource         A valid socket resource
1559          */
1560         public function getSocketResource () {
1561                 return $this->socketResource;
1562         }
1563
1564         /**
1565          * Setter for helper instance
1566          *
1567          * @param       $helperInstance         An instance of a helper class
1568          * @return      void
1569          */
1570         protected final function setHelperInstance (Helper $helperInstance) {
1571                 $this->helperInstance = $helperInstance;
1572         }
1573
1574         /**
1575          * Getter for helper instance
1576          *
1577          * @return      $helperInstance         An instance of a helper class
1578          */
1579         public final function getHelperInstance () {
1580                 return $this->helperInstance;
1581         }
1582
1583         /**
1584          * Setter for a Sourceable instance
1585          *
1586          * @param       $sourceInstance The Sourceable instance
1587          * @return      void
1588          */
1589         protected final function setSourceInstance (Sourceable $sourceInstance) {
1590                 $this->sourceInstance = $sourceInstance;
1591         }
1592
1593         /**
1594          * Getter for a InputStreamable instance
1595          *
1596          * @param       $inputStreamInstance    The InputStreamable instance
1597          */
1598         protected final function getInputStreamInstance () {
1599                 return $this->inputStreamInstance;
1600         }
1601
1602         /**
1603          * Setter for a InputStreamable instance
1604          *
1605          * @param       $inputStreamInstance    The InputStreamable instance
1606          * @return      void
1607          */
1608         protected final function setInputStreamInstance (InputStreamable $inputStreamInstance) {
1609                 $this->inputStreamInstance = $inputStreamInstance;
1610         }
1611
1612         /**
1613          * Getter for a OutputStreamable instance
1614          *
1615          * @param       $outputStreamInstance   The OutputStreamable instance
1616          */
1617         protected final function getOutputStreamInstance () {
1618                 return $this->outputStreamInstance;
1619         }
1620
1621         /**
1622          * Setter for a OutputStreamable instance
1623          *
1624          * @param       $outputStreamInstance   The OutputStreamable instance
1625          * @return      void
1626          */
1627         protected final function setOutputStreamInstance (OutputStreamable $outputStreamInstance) {
1628                 $this->outputStreamInstance = $outputStreamInstance;
1629         }
1630
1631         /**
1632          * Setter for handler instance
1633          *
1634          * @param       $handlerInstance        A Networkable instance
1635          * @return      void
1636          */
1637         protected final function setHandlerInstance (Networkable $handlerInstance) {
1638                 $this->handlerInstance = $handlerInstance;
1639         }
1640
1641         /**
1642          * Getter for handler instance
1643          *
1644          * @return      $handlerInstance        A Networkable instance
1645          */
1646         protected final function getHandlerInstance () {
1647                 return $this->handlerInstance;
1648         }
1649
1650         /**
1651          * Setter for visitor instance
1652          *
1653          * @param       $visitorInstance        A Visitor instance
1654          * @return      void
1655          */
1656         protected final function setVisitorInstance (Visitor $visitorInstance) {
1657                 $this->visitorInstance = $visitorInstance;
1658         }
1659
1660         /**
1661          * Getter for visitor instance
1662          *
1663          * @return      $visitorInstance        A Visitor instance
1664          */
1665         protected final function getVisitorInstance () {
1666                 return $this->visitorInstance;
1667         }
1668
1669         /**
1670          * Setter for raw package Data
1671          *
1672          * @param       $packageData    Raw package Data
1673          * @return      void
1674          */
1675         public final function setPackageData (array $packageData) {
1676                 $this->packageData = $packageData;
1677         }
1678
1679         /**
1680          * Getter for raw package Data
1681          *
1682          * @return      $packageData    Raw package Data
1683          */
1684         public function getPackageData () {
1685                 return $this->packageData;
1686         }
1687
1688         /**
1689          * Converts a hexadecimal string, even with negative sign as first string to
1690          * a decimal number using BC functions.
1691          *
1692          * This work is based on comment #86673 on php.net documentation page at:
1693          * <http://de.php.net/manual/en/function.dechex.php#86673>
1694          *
1695          * @param       $hex    Hexadecimal string
1696          * @return      $dec    Decimal number
1697          */
1698         protected function hex2dec ($hex) {
1699                 // Convert to all lower-case
1700                 $hex = strtolower($hex);
1701
1702                 // Detect sign (negative/positive numbers)
1703                 $sign = '';
1704                 if (substr($hex, 0, 1) == '-') {
1705                         $sign = '-';
1706                         $hex = substr($hex, 1);
1707                 } // END - if
1708
1709                 // Decode the hexadecimal string into a decimal number
1710                 $dec = 0;
1711                 for ($i = strlen($hex) - 1, $e = 1; $i >= 0; $i--, $e = bcmul($e, 16)) {
1712                         $factor = self::$hexdec[substr($hex, $i, 1)];
1713                         $dec = bcadd($dec, bcmul($factor, $e));
1714                 } // END - for
1715
1716                 // Return the decimal number
1717                 return $sign . $dec;
1718         }
1719
1720         /**
1721          * Converts even very large decimal numbers, also with negative sign, to a
1722          * hexadecimal string.
1723          *
1724          * This work is based on comment #97756 on php.net documentation page at:
1725          * <http://de.php.net/manual/en/function.hexdec.php#97756>
1726          *
1727          * @param       $dec            Decimal number, even with negative sign
1728          * @param       $maxLength      Optional maximum length of the string
1729          * @return      $hex    Hexadecimal string
1730          */
1731         protected function dec2hex ($dec, $maxLength = 0) {
1732                 // maxLength can be zero or devideable by 2
1733                 assert(($maxLength == 0) || (($maxLength % 2) == 0));
1734
1735                 // Detect sign (negative/positive numbers)
1736                 $sign = '';
1737                 if ($dec < 0) {
1738                         $sign = '-';
1739                         $dec = abs($dec);
1740                 } // END - if
1741
1742                 // Encode the decimal number into a hexadecimal string
1743                 $hex = '';
1744                 do {
1745                         $hex = self::$dechex[($dec % 16)] . $hex;
1746                         $dec /= 16;
1747                 } while ($dec >= 1);
1748
1749                 /*
1750                  * We need hexadecimal strings with leading zeros if the length cannot
1751                  * be divided by 2
1752                  */
1753                 if ($maxLength > 0) {
1754                         // Prepend more zeros
1755                         $hex = $this->prependStringToString($hex, '0', $maxLength);
1756                 } elseif ((strlen($hex) % 2) != 0) {
1757                         $hex = '0' . $hex;
1758                 }
1759
1760                 // Return the hexadecimal string
1761                 return $sign . $hex;
1762         }
1763
1764         /**
1765          * Converts a ASCII string (0 to 255) into a decimal number.
1766          *
1767          * @param       $asc    The ASCII string to be converted
1768          * @return      $dec    Decimal number
1769          */
1770         protected function asc2dec ($asc) {
1771                 // Convert it into a hexadecimal number
1772                 $hex = bin2hex($asc);
1773
1774                 // And back into a decimal number
1775                 $dec = $this->hex2dec($hex);
1776
1777                 // Return it
1778                 return $dec;
1779         }
1780
1781         /**
1782          * Converts a decimal number into an ASCII string.
1783          *
1784          * @param       $dec            Decimal number
1785          * @return      $asc    An ASCII string
1786          */
1787         protected function dec2asc ($dec) {
1788                 // First convert the number into a hexadecimal string
1789                 $hex = $this->dec2hex($dec);
1790
1791                 // Then convert it into the ASCII string
1792                 $asc = $this->hex2asc($hex);
1793
1794                 // Return it
1795                 return $asc;
1796         }
1797
1798         /**
1799          * Converts a hexadecimal number into an ASCII string. Negative numbers
1800          * are not allowed.
1801          *
1802          * @param       $hex    Hexadecimal string
1803          * @return      $asc    An ASCII string
1804          */
1805         protected function hex2asc ($hex) {
1806                 // Check for length, it must be devideable by 2
1807                 //* DEBUG: */ $this->debugOutput('hex='.$hex);
1808                 assert((strlen($hex) % 2) == 0);
1809
1810                 // Walk the string
1811                 $asc = '';
1812                 for ($idx = 0; $idx < strlen($hex); $idx+=2) {
1813                         // Get the decimal number of the chunk
1814                         $part = hexdec(substr($hex, $idx, 2));
1815
1816                         // Add it to the final string
1817                         $asc .= chr($part);
1818                 } // END - for
1819
1820                 // Return the final string
1821                 return $asc;
1822         }
1823
1824         /**
1825          * Prepends a given string $prepend to $str with a given total length
1826          *
1827          * @param       $str            Given original string which should be prepended
1828          * @param       $prepend        The string to prepend
1829          * @param       $length         Total length of the final string
1830          * @return      $strFinal       Final prepended string
1831          */
1832         protected function prependStringToString ($str, $prepend, $length) {
1833                 // Set final string to original string by default
1834                 $strFinal = $str;
1835
1836                 // Can it devided
1837                 if (strlen($str) < $length) {
1838                         // Difference between total length and length of original string
1839                         $diff = $length - strlen($str);
1840
1841                         // Prepend the string
1842                         $prepend = str_repeat($prepend, ($diff / strlen($prepend) + 1));
1843
1844                         // Make sure it will definedly fit
1845                         assert(strlen($prepend) >= $diff);
1846
1847                         // Cut it a little down
1848                         $prepend = substr($prepend, 0, $diff);
1849                         //* DEBUG: */ $this->debugOutput('prepend('.strlen($prepend).')='.$prepend.',diff='.$diff.',length='.$length);
1850
1851                         // Construct the final prepended string
1852                         $strFinal = $prepend . $str;
1853                 } // END - if
1854
1855                 // Return it
1856                 return $strFinal;
1857         }
1858
1859         /**
1860          * Checks wether the given encoded data was encoded with Base64
1861          *
1862          * @param       $encodedData    Encoded data we shall check
1863          * @return      $isBase64               Wether the encoded data is Base64
1864          */
1865         protected function isBase64Encoded ($encodedData) {
1866                 // Determine it
1867                 $isBase64 = (@base64_decode($encodedData, true) !== false);
1868
1869                 // Return it
1870                 return $isBase64;
1871         }
1872 }
1873
1874 // [EOF]
1875 ?>