Commit 2abdd039c524b9d5be5431e5d45d6d6dfb3efc0c

Authored by Jürgen Knödlseder
1 parent e972352e

Added GFilename class.

The GFilename class handles the decomposition of the filename into the true filename and a FITS extension name.
include/GFilename.hpp 0 → 100644
  1 +/***************************************************************************
  2 + * GFilename.hpp - Filename class *
  3 + * ----------------------------------------------------------------------- *
  4 + * copyright (C) 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 GFilename.hpp
  23 + * @brief Filename class interface definition
  24 + * @author Juergen Knoedlseder
  25 + */
  26 +
  27 +#ifndef GFILENAME_HPP
  28 +#define GFILENAME_HPP
  29 +
  30 +/* __ Includes ___________________________________________________________ */
  31 +#include <string>
  32 +#include "GBase.hpp"
  33 +
  34 +
  35 +/***********************************************************************//**
  36 + * @class GFilename
  37 + *
  38 + * @brief Filename class
  39 + *
  40 + * This class handles filenames.
  41 + ***************************************************************************/
  42 +class GFilename : public GBase {
  43 +
  44 +public:
  45 + // Constructors and destructors
  46 + GFilename(void);
  47 + GFilename(const std::string& filename);
  48 + GFilename(const char* filename);
  49 + GFilename(const GFilename& filename);
  50 + virtual ~GFilename(void);
  51 +
  52 + // Operators
  53 + GFilename& operator=(const GFilename& filename);
  54 +
  55 + // Methods
  56 + void clear(void);
  57 + GFilename* clone(void) const;
  58 + std::string classname(void) const;
  59 + bool empty(void) const;
  60 + int size(void) const;
  61 + int length(void) const;
  62 + const std::string& filename(void) const;
  63 + const std::string& extname(void) const;
  64 + const int& extno(void) const;
  65 + const int& extver(void) const;
  66 + bool has_extname(void) const;
  67 + bool has_extno(void) const;
  68 + bool has_extver(void) const;
  69 + void default_extname(const std::string& extname);
  70 + std::string print(const GChatter& chatter = NORMAL) const;
  71 +
  72 +protected:
  73 + // Protected methods
  74 + void init_members(void);
  75 + void copy_members(const GFilename& filename);
  76 + void free_members(void);
  77 + void set_filename(const std::string& filename);
  78 +
  79 + // Protected members
  80 + std::string m_filename; //!< Filename (with stripped extension info)
  81 + std::string m_extname; //!< Extension name
  82 + int m_extno; //!< Extension number (-1: not set)
  83 + int m_extver; //!< Extension version (0: not set)
  84 +};
  85 +
  86 +
  87 +/***********************************************************************//**
  88 + * @brief Return class name
  89 + *
  90 + * @return String containing the class name ("GFilename").
  91 + ***************************************************************************/
  92 +inline
  93 +std::string GFilename::classname(void) const
  94 +{
  95 + return ("GFilename");
  96 +}
  97 +
  98 +
  99 +/***********************************************************************//**
  100 + * @brief Signal if filename is empty
  101 + *
  102 + * @return True if filename is empty, false otherwise.
  103 + ***************************************************************************/
  104 +inline
  105 +bool GFilename::empty(void) const
  106 +{
  107 + return (m_filename.empty());
  108 +}
  109 +
  110 +
  111 +/***********************************************************************//**
  112 + * @brief Return size of filename
  113 + *
  114 + * @return Size of filename.
  115 + *
  116 + * The size of the file name is equal to its length.
  117 + ***************************************************************************/
  118 +inline
  119 +int GFilename::size(void) const
  120 +{
  121 + return (m_filename.size());
  122 +}
  123 +
  124 +
  125 +/***********************************************************************//**
  126 + * @brief Return length of filename
  127 + *
  128 + * @return Length of filename.
  129 + ***************************************************************************/
  130 +inline
  131 +int GFilename::length(void) const
  132 +{
  133 + return (m_filename.length());
  134 +}
  135 +
  136 +
  137 +/***********************************************************************//**
  138 + * @brief Return file name
  139 + *
  140 + * @return String containing file name.
  141 + ***************************************************************************/
  142 +inline
  143 +const std::string& GFilename::filename(void) const
  144 +{
  145 + return (m_filename);
  146 +}
  147 +
  148 +
  149 +/***********************************************************************//**
  150 + * @brief Return extension name
  151 + *
  152 + * @return String containing extension name.
  153 + ***************************************************************************/
  154 +inline
  155 +const std::string& GFilename::extname(void) const
  156 +{
  157 + return (m_extname);
  158 +}
  159 +
  160 +
  161 +/***********************************************************************//**
  162 + * @brief Return extension number
  163 + *
  164 + * @return Extension number (-1 if not set).
  165 + ***************************************************************************/
  166 +inline
  167 +const int& GFilename::extno(void) const
  168 +{
  169 + return (m_extno);
  170 +}
  171 +
  172 +
  173 +/***********************************************************************//**
  174 + * @brief Return extension version
  175 + *
  176 + * @return Extension version (0 if not set).
  177 + ***************************************************************************/
  178 +inline
  179 +const int& GFilename::extver(void) const
  180 +{
  181 + return (m_extver);
  182 +}
  183 +
  184 +
  185 +/***********************************************************************//**
  186 + * @brief Signal if filename has an extension name
  187 + *
  188 + * @return True if filename has an extension name, false otherwise.
  189 + ***************************************************************************/
  190 +inline
  191 +bool GFilename::has_extname(void) const
  192 +{
  193 + return (!m_extname.empty());
  194 +}
  195 +
  196 +
  197 +/***********************************************************************//**
  198 + * @brief Signal if filename has an extension number
  199 + *
  200 + * @return True if filename has an extension number, false otherwise.
  201 + ***************************************************************************/
  202 +inline
  203 +bool GFilename::has_extno(void) const
  204 +{
  205 + return (m_extno >= 0);
  206 +}
  207 +
  208 +
  209 +/***********************************************************************//**
  210 + * @brief Signal if filename has an extension version
  211 + *
  212 + * @return True if filename has an extension version, false otherwise.
  213 + ***************************************************************************/
  214 +inline
  215 +bool GFilename::has_extver(void) const
  216 +{
  217 + return (m_extver > 0);
  218 +}
  219 +
  220 +#endif /* GFILENAME_HPP */
