示例#1
0
/*
 * vislib::sys::Path::Resolve
 */
vislib::StringA vislib::sys::Path::Resolve(StringA path, StringA basepath) {
    // TODO: Windows shell API resolve does not work in the expected
    // way, so we use the same manual approach for Windows and Linux.

#ifdef _WIN32
    /* Replace unchefmäßige path separators. */
    basepath.Replace('/', SEPARATOR_A);
    path.Replace('/', SEPARATOR_A);
#endif /* _WIN32 */

    if (Path::IsRelative(basepath)) {
        basepath = Resolve(basepath);
    }

    if (path.IsEmpty()) {
        /* Path is empty, i. e. return current working directory. */
        return Path::Canonicalise(basepath);
    
    } else if (Path::IsAbsolute(path)) {
        /* Path is absolute, just return it. */
        return Path::Canonicalise(path);

    } else if ((path[0] == MYDOCUMENTS_MARKER_A) 
            && ((path.Length() == 1) || path[1] == SEPARATOR_A)) {
        /*
         * replace leading ~ with users home directory
         */
        path.Replace(MYDOCUMENTS_MARKER_A, Path::GetUserHomeDirectoryA(), 1);
        return Path::Canonicalise(path);

    } else if ((path[0] == SEPARATOR_A) && (path[1] != SEPARATOR_A)) {
        /*
         * Concatenate current drive and relative path, and canonicalise
         * the result.
         */
        return Path::Concatenate(basepath.Substring(0, 2), path, true);

    } else {
        /*
         * Concatenate current directory and relative path, and canonicalise
         * the result.
         */
        return Path::Concatenate(basepath, path, true);
    }
}
示例#2
0
/*
 * vislib::sys::Path::MakeDirectory
 */
void vislib::sys::Path::MakeDirectory(const StringA& path) {
    Stack<StringA> missingParts;
    StringA firstBuilt;
    StringA curPath = Resolve(path);

    while (!File::Exists(curPath)) {
        StringA::Size pos = curPath.FindLast(SEPARATOR_A);
        if (pos != StringA::INVALID_POS) {
            missingParts.Push(curPath.Substring(pos + 1));
            if (missingParts.Peek()->IsEmpty()) {
                // Remove empty directories as the incremental directory 
                // creation later on will fail for these.
                missingParts.Pop();
            }
            curPath.Truncate(pos);

        } else {
            // Problem: No Separators left, but directory still does not exist.
#ifdef _WIN32
            throw vislib::sys::SystemException(ERROR_INVALID_NAME, __FILE__, __LINE__);
#else /* _WIN32 */
            throw vislib::sys::SystemException(EINVAL, __FILE__, __LINE__);
#endif /* _WIN32 */
        }
    }

    // curPath exists
    if (!File::IsDirectory(curPath)) {
        // the latest existing directory is not a directory (may be a file?)
#ifdef _WIN32
        throw vislib::sys::SystemException(ERROR_DIRECTORY, __FILE__, __LINE__);
#else /* _WIN32 */
        throw vislib::sys::SystemException(EEXIST, __FILE__, __LINE__);
#endif /* _WIN32 */
    }

    while (!missingParts.IsEmpty()) {
        curPath += SEPARATOR_A;
        curPath += missingParts.Pop();

#ifdef _WIN32
        if (CreateDirectoryA(curPath, NULL) != 0) {
#else /* _WIN32 */
        if (mkdir(curPath, S_IRWXG | S_IRWXO | S_IRWXU) == 0) { // TODO: Check
#endif /* _WIN32 */
            // success, so go on.
            if (firstBuilt.IsEmpty()) {
                firstBuilt = curPath;
            }

        } else {
            DWORD errorCode = GetLastError();

            try {
                // failure, so try to remove already created paths and throw exception.
                DeleteDirectory(firstBuilt, true);
            } catch(...) {
            }

            throw vislib::sys::SystemException(errorCode, __FILE__, __LINE__);
        }
    }
    // we are done!
}


/*
 * vislib::sys::Path::MakeDirectory
 */
void vislib::sys::Path::MakeDirectory(const StringW& path) {
#ifdef _WIN32
    Stack<StringW> missingParts;
    StringW firstBuilt;
    StringW curPath = Resolve(path);

    while (!File::Exists(curPath)) {
        StringW::Size pos = curPath.FindLast(SEPARATOR_W);
        if (pos != StringW::INVALID_POS) {
            missingParts.Push(curPath.Substring(pos + 1));
            if (missingParts.Peek()->IsEmpty()) {
                // Remove empty directories as the incremental directory 
                // creation later on will fail for these.
                missingParts.Pop();
            }
            curPath.Truncate(pos);

        } else {
            // Problem: No Separators left, but directory still does not exist.
            throw vislib::sys::SystemException(ERROR_INVALID_NAME, __FILE__, __LINE__);
        }
    }

    // curPath exists
    if (!File::IsDirectory(curPath)) {
        // the latest existing directory is not a directory (may be a file?)
        throw vislib::sys::SystemException(ERROR_DIRECTORY, __FILE__, __LINE__);
    }

    while (!missingParts.IsEmpty()) {
        curPath += SEPARATOR_W;
        curPath += missingParts.Pop();

        if (CreateDirectoryW(curPath, NULL) != 0) {
            // success, so go on.
            if (firstBuilt.IsEmpty()) {
                firstBuilt = curPath;
            }

        } else {
            DWORD errorCode = GetLastError();

            try {
                // failure, so try to remove already created paths and throw exception.
                DeleteDirectory(firstBuilt, true);
            } catch(...) {
            }

            throw vislib::sys::SystemException(errorCode, __FILE__, __LINE__);
        }
    }
    // we are done!

#else /* _WIN32 */
    // linux is stupid
    MakeDirectory(W2A(path));

#endif /* _WIN32 */
}