aboutsummaryrefslogtreecommitdiff
path: root/toolsrc/src/vcpkg_Files.cpp
blob: 611aa74509200641e2978779c7768d2d63c97195 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
#include "vcpkg_Files.h"
#include <fstream>
#include <filesystem>
#include <regex>

namespace fs = std::tr2::sys;

namespace vcpkg {namespace Files
{
    static const std::regex FILESYSTEM_INVALID_CHARACTERS_REGEX = std::regex(R"([\/:*?"<>|])");

    void check_is_directory(const fs::path& dirpath)
    {
        Checks::check_throw(fs::is_directory(dirpath), "The path %s is not a directory", dirpath.string());
    }

    bool has_invalid_chars_for_filesystem(const std::string s)
    {
        return std::regex_search(s, FILESYSTEM_INVALID_CHARACTERS_REGEX);
    }

    expected<std::string> get_contents(const fs::path& file_path) noexcept
    {
        std::fstream file_stream(file_path, std::ios_base::in | std::ios_base::binary);
        if (file_stream.fail())
        {
            return std::errc::no_such_file_or_directory;
        }

        file_stream.seekg(0, file_stream.end);
        auto length = file_stream.tellg();
        file_stream.seekg(0, file_stream.beg);

        if (length > SIZE_MAX)
        {
            return std::errc::file_too_large;
        }

        std::string output;
        output.resize(static_cast<size_t>(length));
        file_stream.read(&output[0], length);
        file_stream.close();

        return std::move(output);
    }

    fs::path find_file_recursively_up(const fs::path& starting_dir, const std::string& filename)
    {
        fs::path current_dir = starting_dir;
        for (; !current_dir.empty(); current_dir = current_dir.parent_path())
        {
            const fs::path candidate = current_dir / filename;
            if (fs::exists(candidate))
            {
                break;
            }
        }

        return current_dir;
    }
}}