... ...
include/GammaLib.hpp
... ... @@ -49,6 +49,7 @@
49 49 #include "GUrl.hpp"
50 50 #include "GUrlFile.hpp"
51 51 #include "GUrlString.hpp"
  52 +#include "GFilename.hpp"
52 53  
53 54 /* __ Linear algebra module ______________________________________________ */
54 55 #include "GVector.hpp"
... ...
include/Makefile.am
... ... @@ -13,6 +13,7 @@ pkginclude_HEADERS = GammaLib.hpp \
13 13 GUrl.hpp \
14 14 GUrlFile.hpp \
15 15 GUrlString.hpp \
  16 + GFilename.hpp \
16 17 GVector.hpp \
17 18 GMatrixBase.hpp \
18 19 GMatrix.hpp \
... ...
pyext/GFilename.i 0 → 100644
  1 +/***************************************************************************
  2 + * GFilename.i - Filename class *
  3 + * ----------------------------------------------------------------------- *
  4 + * copyright (C) 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 GFilename.i
  23 + * @brief Filename class interface definition
  24 + * @author Juergen Knoedlseder
  25 + */
  26 +%{
  27 +/* Put headers and other declarations here that are needed for compilation */
  28 +#include "GFilename.hpp"
  29 +%}
  30 +
  31 +
  32 +/***********************************************************************//**
  33 + * @class GFilename
  34 + *
  35 + * @brief Filename class
  36 + ***************************************************************************/
  37 +class GFilename : public GBase {
  38 +
  39 +public:
  40 + // Constructors and destructors
  41 + GFilename(void);
  42 + GFilename(const std::string& filename);
  43 + GFilename(const GFilename& filename);
  44 + GFilename(const char* filename);
  45 + virtual ~GFilename(void);
  46 +
  47 + // Methods
  48 + void clear(void);
  49 + GFilename* clone(void) const;
  50 + std::string classname(void) const;
  51 + bool empty(void) const;
  52 + int size(void) const;
  53 + int length(void) const;
  54 + const std::string& filename(void) const;
  55 + const std::string& extname(void) const;
  56 + const int& extno(void) const;
  57 + const int& extver(void) const;
  58 + bool has_extname(void) const;
  59 + bool has_extno(void) const;
  60 + bool has_extver(void) const;
  61 + void default_extname(const std::string& extname);
  62 +};
  63 +
  64 +
  65 +/***********************************************************************//**
  66 + * @brief GFilename class extension
  67 + ***************************************************************************/
  68 +%extend GFilename {
  69 + GFilename copy() {
  70 + return (*self);
  71 + }
  72 +};
