GammaLib 2.0.0
Loading...
Searching...
No Matches
GUrlFile.cpp
Go to the documentation of this file.
1/***************************************************************************
2 * GUrlFile.cpp - File URL class *
3 * ----------------------------------------------------------------------- *
4 * copyright (C) 2013-2021 by Juergen Knoedlseder *
5 * ----------------------------------------------------------------------- *
6 * *
7 * This program is free software: you can redistribute it and/or modify *
8 * it under the terms of the GNU General Public License as published by *
9 * the Free Software Foundation, either version 3 of the License, or *
10 * (at your option) any later version. *
11 * *
12 * This program is distributed in the hope that it will be useful, *
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15 * GNU General Public License for more details. *
16 * *
17 * You should have received a copy of the GNU General Public License *
18 * along with this program. If not, see <http://www.gnu.org/licenses/>. *
19 * *
20 ***************************************************************************/
21/**
22 * @file GUrlFile.cpp
23 * @brief File URL class interface implementation
24 * @author Juergen Knoedlseder
25 */
26
27/* __ Includes ___________________________________________________________ */
28#ifdef HAVE_CONFIG_H
29#include <config.h>
30#endif
31#include <cstdarg> // std::va_list
32#include <cstdio> // std::fopen, std::fgets, std::fclose, etc...
33#include "GUrlFile.hpp"
34#include "GTools.hpp"
35#include "GException.hpp"
36
37/* __ Method name definitions ____________________________________________ */
38#define G_OPEN "GUrlFile::open(std::string&, std::string&)"
39
40/* __ Macros _____________________________________________________________ */
41
42/* __ Coding definitions _________________________________________________ */
43
44/* __ Debug definitions __________________________________________________ */
45
46
47/*==========================================================================
48 = =
49 = Constructors/destructors =
50 = =
51 ==========================================================================*/
52
53/***********************************************************************//**
54 * @brief Void constructor
55 ***************************************************************************/
57{
58 // Initialise members
60
61 // Return
62 return;
63}
64
65
66/***********************************************************************//**
67 * @brief Opening constructor
68 *
69 * @param[in] url File name.
70 * @param[in] mode File mode.
71 *
72 * Constructs GUrlFile object by opening a file @p url in the specified
73 * @p mode. Any environment variable present in the file name will be
74 * automatically expanded.
75 ***************************************************************************/
76GUrlFile::GUrlFile(const std::string& url, const std::string& mode) : GUrl()
77{
78 // Initialise members
80
81 // Open file
82 open(url, mode);
83
84 // Return
85 return;
86}
87
88
89/***********************************************************************//**
90 * @brief Copy constructor
91 *
92 * @param[in] url URL.
93 ***************************************************************************/
95{
96 // Initialise members
98
99 // Copy members
100 copy_members(url);
101
102 // Return
103 return;
104}
105
106
107/***********************************************************************//**
108 * @brief Destructor
109 ***************************************************************************/
111{
112 // Free members
113 free_members();
114
115 // Return
116 return;
117}
118
119
120/*==========================================================================
121 = =
122 = Operators =
123 = =
124 ==========================================================================*/
125
126/***********************************************************************//**
127 * @brief Assignment operator
128 *
129 * @param[in] url URL.
130 * @return URL.
131 ***************************************************************************/
133{
134 // Execute only if object is not identical
135 if (this != &url) {
136
137 // Copy base class members
138 this->GUrl::operator=(url);
139
140 // Free members
141 free_members();
142
143 // Initialise members
144 init_members();
145
146 // Copy members
147 copy_members(url);
148
149 } // endif: object was not identical
150
151 // Return
152 return *this;
153}
154
155
156/*==========================================================================
157 = =
158 = Public methods =
159 = =
160 ==========================================================================*/
161
162/***********************************************************************//**
163 * @brief Clear instance
164 ***************************************************************************/
166{
167 // Free class members
168 free_members();
169 this->GUrl::free_members();
170
171 // Initialise members
172 this->GUrl::init_members();
173 init_members();
174
175 // Return
176 return;
177}
178
179
180/***********************************************************************//**
181 * @brief Clone instance
182 *
183 * @return Pointer to deep copy of file URL.
184 ***************************************************************************/
186{
187 // Clone object
188 return new GUrlFile(*this);
189}
190
191
192/***********************************************************************//**
193 * @brief Open file
194 *
195 * @param[in] url File name.
196 * @param[in] mode File mode.
197 *
198 * @exception GException::file_error
199 * Unable to open file.
200 *
201 * Opens a file @p url in the specified @p mode. Any environment variable
202 * present in the filename will be automatically expanded.
203 *
204 * @todo Strip any file:// prefix
205 ***************************************************************************/
206void GUrlFile::open(const std::string& url, const std::string& mode)
207{
208 // First close any existing file
209 close();
210
211 // Expand environment variables
212 std::string filename = gammalib::expand_env(url);
213
214 // Try opening file. Throw an exception if opening failed.
215 m_fptr = std::fopen(filename.c_str(), mode.c_str());
216 if (m_fptr == NULL) {
217 std::string msg = "Unable to open file \""+filename+"\" in mode \""+
218 mode+"\". Please specify an accessible file.";
219 throw GException::file_error(G_OPEN, msg);
220 }
221
222 // Store URL and mode
223 m_url = url;
224 m_mode = mode;
225
226 // Return
227 return;
228}
229
230
231/***********************************************************************//**
232 * @brief Close file
233 ***************************************************************************/
235{
236 // Close file
237 if (m_fptr != NULL) {
238 std::fclose(m_fptr);
239 }
240
241 // Reset members
242 m_url.clear();
243 m_mode.clear();
244 m_fptr = NULL;
245
246 // Return
247 return;
248}
249
250
251/***********************************************************************//**
252 * @brief Read block of data from file in buffer
253 *
254 * @param[in] buffer Data buffer.
255 * @param[in] nbyte Number of Bytes to be read.
256 * @return Number of Bytes that were effectively read.
257 *
258 * Reads @p nbyte Bytes from the file into a @p buffer. The position
259 * indicator of the file is advanced by the total amount of bytes read.
260 *
261 * The total number of Bytes successfully read is returned. If this number
262 * differs from the @p nbyte parameter, either a reading error occurred or
263 * the end-of-file was reached while reading. In both cases, the proper
264 * indicator is set.
265 *
266 * If either @p buffer is NULL or @p nbyte is zero, the method returns zero
267 * and both the file state and the content pointed by @p buffer remain
268 * unchanged.
269 *
270 * If no file has been opened, the method returns zero and both the file
271 * state and the content pointed by @p buffer remain unchanged.
272 ***************************************************************************/
273int GUrlFile::read(void* buffer, const int& nbyte)
274{
275 // Initialise number of Bytes read
276 int nread = 0;
277
278 // Continue only if file is opened
279 if (m_fptr != NULL) {
280
281 // Continue only if buffer is valid and nbyte is positive
282 if (buffer != NULL && nbyte > 0) {
283 nread = std::fread(buffer, 1, nbyte, m_fptr);
284 }
285
286 } // endif: File was opened
287
288 // Return number of Bytes read
289 return nread;
290}
291
292
293/***********************************************************************//**
294 * @brief Write block of data buffer into file
295 *
296 * @param[in] buffer Data buffer.
297 * @param[in] nbyte Number of Bytes to be written.
298 * @return Number of Bytes that were effectively written.
299 *
300 * Writes @p nbyte Bytes from a @p buffer into the file. The position
301 * indicator of the file is advanced by the total amount of bytes written.
302 *
303 * The total number of Bytes successfully written is returned. If this number
304 * differs from the @p nbyte parameter, a writing error prevented the
305 * function from completing.
306 *
307 * If either @p buffer is NULL or @p nbyte is zero, the method returns zero
308 * and both the file state and the content pointed by @p buffer remain
309 * unchanged.
310 *
311 * If no file has been opened, the method returns zero and both the file
312 * state and the content pointed by @p buffer remain unchanged.
313 ***************************************************************************/
314int GUrlFile::write(const void* buffer, const int& nbyte)
315{
316 // Initialise number of Bytes written
317 int nwritten = 0;
318
319 // Continue only if file is opened
320 if (m_fptr != NULL) {
321
322 // Continue only if buffer is valid and nbyte is positive
323 if (buffer != NULL && nbyte > 0) {
324 nwritten = std::fwrite(buffer, 1, nbyte, m_fptr);
325 }
326
327 } // endif: File was opened
328
329 // Return number of Bytes written
330 return nwritten;
331}
332
333
334/***********************************************************************//**
335 * @brief Return next character from file
336 *
337 * @return Next character in file.
338 *
339 * Returns the character currently pointed by the internal file position
340 * indicator of the file. The internal file position indicator is then
341 * advanced to the next character.
342 *
343 * If the stream is at the end-of-file when called, the function returns EOF
344 * and sets the end-of-file indicator for the file.
345 *
346 * If a read error occurs, the method returns EOF.
347 *
348 * If no file has been opened, the method returns EOF.
349 ***************************************************************************/
350int GUrlFile::get_char(void) const
351{
352 // Initialise character to EOF
353 int character = EOF;
354
355 // Continue only if file is opened
356 if (m_fptr != NULL) {
357
358 // Get next character
359 character = std::fgetc(m_fptr);
360
361 } // endif: File was opened
362
363 // Return character
364 return character;
365}
366
367
368/***********************************************************************//**
369 * @brief Write character into file
370 *
371 * @param[in] character Character.
372 *
373 * Writes a character to the file and advances the position indicator.
374 *
375 * If no file has been opened, the method does nothing.
376 ***************************************************************************/
377void GUrlFile::put_char(const int& character)
378{
379 // Continue only if file is opened
380 if (m_fptr != NULL) {
381
382 // Write character
383 std::fputc(character, m_fptr);
384
385 } // endif: File was opened
386
387 // Return
388 return;
389}
390
391
392/***********************************************************************//**
393 * @brief Read formatted data from file
394 *
395 * @param[in] format Format.
396 * @param[in] ... Optional parameters.
397 *
398 * Reads data from a file and stores them according to the parameter format
399 * into the locations pointed by the additional arguments. The additional
400 * arguments should point to already allocated objects of the type specified
401 * by their corresponding format specifier within the format string.
402 *
403 * If no file has been opened, the method does nothing.
404 ***************************************************************************/
405void GUrlFile::scanf(const char* format, ...)
406{
407 // Continue only if file is opened
408 if (m_fptr != NULL) {
409
410 // Declare argument pointer
411 std::va_list arg_ptr;
412
413 // Set start argument
414 va_start(arg_ptr, format);
415
416 // Read data from file
417 vfscanf(m_fptr, format, arg_ptr);
418
419 // Stop argument reading
420 va_end(arg_ptr);
421
422 } // endif: File was opened
423
424 // Return
425 return;
426}
427
428
429/***********************************************************************//**
430 * @brief Write formatted data into file
431 *
432 * @param[in] format Format.
433 * @param[in] ... Optional parameters.
434 *
435 * Writes the C string pointed by format to the file. If format includes
436 * format specifiers (subsequences beginning with %), the additional
437 * arguments following format are formatted and inserted in the resulting
438 * string replacing their respective specifiers.
439 *
440 * After the format parameter, the function expects at least as many
441 * additional arguments as specified by format.
442 *
443 * If no file has been opened, the method does nothing.
444 ***************************************************************************/
445void GUrlFile::printf(const char* format, ...)
446{
447 // Continue only if file is opened
448 if (m_fptr != NULL) {
449
450 // Declare argument pointer
451 std::va_list arg_ptr;
452
453 // Set start argument
454 va_start(arg_ptr, format);
455
456 // Write data into file
457 std::vfprintf(m_fptr, format, arg_ptr);
458
459 // Stop argument reading
460 va_end(arg_ptr);
461
462 } // endif: File was opened
463
464 // Return
465 return;
466}
467
468
469/***********************************************************************//**
470 * @brief Print URL information
471 *
472 * @param[in] chatter Chattiness (defaults to NORMAL).
473 * @return String containing URL information.
474 ***************************************************************************/
475std::string GUrlFile::print(const GChatter& chatter) const
476{
477 // Initialise result string
478 std::string result;
479
480 // Continue only if chatter is not silent
481 if (chatter != SILENT) {
482
483 // Append header
484 result.append("=== GUrlFile ===");
485
486 // Append information
487 if (m_fptr != NULL) {
488
489 // Get information
490 int pos = std::ftell(m_fptr);
491 int err = std::ferror(m_fptr);
492
493 // Append it
494 result.append("\n"+gammalib::parformat("File URL")+m_url);
495 result.append("\n"+gammalib::parformat("File mode")+m_mode);
496 result.append("\n"+gammalib::parformat("File position indicator"));
497 result.append(gammalib::str(pos));
498 result.append("\n"+gammalib::parformat("File error"));
499 if (err == 0) {
500 result.append("none");
501 }
502 else {
503 result.append(gammalib::str(err));
504 }
505 }
506 else {
507 result.append("\n"+gammalib::parformat("URL")+"none");
508 }
509
510 } // endif: chatter was not silent
511
512 // Return result
513 return result;
514}
515
516
517
518
519/*==========================================================================
520 = =
521 = Private methods =
522 = =
523 ==========================================================================*/
524
525/***********************************************************************//**
526 * @brief Initialise class members
527 ***************************************************************************/
529{
530 // Initialise members
531 m_url.clear();
532 m_mode.clear();
533 m_fptr = NULL;
534
535 // Return
536 return;
537}
538
539
540/***********************************************************************//**
541 * @brief Copy class members
542 *
543 * @param[in] url URL.
544 *
545 * @todo The simple copying of the file pointer is not clean as we have no
546 * control anymore over the object. The file pointer should be cloned
547 * somehow.
548 ***************************************************************************/
550{
551 // Copy members
552 m_url = url.m_url;
553 m_mode = url.m_mode;
554 m_fptr = url.m_fptr;
555
556 // Return
557 return;
558}
559
560
561/***********************************************************************//**
562 * @brief Delete class members
563 ***************************************************************************/
565{
566 // Close file
567 close();
568
569 // Return
570 return;
571}
Exception handler interface definition.
#define G_OPEN
Definition GFits.cpp:63
Gammalib tools definition.
GChatter
Definition GTypemaps.hpp:33
@ SILENT
Definition GTypemaps.hpp:34
File URL class interface definition.
File URL class.
Definition GUrlFile.hpp:41
virtual int get_char(void) const
Return next character from file.
Definition GUrlFile.cpp:350
virtual GUrlFile * clone(void) const
Clone instance.
Definition GUrlFile.cpp:185
virtual int write(const void *buffer, const int &nbyte)
Write block of data buffer into file.
Definition GUrlFile.cpp:314
std::string m_url
File URL.
Definition GUrlFile.hpp:74
GUrlFile(void)
Void constructor.
Definition GUrlFile.cpp:56
virtual int read(void *buffer, const int &nbyte)
Read block of data from file in buffer.
Definition GUrlFile.cpp:273
virtual void clear(void)
Clear instance.
Definition GUrlFile.cpp:165
virtual void scanf(const char *format,...)
Read formatted data from file.
Definition GUrlFile.cpp:405
virtual std::string print(const GChatter &chatter=NORMAL) const
Print URL information.
Definition GUrlFile.cpp:475
void copy_members(const GUrlFile &url)
Copy class members.
Definition GUrlFile.cpp:549
virtual void close(void)
Close file.
Definition GUrlFile.cpp:234
void init_members(void)
Initialise class members.
Definition GUrlFile.cpp:528
std::string m_mode
File mode.
Definition GUrlFile.hpp:75
void free_members(void)
Delete class members.
Definition GUrlFile.cpp:564
virtual ~GUrlFile(void)
Destructor.
Definition GUrlFile.cpp:110
virtual void put_char(const int &character)
Write character into file.
Definition GUrlFile.cpp:377
virtual void open(const std::string &url, const std::string &mode)
Open file.
Definition GUrlFile.cpp:206
FILE * m_fptr
File pointer.
Definition GUrlFile.hpp:76
virtual void printf(const char *format,...)
Write formatted data into file.
Definition GUrlFile.cpp:445
GUrlFile & operator=(const GUrlFile &url)
Assignment operator.
Definition GUrlFile.cpp:132
Abstract URL base class.
Definition GUrl.hpp:44
GUrl & operator=(const GUrl &url)
Assignment operator.
Definition GUrl.cpp:104
void init_members(void)
Initialise class members.
Definition GUrl.cpp:141
void free_members(void)
Delete class members.
Definition GUrl.cpp:163
std::string parformat(const std::string &s, const int &indent=0)
Convert string in parameter format.
Definition GTools.cpp:1143
std::string str(const unsigned short int &value)
Convert unsigned short integer value into string.
Definition GTools.cpp:489
std::string expand_env(const std::string &arg)
Expand environment variables in string.
Definition GTools.cpp:214