/** Opens a file stream \param[in] file The file to open \param[in] mode How to open it, explicitly. \throws SCXFilePathNotFoundException \throws SCXUnauthorizedFileSystemAccessException \throws InvalidArgumentException Arguments Unlike STL there is no implicit (default) mode, the requested mode has to explicitly stated */ SCXHandle<std::fstream> SCXFile::OpenFstream(const SCXFilePath& file, std::ios_base::openmode mode) { if (!(mode & std::ios::in) && !(mode & std::ios::out)) { throw SCXInvalidArgumentException(L"mode", L"Specify ios::in or ios::out, or both", SCXSRCLOCATION); } #if defined(WIN32) SCXHandle<std::fstream> streamPtr(new std::fstream(file.Get().c_str(), mode)); #elif defined(SCX_UNIX) SCXHandle<std::fstream> streamPtr(new std::fstream(SCXFileSystem::EncodePath(file).c_str(), mode)); #else #error #endif if (streamPtr->good()) { SCXFileSystem::Attributes attribs(SCXFileSystem::GetAttributes(file)); if (attribs.count(SCXFileSystem::eDirectory) > 0) { throw SCXUnauthorizedFileSystemAccessException(file, attribs, SCXSRCLOCATION); } } else { SCXFileInfo info(file); if (mode & std::ios::in) { if (!info.PathExists()) { throw SCXFilePathNotFoundException(file, SCXSRCLOCATION); } else { throw SCXUnauthorizedFileSystemAccessException(file, (SCXFileSystem::GetAttributes(file)), SCXSRCLOCATION); } } else if (mode & std::ios::out) { throw SCXUnauthorizedFileSystemAccessException(file, SCXFileSystem::GetAttributes(file), SCXSRCLOCATION); } else { throw SCXInvalidArgumentException(L"mode", L"Must specify ios:in or ios:out", SCXSRCLOCATION); } } return streamPtr; }
//! Number of days in month //! \param[in] year Year of month //! \param[in] month Month of interest //! \returns Number of days in month of year //! \throws SCXInvalidArgumentException When month is ouside range unsigned DaysInMonth(scxyear year, scxmonth month) { switch (month) { case 1: return 31; case 2: return IsLeapYear(year)? 29: 28; case 3: return 31; case 4: return 30; case 5: return 31; case 6: return 30; case 7: return 31; case 8: return 31; case 9: return 30; case 10: return 31; case 11: return 30; case 12: return 31; default: throw SCXInvalidArgumentException(L"month", StrFrom(month), SCXSRCLOCATION); } }
SCXGlob::SCXGlob(const SCXFilePath &pttrn) : m_pathnames(NULL), m_index(cNoData), m_isBackSlashEscapeOn(true), m_isErrorAbortOn(false) { if (L"" == pttrn.Get()) { throw SCXInvalidArgumentException(L"pattern", L"Empty pattern not allowed", SCXSRCLOCATION); } memset(&m_globHolder, 0, sizeof(glob_t)); this->m_logHandle = SCXLogHandleFactory::GetLogHandle(L"scx.core.common.pal.os.scxglob"); this->m_pattern = StrToUTF8(pttrn.Get()); this->NormalizePattern(); }
/** Deletes the specified file. An exception is not thrown if the specified file does not exist \param[in] path The path to the file to be deleted. \throws SCXUnauthorizedFileSystemAccessException The caller does not have the required permission or path is a directory or path specified a read-only file The path parameter is permitted to specify relative or absolute path information. Relative path information is interpreted as relative to the current working directory. To obtain the current working directory, see GetCurrentDirectory */ void SCXFile::Delete(const SCXFilePath& path) { #if defined(WIN32) int failure = _wremove(path.Get().c_str()); #elif defined(SCX_UNIX) std::string localizedPath = SCXFileSystem::EncodePath(path); int failure = remove(localizedPath.c_str()); #else #error #endif if (failure) { if (errno == EACCES || errno == EBUSY || errno == EPERM || errno == EROFS) { throw SCXUnauthorizedFileSystemAccessException(path, SCXFileSystem::GetAttributes(path), SCXSRCLOCATION); } else if (errno == ENOENT) { const int existenceOnly = 00; #if defined(WIN32) failure = _waccess(path.Get().c_str(), existenceOnly); #elif defined(SCX_UNIX) failure = access(localizedPath.c_str(), existenceOnly); #else #error #endif bool fileStillExists = !failure; if (fileStillExists) { // We got ENOENT when trying to remove the file, // but appearently the file exists. That means that // the file is not a file but a directory throw SCXUnauthorizedFileSystemAccessException(path, SCXFileSystem::GetAttributes(path), SCXSRCLOCATION); } if (errno == EACCES) { throw SCXUnauthorizedFileSystemAccessException(path, SCXFileSystem::GetAttributes(path), SCXSRCLOCATION); } else if (errno == EINVAL) { throw SCXInvalidArgumentException(L"path", L"Invalid format of path " + path.Get(), SCXSRCLOCATION); } else if (errno != ENOENT) { std::wstring problem(L"Failed to delete " + path.Get()); throw SCXInternalErrorException(UnexpectedErrno(problem, errno), SCXSRCLOCATION); } } else { std::wstring problem(L"Failed to delete " + path.Get()); throw SCXInternalErrorException(UnexpectedErrno(problem, errno), SCXSRCLOCATION); } } }
void SCXGlob::NormalizePattern() { SCX_LOGTRACE(m_logHandle, L"NormalizePattern()"); string separator(1, folderSeparator); #ifndef WIN32 // Throws an exception if the pattern does not start with a separator character. if (0 != separator.compare(0, 1, this->m_pattern, 0, 1)) { throw SCXInvalidArgumentException(L"pattern", L"Pattern must start with a directory separator", SCXSRCLOCATION); } // Throws an exception if found a relative path. // The ls command supports relative paths -- commenting out the following check // in order to emulate the ls command's behaviour. // string dot(1, '.'); /*if (string::npos != this->m_pattern.find(dot+separator) || // "./" string::npos != this->m_pattern.find(dot+dot+separator)) // "../" { throw SCXInvalidArgumentException(L"pattern", L"No relative path allowed", SCXSRCLOCATION); }*/ #endif // Removes the trailing slash(es) if any. size_t len = this->m_pattern.size() - 1; while (0 < len && folderSeparator == this->m_pattern[len]) { len--; } if (len < this->m_pattern.size() - 1) { this->m_pattern = this->m_pattern.erase(len+1); } }
//! Checks if two amounts can be considered equivalent taking a certain tolerance into account //! \param[in] amount1 To be compared //! \param[in] amount2 To be compared //! \param[in] tolerance Max difference allowed to consider the amounts equivalent //! \throws SCXInvalidArgumentException Negative tolerance specified bool IsEquivalent(SCXAmountOfTime amount1, SCXAmountOfTime amount2, SCXAmountOfTime tolerance) { if (tolerance < SCXAmountOfTime()) { throw SCXInvalidArgumentException(L"tolerance", L"Tolerance must not be negative", SCXSRCLOCATION); } return Abs(amount1 - amount2) <= tolerance; }