... ...
pyext/gammalib/support.i
... ... @@ -71,3 +71,4 @@
71 71 %include "GUrl.i"
72 72 %include "GUrlFile.i"
73 73 %include "GUrlString.i"
  74 +%include "GFilename.i"
... ...
src/support/GFilename.cpp 0 → 100644
  1 +/***************************************************************************
  2 + * GFilename.cpp - Filename class *
  3 + * ----------------------------------------------------------------------- *
  4 + * copyright (C) 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 GFilename.cpp
  23 + * @brief Filename class interface implementation
  24 + * @author Juergen Knoedlseder
  25 + */
  26 +
  27 +/* __ Includes ___________________________________________________________ */
  28 +#ifdef HAVE_CONFIG_H
  29 +#include <config.h>
  30 +#endif
  31 +#include "GFilename.hpp"
  32 +#include "GTools.hpp"
  33 +#include "GException.hpp"
  34 +
  35 +/* __ Method name definitions ____________________________________________ */
  36 +#define G_SET_FILENAME "GFilename::set_filename(std::string&)"
  37 +
  38 +/* __ Macros _____________________________________________________________ */
  39 +
  40 +/* __ Coding definitions _________________________________________________ */
  41 +
  42 +/* __ Debug definitions __________________________________________________ */
  43 +
  44 +
  45 +/*==========================================================================
  46 + = =
  47 + = Constructors/destructors =
  48 + = =
  49 + ==========================================================================*/
  50 +
  51 +/***********************************************************************//**
  52 + * @brief Void constructor
  53 + ***************************************************************************/
  54 +GFilename::GFilename(void)
  55 +{
  56 + // Initialise members
  57 + init_members();
  58 +
  59 + // Return
  60 + return;
  61 +}
  62 +
  63 +
  64 +/***********************************************************************//**
  65 + * @brief Filename constructor
  66 + *
  67 + * @param[in] filename File name.
  68 + *
  69 + * Constructs GFilename object by assigning a @p filename.
  70 + ***************************************************************************/
  71 +GFilename::GFilename(const std::string& filename)
  72 +{
  73 + // Initialise members
  74 + init_members();
  75 +
  76 + // Set filename
  77 + set_filename(filename);
  78 +
  79 + // Return
  80 + return;
  81 +}
  82 +
  83 +
  84 +/***********************************************************************//**
  85 + * @brief Filename constructor
  86 + *
  87 + * @param[in] filename File name.
  88 + *
  89 + * Constructs GFilename object by assigning a @p filename.
  90 + ***************************************************************************/
  91 +GFilename::GFilename(const char* filename)
  92 +{
  93 + // Initialise members
  94 + init_members();
  95 +
  96 + // Set filename
  97 + set_filename(std::string(filename));
  98 +
  99 + // Return
  100 + return;
  101 +}
  102 +
  103 +
  104 +/***********************************************************************//**
  105 + * @brief Copy constructor
  106 + *
  107 + * @param[in] filename File name.
  108 + ***************************************************************************/
  109 +GFilename::GFilename(const GFilename& filename)
  110 +{
  111 + // Initialise members
  112 + init_members();
  113 +
  114 + // Copy members
  115 + copy_members(filename);
  116 +
  117 + // Return
  118 + return;
  119 +}
  120 +
  121 +
  122 +/***********************************************************************//**
  123 + * @brief Destructor
  124 + ***************************************************************************/
  125 +GFilename::~GFilename(void)
  126 +{
  127 + // Free members
  128 + free_members();
  129 +
  130 + // Return
  131 + return;
  132 +}
  133 +
  134 +
  135 +/*==========================================================================
  136 + = =
  137 + = Operators =
  138 + = =
  139 + ==========================================================================*/
  140 +
  141 +/***********************************************************************//**
  142 + * @brief Assignment operator
  143 + *
  144 + * @param[in] filename File name.
  145 + * @return File name.
  146 + ***************************************************************************/
  147 +GFilename& GFilename::operator=(const GFilename& filename)
  148 +{
  149 + // Execute only if object is not identical
  150 + if (this != &filename) {
  151 +
  152 + // Free members
  153 + free_members();
  154 +
  155 + // Initialise members
  156 + init_members();
  157 +
  158 + // Copy members
  159 + copy_members(filename);
  160 +
  161 + } // endif: object was not identical
  162 +
  163 + // Return
  164 + return *this;
  165 +}
  166 +
  167 +
  168 +/*==========================================================================
  169 + = =
  170 + = Public methods =
  171 + = =
  172 + ==========================================================================*/
  173 +
  174 +/***********************************************************************//**
  175 + * @brief Clear file name
  176 + ***************************************************************************/
  177 +void GFilename::clear(void)
  178 +{
  179 + // Free class members
  180 + free_members();
  181 +
  182 + // Initialise members
  183 + init_members();
  184 +
  185 + // Return
  186 + return;
  187 +}
  188 +
  189 +
  190 +/***********************************************************************//**
  191 + * @brief Clone file name
  192 + *
  193 + * @return Pointer to deep copy of file name.
  194 + ***************************************************************************/
  195 +GFilename* GFilename::clone(void) const
  196 +{
  197 + // Clone object
  198 + return new GFilename(*this);
  199 +}
  200 +
  201 +
  202 +/***********************************************************************//**
  203 + * @brief Set default extension name
  204 + *
  205 + * @param[in] extname Extension name.
  206 + *
  207 + * If the object has no extension name then set the extension name.
  208 + ***************************************************************************/
  209 +void GFilename::default_extname(const std::string& extname)
  210 +{
  211 + // Set extension name if it has not yet been set
  212 + if (!has_extname()) {
  213 + m_extname = extname;
  214 + }
  215 +
  216 + // Return
  217 + return;
  218 +}
  219 +
  220 +
  221 +/***********************************************************************//**
  222 + * @brief Print file name information
  223 + *
  224 + * @param[in] chatter Chattiness (default: NORMAL).
  225 + * @return String containing file name information.
  226 + ***************************************************************************/
  227 +std::string GFilename::print(const GChatter& chatter) const
  228 +{
  229 + // Initialise result string
  230 + std::string result;
  231 +
  232 + // Continue only if chatter is not silent
  233 + if (chatter != SILENT) {
  234 +
  235 + // Append header
  236 + result.append("=== GFilename ===");
  237 +
  238 + // Append file name
  239 + result.append("\n"+gammalib::parformat("File name"));
  240 + result.append(m_filename);
  241 +
  242 + // Append extension name
  243 + result.append("\n"+gammalib::parformat("Extension name"));
  244 + if (has_extname()) {
  245 + result.append(m_extname);
  246 + }
  247 + else {
  248 + result.append("Not provided");
  249 + }
  250 +
  251 + // Append extension number
  252 + result.append("\n"+gammalib::parformat("Extension number"));
  253 + if (has_extno()) {
  254 + result.append(gammalib::str(m_extno));
  255 + }
  256 + else {
  257 + result.append("Not provided");
  258 + }
  259 +
  260 + // Append extension version
  261 + result.append("\n"+gammalib::parformat("Extension version"));
  262 + if (has_extver()) {
  263 + result.append(gammalib::str(m_extver));
  264 + }
  265 + else {
  266 + result.append("Not provided");
  267 + }
  268 +
  269 + } // endif: chatter was not silent
  270 +
  271 + // Return result
  272 + return result;
  273 +}
  274 +
  275 +
  276 +/*==========================================================================
  277 + = =
  278 + = Private methods =
  279 + = =
  280 + ==========================================================================*/
  281 +
  282 +/***********************************************************************//**
  283 + * @brief Initialise class members
  284 + ***************************************************************************/
  285 +void GFilename::init_members(void)
  286 +{
  287 + // Initialise members
  288 + m_filename.clear();
  289 + m_extname.clear();
  290 + m_extno = -1;
  291 + m_extver = 0;
  292 +
  293 + // Return
  294 + return;
  295 +}
  296 +
  297 +
  298 +/***********************************************************************//**
  299 + * @brief Copy class members
  300 + *
  301 + * @param[in] filename File name.
  302 + ***************************************************************************/
  303 +void GFilename::copy_members(const GFilename& filename)
  304 +{
  305 + // Copy members
  306 + m_filename = filename.m_filename;
  307 + m_extname = filename.m_extname;
  308 + m_extno = filename.m_extno;
  309 + m_extver = filename.m_extver;
  310 +
  311 + // Return
  312 + return;
  313 +}
  314 +
  315 +
  316 +/***********************************************************************//**
  317 + * @brief Delete class members
  318 + ***************************************************************************/
  319 +void GFilename::free_members(void)
  320 +{
  321 + // Return
  322 + return;
  323 +}
  324 +
  325 +
  326 +/***********************************************************************//**
  327 + * @brief Set file name
  328 + *
  329 + * @param[in] filename File name.
  330 + *
  331 + * @exception GException::invalid_argument
  332 + * Invalid file name specified.
  333 + *
  334 + * Sets all attributes of the object by parsing the file name. The file name
  335 + * can have one of the following formats:
  336 + *
  337 + * file.fits No extension
  338 + * file.fits[1] Extension number 1 (starting from 0)
  339 + * file.fits[EVENTS] EVENTS extension
  340 + * file.fits[EVENTS,2] Version 2 of the EVENTS extension
  341 + ***************************************************************************/
  342 +void GFilename::set_filename(const std::string& filename)
  343 +{
  344 + // Clear file name
  345 + clear();
  346 +
  347 + // Strip any whitespace
  348 + std::string fname = gammalib::strip_whitespace(filename);
  349 +
  350 + // Continue only if filename is not empty
  351 + if (!fname.empty()) {
  352 +
  353 + // Check for [ symbol in filename
  354 + size_t start = fname.find_first_of("[");
  355 +
  356 + // If we have an extension then separate filename into filename
  357 + // part and extension part and fill the information of th object
  358 + if (start != std::string::npos) {
  359 +
  360 + // Check for ] symbol in filename
  361 + size_t stop = fname.find_first_of("]", start);
  362 +
  363 + // If there is no ] symbol then throw an exception
  364 + if (stop == std::string::npos) {
  365 + std::string msg = "Missing ] symbol in filename \""+
  366 + fname+"\" extension. Please correct the "
  367 + "filename.";
  368 + throw GException::invalid_argument(G_SET_FILENAME, msg);
  369 + }
  370 +
  371 + // If ] is not the last character then throw an exception
  372 + if (stop < fname.length()-1) {
  373 + std::string msg = "Characters beyond ] symbol in filename \""+
  374 + fname+"\". Please correct the filename.";
  375 + throw GException::invalid_argument(G_SET_FILENAME, msg);
  376 + }
  377 +
  378 + // Extract extension name
  379 + std::string extname = gammalib::strip_whitespace(fname.substr(start+1, stop-start-1));
  380 +
  381 + // Check if there is a , symbol that separates extension name
  382 + // and extension version
  383 + size_t sep = extname.find_first_of(",");
  384 +
  385 + // If we have a separator, then extract the extension version
  386 + if (sep != std::string::npos) {
  387 +
  388 + // Get extension version string
  389 + std::string extver = gammalib::strip_whitespace(extname.substr(sep+1, std::string::npos));
  390 +
  391 + // If string is empty then throw an exception
  392 + if (extver.empty()) {
  393 + std::string msg = "No extension version found after , "
  394 + "symbol in filename \""+fname+
  395 + "\". Please correct the filename.";
  396 + throw GException::invalid_argument(G_SET_FILENAME, msg);
  397 + }
  398 +
  399 + // Extract extension version
  400 + m_extver = gammalib::toint(extver);
  401 +
  402 + // Throw an exception if the extension version is not
  403 + // positive
  404 + if (m_extver <= 0) {
  405 + std::string msg = "Non-positive extension version "
  406 + "encountered in filename \""+fname+
  407 + "\". Please correct the filename.";
  408 + throw GException::invalid_argument(G_SET_FILENAME, msg);
  409 + }
  410 +
  411 + // Update the extension name
  412 + extname = gammalib::strip_whitespace(extname.substr(0,sep));
  413 +
  414 + } // endif: extension version provided
  415 +
  416 + // If we have a purely numerical extension then convert the
  417 + // extension name into an extension number
  418 + if (extname.find_first_of("0123456789") != std::string::npos) {
  419 +
  420 + // Extract extension number
  421 + m_extno = gammalib::toint(extname);
  422 +
  423 + // Throw an exception if the extension version is not
  424 + // positive
  425 + if (m_extno < 0) {
  426 + std::string msg = "Negative extension number encountered "
  427 + "in filename \""+fname+"\". Please "
  428 + "correct the filename.";
  429 + throw GException::invalid_argument(G_SET_FILENAME, msg);
  430 + }
  431 +
  432 + } // endif: extension number provided
  433 +
  434 + // ... otherwise store the extension name
  435 + else {
  436 +
  437 + // Store extension name
  438 + m_extname = gammalib::toupper(extname);
  439 +
  440 + // Throw an exception if extension name is empty
  441 + if (m_extname.empty()) {
  442 + std::string msg = "Empty extension name encountered "
  443 + "in filename \""+fname+"\". Please "
  444 + "correct the filename.";
  445 + throw GException::invalid_argument(G_SET_FILENAME, msg);
  446 + }
  447 +
  448 + } // endelse: extension name provided
  449 +
  450 + // Store the file name
  451 + m_filename = gammalib::strip_whitespace(fname.substr(0,start));
  452 +
  453 + } // endif: had extension
  454 +
  455 + // ... otherwise simply set the filename
  456 + else {
  457 + m_filename = fname;
  458 + }
  459 +
  460 + } // endif: filename was not empty
  461 +
  462 + // Return
  463 + return;
  464 +}
