Continued:
[core.git] / framework / main / classes / file_directories / class_BaseFileIo.php
1 <?php
2 // Own namespace
3 namespace Org\Mxchange\CoreFramework\Filesystem;
4
5 // Import framework stuff
6 use Org\Mxchange\CoreFramework\Filesystem\CloseableFile;
7 use Org\Mxchange\CoreFramework\Filesystem\FilePointer;
8 use Org\Mxchange\CoreFramework\Generic\FrameworkInterface;
9 use Org\Mxchange\CoreFramework\Generic\NullPointerException;
10 use Org\Mxchange\CoreFramework\Object\BaseFrameworkSystem;
11
12 // Import SPL stuff
13 use \OutOfBoundsException;
14 use \SplFileObject;
15
16 /**
17  * A general FileIo class
18  *
19  * @author              Roland Haeder <webmaster@ship-simu.org>
20  * @version             0.0.0
21  * @copyright   Copyright (c) 2007, 2008 Roland Haeder, 2009 - 2023 Core Developer Team
22  * @license             GNU GPL 3.0 or any newer version
23  * @link                http://www.ship-simu.org
24  *
25  * This program is free software: you can redistribute it and/or modify
26  * it under the terms of the GNU General Public License as published by
27  * the Free Software Foundation, either version 3 of the License, or
28  * (at your option) any later version.
29  *
30  * This program is distributed in the hope that it will be useful,
31  * but WITHOUT ANY WARRANTY; without even the implied warranty of
32  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
33  * GNU General Public License for more details.
34  *
35  * You should have received a copy of the GNU General Public License
36  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
37  */
38 abstract class BaseFileIo extends BaseFrameworkSystem implements FilePointer, CloseableFile {
39         /**
40          * The file object
41          */
42         private $fileObject = NULL;
43
44         /**
45          * Protected constructor
46          *
47          * @param       $className      Name of the class
48          * @return      void
49          */
50         protected function __construct (string $className) {
51                 // Call parent constructor
52                 /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-FILE-IO: className=%s - CONSTRUCTED!', $className));
53                 parent::__construct($className);
54
55                 // Trace message
56                 /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage('BASE-FILE-IO: EXIT!');
57         }
58
59         /**
60          * Destructor for cleaning purposes, etc
61          *
62          * @return      void
63          */
64         public final function __destruct() {
65                 // Is there a resource pointer? Then we have to close the file here!
66                 /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-FILE-IO: this->fileObject[]=%s - DESTRUCTOR!', gettype($this->getFileObject())));
67                 if (is_object($this->getFileObject())) {
68                         // Try to close a file
69                         /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage('BASE-FILE-IO: Invoking this->closeFile() ...');
70                         $this->closeFile();
71                 }
72
73                 // Call the parent destructor
74                 parent::__destruct();
75
76                 // Trace message
77                 /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage('BASE-FILE-IO: EXIT!');
78         }
79
80         /**
81          * Close a file source and set it's instance to null and the file name
82          * to empty.
83          *
84          * @return      void
85          * @throws      NullPointerException    If the file pointer instance is not set by setFileObject()
86          * @throws      LogicException  If there is no object being set
87          */
88         public function closeFile () {
89                 // Validate parameter
90                 /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-FILE-IO: fileName=%s - CALLED!', $this->getFileObject()->getPathname()));
91                 if (is_null($this->getFileObject())) {
92                         // Pointer not initialized
93                         throw new NullPointerException($this, FrameworkInterface::EXCEPTION_IS_NULL_POINTER);
94                 } elseif (!is_object($this->getFileObject())) {
95                         // Pointer is not a valid resource!
96                         throw new LogicException(sprintf('this->fileObject[]=%s is no object', gettype($this->getFileObject())), FrameworkInterface::EXCEPTION_LOGIC_EXCEPTION);
97                 }
98
99                 // Close the file pointer by NULL-ing it
100                 /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugMessage(sprintf('BASE-FILE-IO: Closing file %s ...', $this->getFileObject()->getPathname()));
101                 $this->resetFileObject();
102
103                 // Trace message
104                 /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage('BASE-FILE-IO: EXIT!');
105         }
106
107         /**
108          * Resets file object instance to NULL
109          *
110          * @return      void
111          */
112         protected final function resetFileObject () {
113                 // Set it to NULL
114                 /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage('BASE-FILE-IO: Setting this->fileObject=NULL - CALLED!');
115                 $this->fileObject = NULL;
116
117                 // Trace message
118                 /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage('BASE-FILE-IO: EXIT!');
119         }
120
121         /**
122          * Setter for the file object
123          *
124          * @param       $fileObject             An instance of a SplFileObject class
125          * @return      void
126          */
127         protected final function setFileObject (SplFileObject $fileObject) {
128                 $this->fileObject = $fileObject;
129         }
130
131         /**
132          * Getter for the file object
133          *
134          * @return      $fileObject             An instance of a SplFileObject class
135          */
136         public final function getFileObject () {
137                 return $this->fileObject;
138         }
139
140         /**
141          * Determines seek position
142          *
143          * @return      $seekPosition   Current seek position
144          */
145         public final function determineSeekPosition () {
146                 return $this->getFileObject()->ftell();
147         }
148
149         /**
150          * Determines whether the EOF has been reached
151          *
152          * @return      $isEndOfFileReached             Whether the EOF has been reached
153          */
154         public final function isEndOfFileReached () {
155                 return $this->getFileObject()->eof();
156         }
157
158         /**
159          * Seek to given offset (default) or other possibilities as fseek() gives.
160          *
161          * @param       $offset         Offset to seek to (or used as "base" for other seeks)
162          * @param       $whence         Added to offset (default: only use offset to seek to)
163          * @return      $status         Status of file seek: 0 = success, -1 = failed
164          */
165         public function seek (int $offset, int $whence = SEEK_SET) {
166                 // Validate parameter
167                 /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-FILE-IO: offset=%d,whence=%d - CALLED!', $offset, $whence));
168                 if ($offset < 0) {
169                         // Throw exception
170                         throw new OutOfBoundsException(sprintf('offset=%d is not valid', $offset));
171                 }
172
173                 // Seek to position
174                 $status = $this->getFileObject()->fseek($offset, $whence);
175
176                 // Return status
177                 /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-FILE-IO: status=%d - EXIT!', $status));
178                 return $status;
179         }
180
181         /**
182          * Size of this file
183          *
184          * @return      $size   Size (in bytes) of file
185          * @todo        Handle seekStatus
186          */
187         public function size () {
188                 // Get current seek position
189                 /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage('BASE-FILE-IO: CALLED!');
190                 $seekPosition = $this->determineSeekPosition();
191
192                 // Seek to end
193                 $seekStatus = $this->seek(0, SEEK_END);
194
195                 // Get position again (which is the end of the file)
196                 /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugMessage(sprintf('BASE-FILE-IO: seekStatus[%s]=%d', gettype($seekStatus), $seekStatus));
197                 $size = $this->determineSeekPosition();
198
199                 // Reset seek position to old
200                 /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugMessage(sprintf('BASE-FILE-IO: size[%s]=%d', gettype($size), $size));
201                 $this->seek($seekPosition);
202
203                 // Return size
204                 /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-FILE-IO: size=%d - EXIT!', $size));
205                 return $size;
206         }
207
208 }