LCOV - code coverage report
Current view: top level - src/utils/common - FileHelpers.cpp (source / functions) Coverage Total Hit
Test: lcov.info Lines: 59.0 % 105 62
Test Date: 2024-11-22 15:46:21 Functions: 55.6 % 18 10

            Line data    Source code
       1              : /****************************************************************************/
       2              : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
       3              : // Copyright (C) 2001-2024 German Aerospace Center (DLR) and others.
       4              : // This program and the accompanying materials are made available under the
       5              : // terms of the Eclipse Public License 2.0 which is available at
       6              : // https://www.eclipse.org/legal/epl-2.0/
       7              : // This Source Code may also be made available under the following Secondary
       8              : // Licenses when the conditions for such availability set forth in the Eclipse
       9              : // Public License 2.0 are satisfied: GNU General Public License, version 2
      10              : // or later which is available at
      11              : // https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
      12              : // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
      13              : /****************************************************************************/
      14              : /// @file    FileHelpers.cpp
      15              : /// @author  Daniel Krajzewicz
      16              : /// @author  Michael Behrisch
      17              : /// @date    Mon, 17 Dec 2001
      18              : ///
      19              : // Functions for an easier usage of files
      20              : /****************************************************************************/
      21              : #include <config.h>
      22              : 
      23              : #include <string>
      24              : #ifdef WIN32
      25              : // this is how fox does it in xincs.h
      26              : #include <io.h>
      27              : #define access _access
      28              : #define R_OK    4       /* Test for read permission.  */
      29              : #include <direct.h>
      30              : #define getcwd _getcwd // stupid MSFT "deprecation" warning
      31              : #else
      32              : #include <unistd.h>
      33              : #endif
      34              : #include <fstream>
      35              : #include <sys/stat.h>
      36              : #include "FileHelpers.h"
      37              : #include "StringTokenizer.h"
      38              : #include "StringUtils.h"
      39              : #include "MsgHandler.h"
      40              : 
      41              : 
      42              : // ===========================================================================
      43              : // method definitions
      44              : // ===========================================================================
      45              : 
      46              : // ---------------------------------------------------------------------------
      47              : // file access functions
      48              : // ---------------------------------------------------------------------------
      49              : 
      50              : bool
      51       445245 : FileHelpers::isReadable(std::string path) {
      52       445245 :     if (path.length() == 0) {
      53              :         return false;
      54              :     }
      55       445245 :     while (path[path.length() - 1] == '/' || path[path.length() - 1] == '\\') {
      56              :         path.erase(path.end() - 1);
      57              :     }
      58       445245 :     if (path.length() == 0) {
      59              :         return false;
      60              :     }
      61       445245 :     return access(StringUtils::transcodeToLocal(path).c_str(), R_OK) == 0;
      62              : }
      63              : 
      64              : bool
      65       188799 : FileHelpers::isDirectory(std::string path) {
      66              : #ifdef _MSC_VER
      67              :     struct _stat64 fileInfo;
      68              :     if (_stat64(StringUtils::transcodeToLocal(path).c_str(), &fileInfo) != 0) {
      69              : #else
      70              :     struct stat fileInfo;
      71       377598 :     if (stat(StringUtils::transcodeToLocal(path).c_str(), &fileInfo) != 0) {
      72              : #endif
      73            0 :         throw ProcessError(TLF("Cannot get file attributes for file '%'!", path));
      74              :     }
      75       188799 :     return (fileInfo.st_mode & S_IFMT) == S_IFDIR;
      76              : }
      77              : 
      78              : // ---------------------------------------------------------------------------
      79              : // file path evaluating functions
      80              : // ---------------------------------------------------------------------------
      81              : 
      82              : std::string
      83       171093 : FileHelpers::getFilePath(const std::string& path) {
      84              :     const auto beg = path.find_last_of("\\/");
      85       171093 :     if (beg == std::string::npos) {
      86       161085 :         return "";
      87              :     }
      88        10008 :     return path.substr(0, beg + 1);
      89              : }
      90              : 
      91              : 
      92              : std::string
      93            0 : FileHelpers::getFileFromPath(std::string path, const bool removeExtension) {
      94              :     // first remove extension
      95            0 :     if (removeExtension) {
      96              :         const auto begExtension = path.find_last_of(".");
      97            0 :         if (begExtension != std::string::npos) {
      98            0 :             path = path.substr(0, begExtension);
      99              :         }
     100              :     }
     101              :     // now remove path
     102              :     const auto begPath = path.find_last_of("\\/");
     103            0 :     if (begPath != std::string::npos) {
     104            0 :         path = path.substr(begPath + 1, path.size());
     105              :     }
     106            0 :     return path;
     107              : }
     108              : 
     109              : 
     110              : std::string
     111            0 : FileHelpers::addExtension(const std::string& path, const std::string& extension) {
     112            0 :     if (path.empty()) {
     113            0 :         return "";
     114            0 :     } else if (extension.empty()) {
     115              :         return path;
     116            0 :     } else if (path == extension) {
     117            0 :         return "";
     118            0 :     } else if (path.size() < extension.size()) {
     119              :         return path + extension;
     120              :     } else {
     121              :         // declare two reverse iterator for every string
     122              :         std::string::const_reverse_iterator it_path = path.rbegin();
     123              :         std::string::const_reverse_iterator it_extension = extension.rbegin();
     124              :         // iterate over extension and compare both characters
     125            0 :         while (it_extension != extension.rend()) {
     126              :             // if both characters are different, then return path + extension
     127            0 :             if (*it_path != *it_extension) {
     128              :                 return path + extension;
     129              :             }
     130              :             it_path++;
     131              :             it_extension++;
     132              :         }
     133              :         // if comparison was successful, then the path has already the extension
     134              :         return path;
     135              :     }
     136              : }
     137              : 
     138              : 
     139              : std::string
     140       170256 : FileHelpers::getConfigurationRelative(const std::string& configPath, const std::string& path) {
     141       170256 :     std::string retPath = getFilePath(configPath);
     142       170256 :     return retPath + path;
     143              : }
     144              : 
     145              : 
     146              : bool
     147       243351 : FileHelpers::isSocket(const std::string& name) {
     148              :     const std::string::size_type colonPos = name.find(":");
     149       243351 :     return (colonPos != std::string::npos) && (colonPos > 1 || name[0] == '[');
     150              : }
     151              : 
     152              : 
     153              : bool
     154       175582 : FileHelpers::isAbsolute(const std::string& path) {
     155       175582 :     if (isSocket(path)) {
     156              :         return true;
     157              :     }
     158              :     // check UNIX - absolute paths
     159       175575 :     if (path.length() > 0 && path[0] == '/') {
     160              :         return true;
     161              :     }
     162              :     // check Windows - absolute paths
     163       175419 :     if (path.length() > 0 && path[0] == '\\') {
     164              :         return true;
     165              :     }
     166       175419 :     if (path.length() > 1 && path[1] == ':') {
     167              :         return true;
     168              :     }
     169       175419 :     if (path == "nul" || path == "NUL") {
     170              :         return true;
     171              :     }
     172              :     return false;
     173              : }
     174              : 
     175              : 
     176              : std::string
     177       167087 : FileHelpers::checkForRelativity(const std::string& filename, const std::string& basePath) {
     178       167087 :     if (filename == "stdout" || filename == "STDOUT" || filename == "-") {
     179          141 :         return "stdout";
     180              :     }
     181       166946 :     if (filename == "stderr" || filename == "STDERR") {
     182          108 :         return "stderr";
     183              :     }
     184       166838 :     if (filename == "nul" || filename == "NUL") {
     185          766 :         return "/dev/null";
     186              :     }
     187       166072 :     if (!isAbsolute(filename)) {
     188       165928 :         return getConfigurationRelative(basePath, filename);
     189              :     }
     190              :     return filename;
     191              : }
     192              : 
     193              : 
     194              : std::string
     195            0 : FileHelpers::getCurrentDir() {
     196              :     char buffer[1024];
     197              :     char* answer = getcwd(buffer, sizeof(buffer));
     198            0 :     if (answer) {
     199            0 :         return answer;
     200              :     }
     201            0 :     return "";
     202              : }
     203              : 
     204              : 
     205              : std::vector<std::string>
     206         3455 : FileHelpers::splitDirs(const std::string& filename) {
     207              :     std::vector<std::string> result;
     208        16077 :     for (const std::string& d : StringTokenizer(filename, "\\/", true).getVector()) {
     209         5712 :         if (d == ".." && !result.empty() && result.back() != "..") {
     210              :             result.pop_back();
     211         5707 :         } else if ((d == "" && result.empty()) || (d != "" && d != ".")) {
     212         5707 :             result.push_back(d);
     213              :         }
     214         3455 :     }
     215         3455 :     return result;
     216            0 : }
     217              : 
     218              : 
     219              : std::string
     220         1731 : FileHelpers::fixRelative(const std::string& filename, const std::string& basePath, const bool force, std::string curDir) {
     221         1731 :     if (filename == "stdout" || filename == "STDOUT" || filename == "-") {
     222            1 :         return "stdout";
     223              :     }
     224         1730 :     if (filename == "stderr" || filename == "STDERR") {
     225            0 :         return "stderr";
     226              :     }
     227         1730 :     if (filename == "nul" || filename == "NUL" || filename == "/dev/null") {
     228            0 :         return "/dev/null";
     229              :     }
     230         1730 :     if (isSocket(filename) || (isAbsolute(filename) && !force)) {
     231              :         return filename;
     232              :     }
     233         1724 :     std::vector<std::string> filePathSplit = splitDirs(filename);
     234         1724 :     std::vector<std::string> basePathSplit = splitDirs(basePath);
     235         1724 :     if (isAbsolute(filename) || isAbsolute(basePath) || basePathSplit[0] == "..") {
     236              :         // if at least one is absolute we need to make the other absolute too
     237              :         // the same is true if the basePath refers to a parent dir
     238            6 :         if (curDir == "") {
     239            0 :             curDir = getCurrentDir();
     240              :         }
     241            6 :         if (!isAbsolute(filename)) {
     242           12 :             filePathSplit = splitDirs(curDir + "/" + filename);
     243              :         }
     244            6 :         if (!isAbsolute(basePath)) {
     245            9 :             basePathSplit = splitDirs(curDir + "/" + basePath);
     246              :         }
     247            6 :         if (filePathSplit[0] != basePathSplit[0]) {
     248              :             // don't try to make something relative on different windows disks
     249            0 :             return joinToString(filePathSplit, "/");
     250              :         }
     251              :     }
     252         2063 :     while (!filePathSplit.empty() && !basePathSplit.empty() && filePathSplit[0] == basePathSplit[0]) {
     253              :         filePathSplit.erase(filePathSplit.begin());
     254              :         basePathSplit.erase(basePathSplit.begin());
     255              :     }
     256         3004 :     for (int i = 0; i < (int)basePathSplit.size() - 1; i++) {
     257         2560 :         filePathSplit.insert(filePathSplit.begin(), "..");
     258              :     }
     259         1724 :     return joinToString(filePathSplit, "/");
     260         1724 : }
     261              : 
     262              : 
     263              : std::string
     264          674 : FileHelpers::prependToLastPathComponent(const std::string& prefix, const std::string& path) {
     265              :     const std::string::size_type sep_index = path.find_last_of("\\/");
     266          674 :     if (sep_index == std::string::npos) {
     267              :         return prefix + path;
     268              :     } else {
     269         1851 :         return path.substr(0, sep_index + 1) + prefix + path.substr(sep_index + 1);
     270              :     }
     271              : }
     272              : 
     273              : // ---------------------------------------------------------------------------
     274              : // binary reading/writing functions
     275              : // ---------------------------------------------------------------------------
     276              : 
     277              : std::ostream&
     278            0 : FileHelpers::writeInt(std::ostream& strm, int value) {
     279            0 :     strm.write((char*) &value, sizeof(int));
     280            0 :     return strm;
     281              : }
     282              : 
     283              : 
     284              : std::ostream&
     285            0 : FileHelpers::writeFloat(std::ostream& strm, double value) {
     286            0 :     strm.write((char*) &value, sizeof(double));
     287            0 :     return strm;
     288              : }
     289              : 
     290              : 
     291              : std::ostream&
     292            0 : FileHelpers::writeByte(std::ostream& strm, unsigned char value) {
     293            0 :     strm.write((char*) &value, sizeof(char));
     294            0 :     return strm;
     295              : }
     296              : 
     297              : 
     298              : std::ostream&
     299            0 : FileHelpers::writeString(std::ostream& strm, const std::string& value) {
     300            0 :     int size = (int)value.length();
     301              :     const char* cstr = value.c_str();
     302            0 :     writeInt(strm, size);
     303            0 :     strm.write((char*) cstr, (std::streamsize)(sizeof(char)*size));
     304            0 :     return strm;
     305              : }
     306              : 
     307              : 
     308              : std::ostream&
     309            0 : FileHelpers::writeTime(std::ostream& strm, SUMOTime value) {
     310            0 :     strm.write((char*) &value, sizeof(SUMOTime));
     311            0 :     return strm;
     312              : }
     313              : 
     314              : 
     315              : /****************************************************************************/
        

Generated by: LCOV version 2.0-1