... ...
src/support/Makefile.am
... ... @@ -14,7 +14,8 @@ sources = GException.cpp \
14 14 GRan.cpp \
15 15 GUrl.cpp \
16 16 GUrlFile.cpp \
17   - GUrlString.cpp
  17 + GUrlString.cpp \
  18 + GFilename.cpp
18 19  
19 20 # Build libtool library
20 21 noinst_LTLIBRARIES = libsupport.la
... ...
test/test_GSupport.cpp
... ... @@ -55,6 +55,7 @@ void TestGSupport::set(void){
55 55 append(static_cast<pfunction>(&TestGSupport::test_bilinear), "Test GBilinear");
56 56 append(static_cast<pfunction>(&TestGSupport::test_url_file), "Test GUrlFile");
57 57 append(static_cast<pfunction>(&TestGSupport::test_url_string), "Test GUrlString");
  58 + append(static_cast<pfunction>(&TestGSupport::test_filename), "Test GFilename");
58 59  
59 60 // Return
60 61 return;
... ... @@ -516,7 +517,7 @@ void TestGSupport::test_url_file(void)
516 517 std::string result = std::string(buffer, 21);
517 518 test_assert(result.compare("abcdefghijklm419.9xyz") == 0,
518 519 "Expected \"abcdefghijklm419.9xyz\" in file, found \""+
519   - result+"\n");
  520 + result+"\"");
