/**
        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;
    }
Exemple #2
0
//! 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);
    }
}
Exemple #3
0
    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);
            }
        }
    }
Exemple #5
0
    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;
}