GammaLib  1.7.0.dev
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
GUrlFile.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  * GUrlFile.cpp - File URL class *
3  * ----------------------------------------------------------------------- *
4  * copyright (C) 2013-2015 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
59  init_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  ***************************************************************************/
76 GUrlFile::GUrlFile(const std::string& url, const std::string& mode) : GUrl()
77 {
78  // Initialise members
79  init_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  ***************************************************************************/
94 GUrlFile::GUrlFile(const GUrlFile& url) : GUrl(url)
95 {
96  // Initialise members
97  init_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  ***************************************************************************/
165 void GUrlFile::clear(void)
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_open_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  ***************************************************************************/
206 void 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  throw GException::file_open_error(G_OPEN, filename);
218  }
219 
220  // Store URL and mode
221  m_url = url;
222  m_mode = mode;
223 
224  // Return
225  return;
226 }
227 
228 
229 /***********************************************************************//**
230  * @brief Close file
231  ***************************************************************************/
232 void GUrlFile::close(void)
233 {
234  // Close file
235  if (m_fptr != NULL) {
236  std::fclose(m_fptr);
237  }
238 
239  // Reset members
240  m_url.clear();
241  m_mode.clear();
242  m_fptr = NULL;
243 
244  // Return
245  return;
246 }
247 
248 
249 /***********************************************************************//**
250  * @brief Read block of data from file in buffer
251  *
252  * @param[in] buffer Data buffer.
253  * @param[in] nbyte Number of Bytes to be read.
254  * @return Number of Bytes that were effectively read.
255  *
256  * Reads @p nbyte Bytes from the file into a @p buffer. The position
257  * indicator of the file is advanced by the total amount of bytes read.
258  *
259  * The total number of Bytes successfully read is returned. If this number
260  * differs from the @p nbyte parameter, either a reading error occurred or
261  * the end-of-file was reached while reading. In both cases, the proper
262  * indicator is set.
263  *
264  * If either @p buffer is NULL or @p nbyte is zero, the method returns zero
265  * and both the file state and the content pointed by @p buffer remain
266  * unchanged.
267  *
268  * If no file has been opened, the method returns zero and both the file
269  * state and the content pointed by @p buffer remain unchanged.
270  ***************************************************************************/
271 int GUrlFile::read(void* buffer, const int& nbyte)
272 {
273  // Initialise number of Bytes read
274  int nread = 0;
275 
276  // Continue only if file is opened
277  if (m_fptr != NULL) {
278 
279  // Continue only if buffer is valid and nbyte is positive
280  if (buffer != NULL && nbyte > 0) {
281  nread = std::fread(buffer, 1, nbyte, m_fptr);
282  }
283 
284  } // endif: File was opened
285 
286  // Return number of Bytes read
287  return nread;
288 }
289 
290 
291 /***********************************************************************//**
292  * @brief Write block of data buffer into file
293  *
294  * @param[in] buffer Data buffer.
295  * @param[in] nbyte Number of Bytes to be written.
296  * @return Number of Bytes that were effectively written.
297  *
298  * Writes @p nbyte Bytes from a @p buffer into the file. The position
299  * indicator of the file is advanced by the total amount of bytes written.
300  *
301  * The total number of Bytes successfully written is returned. If this number
302  * differs from the @p nbyte parameter, a writing error prevented the
303  * function from completing.
304  *
305  * If either @p buffer is NULL or @p nbyte is zero, the method returns zero
306  * and both the file state and the content pointed by @p buffer remain
307  * unchanged.
308  *
309  * If no file has been opened, the method returns zero and both the file
310  * state and the content pointed by @p buffer remain unchanged.
311  ***************************************************************************/
312 int GUrlFile::write(const void* buffer, const int& nbyte)
313 {
314  // Initialise number of Bytes written
315  int nwritten = 0;
316 
317  // Continue only if file is opened
318  if (m_fptr != NULL) {
319 
320  // Continue only if buffer is valid and nbyte is positive
321  if (buffer != NULL && nbyte > 0) {
322  nwritten = std::fwrite(buffer, 1, nbyte, m_fptr);
323  }
324 
325  } // endif: File was opened
326 
327  // Return number of Bytes written
328  return nwritten;
329 }
330 
331 
332 /***********************************************************************//**
333  * @brief Return next character from file
334  *
335  * @return Next character in file.
336  *
337  * Returns the character currently pointed by the internal file position
338  * indicator of the file. The internal file position indicator is then
339  * advanced to the next character.
340  *
341  * If the stream is at the end-of-file when called, the function returns EOF
342  * and sets the end-of-file indicator for the file.
343  *
344  * If a read error occurs, the method returns EOF.
345  *
346  * If no file has been opened, the method returns EOF.
347  ***************************************************************************/
348 int GUrlFile::get_char(void) const
349 {
350  // Initialise character to EOF
351  int character = EOF;
352 
353  // Continue only if file is opened
354  if (m_fptr != NULL) {
355 
356  // Get next character
357  character = std::fgetc(m_fptr);
358 
359  } // endif: File was opened
360 
361  // Return character
362  return character;
363 }
364 
365 
366 /***********************************************************************//**
367  * @brief Write character into file
368  *
369  * @param[in] character Character.
370  *
371  * Writes a character to the file and advances the position indicator.
372  *
373  * If no file has been opened, the method does nothing.
374  ***************************************************************************/
375 void GUrlFile::put_char(const int& character)
376 {
377  // Continue only if file is opened
378  if (m_fptr != NULL) {
379 
380  // Write character
381  std::fputc(character, m_fptr);
382 
383  } // endif: File was opened
384 
385  // Return
386  return;
387 }
388 
389 
390 /***********************************************************************//**
391  * @brief Read formatted data from file
392  *
393  * @param[in] format Format.
394  * @param[in] ... Optional parameters.
395  *
396  * Reads data from a file and stores them according to the parameter format
397  * into the locations pointed by the additional arguments. The additional
398  * arguments should point to already allocated objects of the type specified
399  * by their corresponding format specifier within the format string.
400  *
401  * If no file has been opened, the method does nothing.
402  ***************************************************************************/
403 void GUrlFile::scanf(const char* format, ...)
404 {
405  // Continue only if file is opened
406  if (m_fptr != NULL) {
407 
408  // Declare argument pointer
409  std::va_list arg_ptr;
410 
411  // Set start argument
412  va_start(arg_ptr, format);
413 
414  // Read data from file
415  vfscanf(m_fptr, format, arg_ptr);
416 
417  // Stop argument reading
418  va_end(arg_ptr);
419 
420  } // endif: File was opened
421 
422  // Return
423  return;
424 }
425 
426 
427 /***********************************************************************//**
428  * @brief Write formatted data into file
429  *
430  * @param[in] format Format.
431  * @param[in] ... Optional parameters.
432  *
433  * Writes the C string pointed by format to the file. If format includes
434  * format specifiers (subsequences beginning with %), the additional
435  * arguments following format are formatted and inserted in the resulting
436  * string replacing their respective specifiers.
437  *
438  * After the format parameter, the function expects at least as many
439  * additional arguments as specified by format.
440  *
441  * If no file has been opened, the method does nothing.
442  ***************************************************************************/
443 void GUrlFile::printf(const char* format, ...)
444 {
445  // Continue only if file is opened
446  if (m_fptr != NULL) {
447 
448  // Declare argument pointer
449  std::va_list arg_ptr;
450 
451  // Set start argument
452  va_start(arg_ptr, format);
453 
454  // Write data into file
455  std::vfprintf(m_fptr, format, arg_ptr);
456 
457  // Stop argument reading
458  va_end(arg_ptr);
459 
460  } // endif: File was opened
461 
462  // Return
463  return;
464 }
465 
466 
467 /***********************************************************************//**
468  * @brief Print URL information
469  *
470  * @param[in] chatter Chattiness (defaults to NORMAL).
471  * @return String containing URL information.
472  ***************************************************************************/
473 std::string GUrlFile::print(const GChatter& chatter) const
474 {
475  // Initialise result string
476  std::string result;
477 
478  // Continue only if chatter is not silent
479  if (chatter != SILENT) {
480 
481  // Append header
482  result.append("=== GUrlFile ===");
483 
484  // Append information
485  if (m_fptr != NULL) {
486 
487  // Get information
488  int pos = std::ftell(m_fptr);
489  int err = std::ferror(m_fptr);
490 
491  // Append it
492  result.append("\n"+gammalib::parformat("File URL")+m_url);
493  result.append("\n"+gammalib::parformat("File mode")+m_mode);
494  result.append("\n"+gammalib::parformat("File position indicator"));
495  result.append(gammalib::str(pos));
496  result.append("\n"+gammalib::parformat("File error"));
497  if (err == 0) {
498  result.append("none");
499  }
500  else {
501  result.append(gammalib::str(err));
502  }
503  }
504  else {
505  result.append("\n"+gammalib::parformat("URL")+"none");
506  }
507 
508  } // endif: chatter was not silent
509 
510  // Return result
511  return result;
512 }
513 
514 
515 
516 
517 /*==========================================================================
518  = =
519  = Private methods =
520  = =
521  ==========================================================================*/
522 
523 /***********************************************************************//**
524  * @brief Initialise class members
525  ***************************************************************************/
527 {
528  // Initialise members
529  m_url.clear();
530  m_mode.clear();
531  m_fptr = NULL;
532 
533  // Return
534  return;
535 }
536 
537 
538 /***********************************************************************//**
539  * @brief Copy class members
540  *
541  * @param[in] url URL.
542  *
543  * @todo The simple copying of the file pointer is not clean as we have no
544  * control anymore over the object. The file pointer should be cloned
545  * somehow.
546  ***************************************************************************/
548 {
549  // Copy members
550  m_url = url.m_url;
551  m_mode = url.m_mode;
552  m_fptr = url.m_fptr;
553 
554  // Return
555  return;
556 }
557 
558 
559 /***********************************************************************//**
560  * @brief Delete class members
561  ***************************************************************************/
563 {
564  // Close file
565  close();
566 
567  // Return
568  return;
569 }
std::string m_mode
File mode.
Definition: GUrlFile.hpp:75
virtual void clear(void)
Clear instance.
Definition: GUrlFile.cpp:165
GUrlFile(void)
Void constructor.
Definition: GUrlFile.cpp:56
void free_members(void)
Delete class members.
Definition: GUrlFile.cpp:562
GUrlFile & operator=(const GUrlFile &url)
Assignment operator.
Definition: GUrlFile.cpp:132
GUrl & operator=(const GUrl &url)
Assignment operator.
Definition: GUrl.cpp:104
virtual int write(const void *buffer, const int &nbyte)
Write block of data buffer into file.
Definition: GUrlFile.cpp:312
Gammalib tools definition.
virtual std::string print(const GChatter &chatter=NORMAL) const
Print URL information.
Definition: GUrlFile.cpp:473
File URL class interface definition.
virtual ~GUrlFile(void)
Destructor.
Definition: GUrlFile.cpp:110
Abstract URL base class.
Definition: GUrl.hpp:44
File URL class.
Definition: GUrlFile.hpp:41
std::string m_url
File URL.
Definition: GUrlFile.hpp:74
virtual void close(void)
Close file.
Definition: GUrlFile.cpp:232
virtual void open(const std::string &url, const std::string &mode)
Open file.
Definition: GUrlFile.cpp:206
GChatter
Definition: GTypemaps.hpp:33
void free_members(void)
Delete class members.
Definition: GUrl.cpp:163
virtual void printf(const char *format,...)
Write formatted data into file.
Definition: GUrlFile.cpp:443
void copy_members(const GUrlFile &url)
Copy class members.
Definition: GUrlFile.cpp:547
#define G_OPEN
Definition: GUrlFile.cpp:38
virtual void scanf(const char *format,...)
Read formatted data from file.
Definition: GUrlFile.cpp:403
virtual int get_char(void) const
Return next character from file.
Definition: GUrlFile.cpp:348
virtual GUrlFile * clone(void) const
Clone instance.
Definition: GUrlFile.cpp:185
virtual int read(void *buffer, const int &nbyte)
Read block of data from file in buffer.
Definition: GUrlFile.cpp:271
virtual void put_char(const int &character)
Write character into file.
Definition: GUrlFile.cpp:375
Exception handler interface definition.
std::string expand_env(const std::string &arg)
Expand environment variables in string.
Definition: GTools.cpp:207
std::string parformat(const std::string &s, const int &indent=0)
Convert string in parameter format.
Definition: GTools.cpp:1022
void init_members(void)
Initialise class members.
Definition: GUrlFile.cpp:526
void init_members(void)
Initialise class members.
Definition: GUrl.cpp:141
FILE * m_fptr
File pointer.
Definition: GUrlFile.hpp:76
std::string str(const unsigned short int &value)
Convert unsigned short integer value into string.
Definition: GTools.cpp:413