520 521 url.close();
521 522  
522 523 // Test file reading using get_char() method
... ... @@ -532,7 +533,7 @@ void TestGSupport::test_url_file(void)
532 533 } while (character != EOF);
533 534 test_assert(result.compare("abcdefghijklm419.9xyz") == 0,
534 535 "Expected \"abcdefghijklm419.9xyz\" in file, found \""+
535   - result+"\n");
  536 + result+"\"");
536 537 url.close();
537 538  
538 539 // Test file reading using scanf() method
... ... @@ -542,7 +543,7 @@ void TestGSupport::test_url_file(void)
542 543 result = std::string(buffer, 21);
543 544 test_assert(result.compare("abcdefghijklm419.9xyz") == 0,
544 545 "Expected \"abcdefghijklm419.9xyz\" in file, found \""+
545   - result+"\n");
  546 + result+"\"");
546 547 url.close();
547 548  
548 549 // Return
... ... @@ -590,7 +591,7 @@ void TestGSupport::test_url_string(void)
590 591 std::string result = std::string(buffer, 21);
591 592 test_assert(result.compare("abcdefghijklm419.9xyz") == 0,
592 593 "Expected \"abcdefghijklm419.9xyz\" in file, found \""+
593   - result+"\n");
  594 + result+"\"");
