LCOV - code coverage report
Current view: top level - alma/ASDM - Misc.h (source / functions) Hit Total Coverage
Test: casacpp_coverage.info Lines: 27 31 87.1 %
Date: 2024-12-11 20:54:31 Functions: 10 14 71.4 %

          Line data    Source code
       1             : #ifndef MISC_H
       2             : #define MISC_H
       3             : /*
       4             :  * ALMA - Atacama Large Millimeter Array
       5             :  * (c) European Southern Observatory, 2002
       6             :  * (c) Associated Universities Inc., 2002
       7             :  * Copyright by ESO (in the framework of the ALMA collaboration),
       8             :  * Copyright by AUI (in the framework of the ALMA collaboration),
       9             :  * All rights reserved.
      10             :  * 
      11             :  * This library is free software; you can redistribute it and/or
      12             :  * modify it under the terms of the GNU Lesser General Public
      13             :  * License as published by the Free software Foundation; either
      14             :  * version 2.1 of the License, or (at your option) any later verson.
      15             :  * 
      16             :  * This library is distributed in the hope that it will be useful,
      17             :  * but WITHOUT ANY WARRANTY, without even the implied warranty of
      18             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      19             :  * Lesser General Public License for more details.
      20             :  * 
      21             :  * You should have received a copy of the GNU Lesser General Public
      22             :  * License along with this library; if not, write to the Free Software
      23             :  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
      24             :  * MA 02111-1307  USA
      25             :  *
      26             :  *
      27             :  * File Misc.h
      28             :  */
      29             : 
      30             : #include <iostream>
      31             : #include <fstream>
      32             : #include <string> 
      33             : #include <vector>
      34             : #include <set>
      35             : #include <map>
      36             : 
      37             : #ifndef WITHOUT_BOOST
      38             : #include <boost/filesystem/path.hpp>
      39             : #include <boost/filesystem/convenience.hpp>
      40             : #include <boost/algorithm/string/trim.hpp>
      41             : #include <boost/algorithm/string/predicate.hpp>
      42             : #include <boost/algorithm/string/split.hpp>
      43             : #else
      44             : #include <sys/stat.h>
      45             : #include <sstream>
      46             : #endif
      47             : 
      48             : #include <algorithm>
      49             : #include <cctype>
      50             : #include <locale>
      51             : 
      52             : typedef unsigned char xmlChar;
      53             : 
      54             : struct _xmlNode;
      55             : typedef struct _xmlNode xmlNode;
      56             : typedef xmlNode *xmlNodePtr;
      57             : 
      58             : struct _xmlDoc;
      59             : typedef struct _xmlDoc xmlDoc;
      60             : typedef xmlDoc *xmlDocPtr;
      61             : 
      62             : struct _xsltStylesheet;
      63             : typedef struct _xsltStylesheet xsltStylesheet;
      64             : typedef xsltStylesheet *xsltStylesheetPtr;
      65             : 
      66             : extern "C" int xmlLoadExtDtdDefaultValue;
      67             : 
      68             : namespace asdm {
      69             :   /**
      70             :    * Some utility methods to manipulate directories.
      71             :    */
      72             :          
      73             :   /**
      74             :    * Returns whether the specified directory exists.
      75             :    *
      76             :    * Example:
      77             :    * --------
      78             :    *          if (!directoryExists("output"))
      79             :    *          {
      80             :    *              createDirectory("output");
      81             :    *          }
      82             :    */ 
      83             :   bool directoryExists(const char* dir);
      84             :         
      85             :   /**
      86             :    * Creates the specified directory. Fails if the path leading to
      87             :    * this directory does not exist.
      88             :    *
      89             :    * Example:
      90             :    * --------
      91             :    *          createDirectory("output");      
      92             :    */
      93             :   bool createDirectory(const char* dir);
      94             :         
      95             :   /**
      96             :    * Creates a complete path.
      97             :    *
      98             :    * Example:
      99             :    * --------
     100             :    *           ("output/sample1/temperature0/");
     101             :    */
     102             :   bool createPath(const char* path);
     103             :         
     104             :         
     105             :   /**
     106             :    * Swap bytes 
     107             :    */
     108             : #define ByteSwap5(x) ByteSwap((unsigned char *) &x,sizeof(x))        
     109             :   void ByteSwap(unsigned char * b, int n);
     110             : 
     111             :   /**
     112             :    * A class to represent byte order information.
     113             :    *
     114             :    */
     115             :   class ByteOrder {
     116             :   public:
     117             :     static const ByteOrder* Little_Endian; /*< A unique object to represent a little endian byte order. */
     118             :     static const ByteOrder* Big_Endian;    /*< A unique object to represent a big endian byte order. */
     119             :     static const ByteOrder* Machine_Endianity; /*< A unique object storing the endianity of the machine. */
     120             : 
     121             :     /**
     122             :      * Returns a string representation of this.
     123             :      *
     124             :      * <ul>
     125             :      * <li> Little_Endian is returned as "Little_Endian", </li>
     126             :      * <li> Big_Endian is returned as "Big_Endian", </li>
     127             :      * </ul>
     128             :      */
     129             :     std::string toString() const ;
     130             : 
     131             :     /**
     132             :      * Convert a string to a const ByteOrder*.
     133             :      *
     134             :      * @param s the input string.
     135             :      * @return a const pointer to a ByteOrder for which the toString() method returns
     136             :      * a string == to the input string, or 0 if no such instance of ByteOrder exists.
     137             :      */
     138             :     static const ByteOrder* fromString(const std::string & s);
     139             : 
     140             :   private:
     141             :     std::string name_;
     142             : 
     143             :     ByteOrder(const std::string & name);
     144             :     virtual ~ByteOrder();
     145             :     static const ByteOrder* machineEndianity(); 
     146             :   };
     147             : 
     148             :   /**
     149             :    * Return a string whose content is equal to the content of s
     150             :    * but with all the repetitions of '/' characters replaced by
     151             :    * a unique '/'.
     152             :    *
     153             :    * @return a string.
     154             :    */
     155             :   std::string uniqSlashes(const std::string& s);
     156             : 
     157             : 
     158             : #ifdef WITHOUT_BOOST
     159             :   // string trimming functions to be used in place of boost functions
     160             :   // uses lambdas (c++11)
     161             : 
     162             :   // trim from start (in place)
     163      753681 :   inline void ltrim(std::string &s) {
     164      753681 :     s.erase(s.begin(), std::find_if(s.begin(), s.end(), [](int ch) {
     165     1100423 :           return !std::isspace(ch);
     166             :         }));
     167      753681 :   }
     168             : 
     169             :   // trim from end (in place)
     170      753681 :   inline void rtrim(std::string &s) {
     171     1507362 :     s.erase(std::find_if(s.rbegin(), s.rend(), [](int ch) {
     172      753760 :           return !std::isspace(ch);
     173     1507362 :         }).base(), s.end());
     174      753681 :   }
     175             : 
     176             :   // trim from both ends (in place)
     177      753681 :   inline void trim(std::string &s) {
     178      753681 :     ltrim(s);
     179      753681 :     rtrim(s);
     180      753681 :   }
     181             : 
     182             :   // trim from start (copying)
     183             :   inline std::string ltrim_copy(std::string s) {
     184             :     ltrim(s);
     185             :     return s;
     186             :   }
     187             : 
     188             :   // trim from end (copying)
     189             :   inline std::string rtrim_copy(std::string s) {
     190             :     rtrim(s);
     191             :     return s;
     192             :   }
     193             : 
     194             :   // trim from both ends (copying)
     195      148961 :   inline std::string trim_copy(std::string s) {
     196      148961 :     trim(s);
     197      148961 :     return s;
     198             :   }
     199             : 
     200             :   // return a copy of str with everything transformed to upper case
     201      344078 :   inline std::string str_toupper(std::string s) {
     202     5033431 :     std::transform(s.begin(), s.end(), s.begin(), [](unsigned char c) { return std::toupper(c); });
     203      344078 :     return s;
     204             :   }
     205             : 
     206             :   // return a copy of str with everything transformed to lower case
     207             :   inline std::string str_tolower(std::string s) {
     208             :     std::transform(s.begin(), s.end(), s.begin(), [](unsigned char c) { return std::tolower(c); });
     209             :     return s;
     210             :   }
     211             : 
     212             :   // split a string into vector using provided character as the delimiter
     213             :   // resuls are added to the pre-existing results vector
     214      132909 :   inline void strsplit(const std::string &str, char delim, std::vector<std::string> &result) {
     215      132909 :     std::stringstream ss(str);
     216      132909 :     std::string token;
     217      397571 :     while(std::getline(ss,token,delim)) {
     218      264662 :       result.push_back(token);
     219             :     }
     220      132909 :   }
     221             : 
     222             :   // check to see if a file exists using posix 'stat(...)'
     223        1915 :   inline bool file_exists(const std::string &filename) {
     224             :     struct stat statbuf;
     225        1915 :     return (stat(filename.c_str(),&statbuf)==0);
     226             :   }
     227             : 
     228             : #endif
     229             : 
     230             :   class ASDMUtilsException {
     231             :   public:
     232             :     ASDMUtilsException();
     233             :     ASDMUtilsException(const std::string& message);
     234             :     
     235             :     const std::string& getMessage() const;
     236             :     
     237             :   private:
     238             :     std::string message;
     239             :   };
     240             :   
     241             :   class ASDMUtils {
     242             :   public :
     243             :     enum Origin { UNKNOWN, ALMA, EVLA };
     244             :     static std::string          version (const std::string& asdmPath);
     245             :     static std::vector<std::string> telescopeNames(const std::string& asdmPath);
     246             :     static Origin               origin(const std::vector<std::string>& telescopeNames);
     247             :     static std::vector<std::string> xmlFilenames(const std::string& asdmPath);
     248             :     
     249             :     static std::string pathToV2V3ALMAxslTransform() ;
     250             :     static std::string pathToV2V3EVLAxslTransform() ;
     251             :     static std::string nameOfV2V3xslTransform(ASDMUtils::Origin origin);
     252             : 
     253             : #ifndef WITHOUT_BOOST
     254             :     struct DotXMLFilter {
     255             :     public:
     256             :       DotXMLFilter(std::vector<std::string>& filenames);
     257             :       //void operator() (path& p);
     258             :       void operator() ( boost::filesystem::directory_entry& p);
     259             :     private:
     260             :       std::vector<std::string>* filenames;    
     261             :     };
     262             : #endif
     263             :     
     264             :   private :
     265             :     static bool initialize();
     266             :     static bool initialized;
     267             :     static bool hasChild(xmlDocPtr, xmlNodePtr node, const xmlChar* childName);
     268             :     static std::string parseRow(xmlDocPtr, xmlNodePtr node, const xmlChar* childName);
     269             :     static std::set<std::string> evlaValidNames;
     270             :     static std::set<std::string> almaValidNames;
     271             :     static std::map<ASDMUtils::Origin, std::string> filenameOfV2V3xslTransform;
     272             :     static std::map<std::string, std::string> rootSubdir ;
     273             : 
     274             :     static std::string pathToxslTransform( const std::string& xsltFilename);
     275             :   }; // end class ASDMUtil.
     276             : 
     277             : 
     278             :   /**
     279             :    * A class to define a collection of options regarding the way to consider an ASDM dataset
     280             :    * especially when it's about to be read on disk, parsed and transformed into its representation in memory.
     281             :    *
     282             :    *
     283             :    * The options that can be set with instances of this class are :
     284             :    * <ul>
     285             :    * <li> The origin of the dataset , i.e. the location where it's been produced. Currently three locations are known : ALMA, EVLA and IRAM at
     286             :    * its Plateau de Bure.</li>
     287             :    * <li> The version of the dataset. At present time version 2 or version 3 are known.</li>
     288             :    * <li> The fact that all the tables of a dataset are expected to be present in memory or only those which are referenced by the code
     289             :    * which needs to acces them </li>
     290             :    * </ul>
     291             :    * The method setFromFile defined in the class ASDM is the principal (not to say only) user of instances of this class.
     292             :    *
     293             :    * It should be noticed that all the methods defined to set the options return a reference onto the instance of ASDMParseOptions they 
     294             :    * are applied. This technique facilitates the definition of a collection of options in one single statement, e.g. :
     295             :    *
     296             :    * <code>
     297             :    * ASDMParseOptions parse;
     298             :    * parse.asALMA().asV2().loadTablesOnDemand(true);
     299             :    * </code>
     300             :    *
     301             :    */ 
     302             : 
     303             :   class ASDMParseOptions {
     304             :     friend class ASDM;
     305             : 
     306             :   public:
     307             :     /**
     308             :      * A null constructor.
     309             :      *
     310             :      * The instance built by this constructor defines the instances as follows :
     311             :      * <ul>
     312             :      * <li> The origin is UNKNOWN. </li>
     313             :      * <li> The version is UNKNOWN. </li>
     314             :      * <li> All the tables are to be loaded in memory. </li>
     315             :      * </ul>
     316             :      *
     317             :      */
     318             :     ASDMParseOptions();
     319             : 
     320             :     /**
     321             :      * A copy constructor
     322             :      */
     323             :     ASDMParseOptions(const ASDMParseOptions& x);
     324             : 
     325             :     /**
     326             :      * The destructor.
     327             :      * Does nothing special.
     328             :      */
     329             :     virtual ~ASDMParseOptions();
     330             : 
     331             :     /**
     332             :      * = operator.
     333             :      */
     334             :     ASDMParseOptions & operator=(const ASDMParseOptions & rhs);
     335             : 
     336             :     
     337             :     /**
     338             :      * This is an ALMA dataset.
     339             :      */
     340             :     ASDMParseOptions& asALMA();
     341             : 
     342             :     /**
     343             :      * This is an IRAM / Plateau de Bure dataset.
     344             :      */
     345             :     ASDMParseOptions& asIRAM_PDB();
     346             : 
     347             :     /**
     348             :      * This is an EVLA dataset.
     349             :      */
     350             :     ASDMParseOptions& asEVLA();
     351             : 
     352             :     /**
     353             :      * This is a V2 dataset.
     354             :      */
     355             :     ASDMParseOptions& asV2();
     356             : 
     357             :     /**
     358             :      * This is a V3 dataset.
     359             :      */
     360             :     ASDMParseOptions& asV3();
     361             : 
     362             :     /**
     363             :      * Load all the tables in memory or only those which are required by the code.
     364             :      *
     365             :      * @param b a boolean value. <code>true</code> <-> load only the table which are required by the code when they are referred, <code>false</code> <-> load
     366             :      * all the code.
     367             :      */
     368             :     ASDMParseOptions& loadTablesOnDemand(bool b);
     369             : 
     370             :     /**
     371             :      * Determines if a control of the uniqueness is performed (b==true) or not (b==false) for each row of each table converted and loaded into memory.
     372             :      * 
     373             :      * @param bool b 
     374             :      *
     375             :      */
     376             :     ASDMParseOptions& checkRowUniqueness(bool b);
     377             : 
     378             :     /**
     379             :      * Defines how an instance of ASDMParseOptions is output on an ostream.
     380             :      */
     381             :     friend std::ostream& operator<<(std::ostream& output, const ASDMParseOptions& p);
     382             : 
     383             :     std::string toString() const;
     384             : 
     385             :   private:
     386             :     ASDMUtils::Origin   origin_;
     387             :     bool                detectOrigin_;
     388             :     std::string         version_;
     389             :     bool                detectVersion_;
     390             :     bool                loadTablesOnDemand_;
     391             :     bool                checkRowUniqueness_;
     392             :   };                            // end class ASDMParseOptions.
     393             : 
     394             :   /**
     395             :    * A class to represent an exception thrown while an XSL transformation is applied by an instance of XSLTransformer.
     396             :    */
     397             : 
     398             :   class XSLTransformerException {
     399             : 
     400             :   public:
     401             :     /**
     402             :      * An empty constructor.
     403             :      */
     404             :     XSLTransformerException();
     405             : 
     406             :     /**
     407             :      * A constructor with a message associated with the exception.
     408             :      * @param m a string containing the message.
     409             :      */
     410             :     XSLTransformerException(const std::string & m);
     411             :     
     412             :     /**
     413             :      * The destructor.
     414             :      */
     415             :     virtual ~XSLTransformerException();
     416             : 
     417             :     /**
     418             :      * Return the message associated to this exception.
     419             :      * @return a string.
     420             :      */
     421             :     std::string getMessage() const;
     422             : 
     423             :   protected:
     424             :     std::string message;
     425             : 
     426             :   };
     427             : 
     428             :   inline XSLTransformerException::XSLTransformerException() : message ("XSLTransformerException") {}
     429           0 :   inline XSLTransformerException::XSLTransformerException(const std::string& m) : message(m) {}
     430           0 :   inline XSLTransformerException::~XSLTransformerException() {}
     431           0 :   inline std::string XSLTransformerException::getMessage() const {
     432           0 :     return "XSLTransformerException : " + message;
     433             :   }
     434             : 
     435             :   /**
     436             :    * A class to apply XSL transformations on an XML document.
     437             :    * The XSL transformation to be applied is defined when an instance is constructed. The class has its operator operator() overloaded 
     438             :    * so that the transformation can be applied by using the instance as a functor.
     439             :    *
     440             :    * An instance built with an empty constructor will be interpreted as a "neutral" transformation, i.e. a transformation which leaves 
     441             :    * the XML document unchanged.
     442             :    *
     443             :    */
     444             :   class XSLTransformer {
     445             :   public:
     446             :     /**
     447             :      * The empty constructor.
     448             :      * 
     449             :      * The instance will leave the XML document unchanged.
     450             :      */
     451             :     XSLTransformer();
     452             : 
     453             :     /**
     454             :      * The destructor.
     455             :      */
     456             :     virtual ~XSLTransformer();
     457             : 
     458             :     /**
     459             :      * A constructor with an XSL transformation.
     460             :      *
     461             :      * The XSL transformation is read in the file whose path is passed as a parameter, then it's parsed
     462             :      * and stored in memory. 
     463             :      *
     464             :      * @param xslPath the path ot the file containing the XSL transformation.
     465             :      * @throws XSLTransformerException;
     466             :      */
     467             :     XSLTransformer(const std::string& xsltPath);
     468             : 
     469             :     /**
     470             :      * A setter to (re) define the XSL transformation associated with the instance of XSLTransformer.
     471             :      *
     472             :      * The XSL transformation is read in the file whose path is passed as a parameter, then it's parsed
     473             :      * and stored in memory. 
     474             :      * 
     475             :      * @param xslPath the path ot the file containing the XSL transformation.
     476             :      *
     477             :      * @throws XSLTransformerException.
     478             :      */
     479             :     void setTransformation(const std::string& xsltPath);
     480             : 
     481             :     /**
     482             :      * Overloads operator() so that the instance can be used as a functor to apply the transformation on a given XML document.
     483             :      *
     484             :      * The XML document to be transformed is expected to be found in a file whose path is passed as a parameter. 
     485             :      * It is read and parsed and stored into memory, then the XSL transformation associated with the instance is applied to the XML document 
     486             :      * stored in memory and finally the result of the transformation is converted to a string which is returned to the caller.
     487             :      *
     488             :      * @param xsltPath a string whose value is the path to the file containing the XML document to be transformed.
     489             :      * @return a string containing the result of the transformation applied to the XML document.
     490             :      *
     491             :      * @throws XSLTransformerException.
     492             :      *
     493             :      */
     494             :     std::string operator()(const std::string& xmlPath);
     495             :     
     496             :   private:
     497             :     
     498             :     xsltStylesheetPtr cur;
     499             : 
     500             :     XSLTransformer& operator=(const XSLTransformer & rhs);
     501             :     XSLTransformer(const XSLTransformer & rsh);    
     502             :   }; // end class XSLTransformer.
     503             : 
     504             : 
     505             :   /**
     506             :    * Functor class of for a comparison between a "given" character and a characted assumed to be read from a file.
     507             :    * 
     508             :    * Instances of this class are meant to  be used as binary bool functor comparing the uppercase version of the first (char) operand
     509             :    * with the second (char) operand and returning the boolan result of the comparison as long as the read head position in 
     510             :    * the file passed as a parameter to the constructor is smaller than a limit also passed a parameter to the constructor. Once this 
     511             :    * limit is passed , the () operator which returns the result of the comparison will return systematically true.
     512             :    *
     513             :    */
     514             :   class CharComparator {
     515             :   public:
     516             :     CharComparator(std::ifstream * is_p = NULL, off_t limit = 0);
     517             :     bool operator() (char cl, char cr);
     518             : 
     519             :   private:
     520             :     std::ifstream* is_p;
     521             :     off_t limit;
     522             :     char* asdmDebug_p; 
     523             :   };
     524             : 
     525             :   /**
     526             :    * Functor class of for a comparison between a "given" character and a characted assumed to be read in a file with a an accumulation
     527             :    * of the characters read in the file into a accumulating string.
     528             :    * 
     529             :    * Instances of this class are meant to  be used as binary bool functor comparing the uppercase version of the first (char) operand
     530             :    * with the second (char) operand and returning the boolan result of the comparison as long as the read head position in 
     531             :    * the file passed as a parameter to the constructor is smaller than a limit also passed a parameter to the constructor. Once this 
     532             :    * limit is passed , the () operator which returns the result of the comparison will return systematically true. When the comparison
     533             :    * returns false, the character read from the file is appended to one string whose pointer is passed as a parameter to the constructor.
     534             :    *
     535             :    */
     536             : 
     537             :   class CharCompAccumulator {
     538             :   private:
     539             :     std::string*    accumulator_p;
     540             :     std::ifstream*  is_p;
     541             :     off_t           limit;
     542             :     int             nEqualChars;
     543             :     char*           asdmDebug_p; 
     544             :   public:
     545             :     /**
     546             :      * The constructor.
     547             :      *
     548             :      * @param accumulator_p a pointer to a string where the characters will be accumulated as a side effect of the call to the operator ().
     549             :      * @param is_p a pointer to the file where the characters are assumed to be read.
     550             :      * @param limit the position in the file beyond which the comparison will return systematically true.
     551             :      */
     552             :     CharCompAccumulator(std::string* accumulator_p = NULL, std::ifstream * is_p = NULL , off_t limit = 0);
     553             : 
     554             :     /**
     555             :      * Returns true when tpupper(cl) is equal to cr or when the read head position in is_p is >= limit. 
     556             :      * @return a boolean
     557             :      *
     558             :      * Side effect : append cl to *accumulator when the result of the comparison is false.
     559             :      */
     560             :     bool operator()(char cl, char cr);
     561             :   };
     562             : } // end namespace asdm
     563             : #endif  // MISC_H
     564             : 

Generated by: LCOV version 1.16