594 595  
595 596 // Test string reading using get_char() method
596 597 result.clear();
... ... @@ -605,7 +606,7 @@ void TestGSupport::test_url_string(void)
605 606 } while (character != EOF);
606 607 test_assert(result.compare("abcdefghijklm419.9xyz") == 0,
607 608 "Expected \"abcdefghijklm419.9xyz\" in file, found \""+
608   - result+"\n");
  609 + result+"\"");
609 610  
610 611 // Test string reading using scanf() method
611 612 char buffer2[100];
... ... @@ -615,7 +616,7 @@ void TestGSupport::test_url_string(void)
615 616 result = std::string(buffer2, 21);
616 617 test_assert(result.compare("abcdefghijklm419.9xyz") == 0,
617 618 "Expected \"abcdefghijklm419.9xyz\" in file, found \""+
618   - result+"\n");
  619 + result+"\"");
619 620 url.close();
620 621  
621 622 // Return
... ... @@ -624,6 +625,157 @@ void TestGSupport::test_url_string(void)
624 625  
625 626  
626 627 /***********************************************************************//**
  628 + * @brief Test GFilename class
  629 + *
  630 + * Test the GFilename class.
  631 + ***************************************************************************/
  632 +void TestGSupport::test_filename(void)
  633 +{
  634 + // Test void constructor
  635 + test_try("Void constructor");
  636 + try {
  637 + GFilename filename;
  638 + test_try_success();
  639 + }
  640 + catch (std::exception &e) {
  641 + test_try_failure(e);
  642 + }
  643 +
  644 + // Set filename without extension
  645 + GFilename filename = "myfile.fits";
  646 + test_assert(filename.filename() == "myfile.fits",
  647 + "Expected \"myfile.fits\" filename, "
  648 + "found \""+filename.filename()+"\"");
  649 + test_assert(!filename.has_extname(),
  650 + "Expected that extension name is not set.");
  651 +
  652 + // Set filename with extension name
  653 + filename = "myfile.fits[EVENTS]";
  654 + test_assert(filename.filename() == "myfile.fits",
  655 + "Expected \"myfile.fits\" filename, "
  656 + "found \""+filename.filename()+"\"");
  657 + test_assert(filename.extname() == "EVENTS",
  658 + "Expected \"EVENTS\" extension name, "
  659 + "found \""+filename.extname()+"\"");
  660 + test_assert(filename.has_extname(),
  661 + "Expected that extension name is set.");
  662 +
  663 + // Set filename with extension name and version
  664 + filename = "myfile.fits[EVENTS,2]";
  665 + test_assert(filename.filename() == "myfile.fits",
  666 + "Expected \"myfile.fits\" filename, "
  667 + "found \""+filename.filename()+"\"");
  668 + test_assert(filename.extname() == "EVENTS",
  669 + "Expected \"EVENTS\" extension name, "
  670 + "found \""+filename.extname()+"\"");
  671 + test_assert(filename.has_extname(),
  672 + "Expected that extension name is set.");
  673 + test_value(filename.extver(), 2);
  674 + test_assert(filename.has_extver(),
  675 + "Expected that extension version is set.");
  676 +
  677 + // Set filename with lower case extension name
  678 + filename = "myfile.fits[events]";
  679 + test_assert(filename.extname() == "EVENTS",
  680 + "Expected \"EVENTS\" extension name, "
  681 + "found \""+filename.extname()+"\"");
  682 +
  683 + // Set filename with extension number and version
  684 + filename = "myfile.fits[1,2]";
  685 + test_assert(filename.filename() == "myfile.fits",
  686 + "Expected \"myfile.fits\" filename, "
  687 + "found \""+filename.filename()+"\"");
  688 + test_value(filename.extno(), 1);
  689 + test_assert(filename.has_extno(),
  690 + "Expected that extension number is set.");
  691 + test_value(filename.extver(), 2);
  692 + test_assert(filename.has_extver(),
  693 + "Expected that extension version is set.");
  694 +
  695 + // Test missing closing symbol
  696 + test_try("Missing ] symbol");
  697 + try {
  698 + GFilename filename("myfile.fits[");
  699 + test_try_failure();
  700 + }
  701 + catch (GException::invalid_argument &e) {
  702 + test_try_success();
  703 + }
  704 +
  705 + // Test character after closing symbol
  706 + test_try("Character after ] symbol");
  707 + try {
  708 + GFilename filename("myfile.fits[EVENTS]a");
  709 + test_try_failure();
  710 + }
  711 + catch (GException::invalid_argument &e) {
  712 + test_try_success();
  713 + }
  714 +
  715 + // Test empty extension name
  716 + test_try("Empty extension name");
  717 + try {
  718 + GFilename filename("myfile.fits[]");
  719 + test_try_failure();
  720 + }
  721 + catch (GException::invalid_argument &e) {
  722 + test_try_success();
  723 + }
  724 +
  725 + // Test invalid extension number
  726 + test_try("Invalid extension number");
  727 + try {
  728 + GFilename filename("myfile.fits[-1]");
  729 + test_try_failure();
  730 + }
  731 + catch (GException::invalid_argument &e) {
  732 + test_try_success();
  733 + }
  734 +
  735 + // Test missing extension version
  736 + test_try("Missing extension version");
  737 + try {
  738 + GFilename filename("myfile.fits[EVENTS,]");
  739 + test_try_failure();
  740 + }
  741 + catch (GException::invalid_argument &e) {
  742 + test_try_success();
  743 + }
  744 +
  745 + // Test invalid extension version
  746 + test_try("Invalid extension version");
  747 + try {
  748 + GFilename filename("myfile.fits[EVENTS,-1]");
  749 + test_try_failure();
  750 + }
  751 + catch (GException::invalid_argument &e) {
  752 + test_try_success();
  753 + }
  754 +
  755 + // Test size operators
  756 + filename = "myfile.fits";
  757 + test_assert(!filename.empty(), "Non empty file name expected.");
  758 + test_value(filename.size(), 11);
  759 + test_value(filename.length(), 11);
  760 +
  761 + // Test default extension name
  762 + filename = "myfile.fits";
  763 + filename.default_extname("EVENTS");
  764 + test_assert(filename.extname() == "EVENTS",
  765 + "Expected \"EVENTS\" extension name, "
  766 + "found \""+filename.extname()+"\"");
  767 + filename = "myfile.fits[LUCKY]";
  768 + filename.default_extname("EVENTS");
  769 + test_assert(filename.extname() == "LUCKY",
  770 + "Expected \"LUCKY\" extension name, "
  771 + "found \""+filename.extname()+"\"");
  772 +
  773 + // Return
  774 + return;
  775 +}
  776 +
  777 +
  778 +/***********************************************************************//**
627 779 * @brief Main test entry point
628 780 ***************************************************************************/
629 781 int main(void)
... ...
test/test_GSupport.hpp
... ... @@ -47,12 +47,13 @@ public:
47 47 virtual void set(void);
48 48 virtual TestGSupport* clone(void) const;
49 49 virtual std::string classname(void) const { return "TestGSupport"; }
  50 + void test_tools(void);
50 51 void test_expand_env(void);
51 52 void test_node_array(void);
52 53 void test_bilinear(void);
53 54 void test_url_file(void);
54 55 void test_url_string(void);
55   - void test_tools(void);
  56 + void test_filename(void);
56 57  
57 58 private:
58 59 // Private methods
... ...
test/test_GSupport.py
... ... @@ -51,6 +51,7 @@ class Test(gammalib.GPythonTestSuite):
51 51 self.append(self.test_node_array, "Test GNodeArray")
52 52 self.append(self.test_url_file, "Test GUrlFile")
53 53 self.append(self.test_url_string, "Test GUrlString")
  54 + self.append(self.test_filename, "Test GFilename")
54 55  
55 56 # Return
56 57 return
... ... @@ -106,7 +107,7 @@ class Test(gammalib.GPythonTestSuite):
106 107 buffer = url.read(99)
107 108 self.test_assert(buffer == "abcde",
108 109 "Expected \"abcde\" in file, found \""+
109   - buffer+"\n");
  110 + buffer+"\"")
110 111 url.close()
111 112  
112 113 # Return
... ... @@ -128,9 +129,41 @@ class Test(gammalib.GPythonTestSuite):
128 129 buffer = url.read(99)
129 130 self.test_assert(buffer == "abcde",
130 131 "Expected \"abcde\" in file, found \""+
131   - buffer+"\n");
  132 + buffer+"\"")
132 133 url.close()
133 134  
134 135 # Return
135 136 return
136 137  
  138 + # Test GFilename class
  139 + def test_filename(self):
  140 + """
  141 + Test GFilename class.
  142 + """
  143 + # Test assigning file names
  144 + filename = gammalib.GFilename("myfile.fits")
  145 + self.test_assert(filename.filename() == "myfile.fits",
  146 + "Expected \"myfile.fits\", found \""+
  147 + filename.filename()+"\"")
  148 + filename = gammalib.GFilename("myfile.fits[EVENTS]")
  149 + self.test_assert(filename.filename() == "myfile.fits",
  150 + "Expected \"myfile.fits\", found \""+
  151 + filename.filename()+"\"")
  152 + self.test_assert(filename.extname() == "EVENTS",
  153 + "Expected extension \"EVENTS\", found \""+
  154 + filename.extname()+"\"")
  155 + filename = gammalib.GFilename("myfile.fits[0]")
  156 + self.test_assert(filename.filename() == "myfile.fits",
  157 + "Expected \"myfile.fits\", found \""+
  158 + filename.filename()+"\"")
  159 + self.test_value(filename.extno(), 0)
  160 + filename = gammalib.GFilename("myfile.fits[0,2]")
  161 + self.test_assert(filename.filename() == "myfile.fits",
  162 + "Expected \"myfile.fits\", found \""+
  163 + filename.filename()+"\"")
  164 + self.test_value(filename.extno(), 0)
  165 + self.test_value(filename.extver(), 2)
  166 +
  167 + # Return
  168 + return
  169 +
137 170 \ No newline at end of file
... ...