Cbeam
Loading...
Searching...
No Matches
system_folders.hpp
Go to the documentation of this file.
1/*
2Copyright (c) 2025 acrion innovations GmbH
3Authors: Stefan Zipproth, s.zipproth@acrion.ch
4
5This file is part of Cbeam, see https://github.com/acrion/cbeam and https://cbeam.org
6
7Cbeam is offered under a commercial and under the AGPL license.
8For commercial licensing, contact us at https://acrion.ch/sales. For AGPL licensing, see below.
9
10AGPL licensing:
11
12Cbeam is free software: you can redistribute it and/or modify
13it under the terms of the GNU Affero General Public License as published by
14the Free Software Foundation, either version 3 of the License, or
15(at your option) any later version.
16
17Cbeam is distributed in the hope that it will be useful,
18but WITHOUT ANY WARRANTY; without even the implied warranty of
19MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20GNU Affero General Public License for more details.
21
22You should have received a copy of the GNU Affero General Public License
23along with Cbeam. If not, see <https://www.gnu.org/licenses/>.
24*/
25
26#pragma once
27
28#include <cbeam/error/runtime_error.hpp> // for cbeam::error:runtime_error
29
30#ifdef _WIN32
31 #include "windows_config.hpp"
32 #include <Knownfolders.h>
33 #include <shlobj_core.h>
34 #pragma comment(lib, "comsuppw.lib")
35 #pragma comment(lib, "kernel32.lib")
36#else
37 #include <cbeam/config.hpp>
38
39 #if HAVE_PWD_H
40 #include <pwd.h> // for getpwuid, passwd
41 #endif
42 #if HAVE_UNISTD_H
43 #include <unistd.h> // for getuid
44 #endif
45#endif
46
47#include <filesystem> // for std::filesystem::path, std::filesystem::operator/, std::filesystem::exists
48#include <mutex> // for std::mutex, std::lock_guard
49#include <string> // for std::allocator, std::operator+, std::char_traits, std::string_literals::operator""s, std::string_literals
50
51namespace cbeam::filesystem
52{
62 inline std::filesystem::path get_home_dir()
63 {
64 static std::filesystem::path home_folder;
65 static std::mutex mtx;
66 std::lock_guard<std::mutex> lock(mtx);
67
68 if (home_folder.empty())
69 {
70#ifdef _WIN32
71 PWSTR pszPath = nullptr;
72 HRESULT hr = SHGetKnownFolderPath(FOLDERID_Profile, 0, nullptr, &pszPath);
73
74 if (hr == S_OK && pszPath)
75 {
76 home_folder = pszPath;
77 }
78 else
79 {
80 throw cbeam::error::runtime_error("Failed to determine path to user's home directory (FOLDERID_Profile)");
81 }
82#elif HAVE_PWD_H && HAVE_UNISTD_H
83
84 struct passwd* p = getpwuid(getuid());
85 if (p == nullptr)
86 {
87 throw cbeam::error::runtime_error("Failed to determine path to user's home directory (passwd::pw_dir)");
88 }
89 home_folder = p->pw_dir;
90#else
91 #error Unsupported platform
92#endif
93 }
94
95 return home_folder;
96 }
97
108 inline std::filesystem::path get_user_data_dir()
109 {
110 using namespace std::string_literals;
111
112 static std::filesystem::path app_data_folder;
113 static std::mutex mtx;
114 std::lock_guard<std::mutex> lock(mtx);
115
116#ifdef _WIN32
117 PWSTR pszPath = nullptr;
118 HRESULT hr = SHGetKnownFolderPath(FOLDERID_RoamingAppData, 0, nullptr, &pszPath);
119
120 if (hr == S_OK && pszPath)
121 {
122 app_data_folder = pszPath;
123 }
124 else
125 {
126 throw cbeam::error::runtime_error("Failed to determine Cbeam %APPDATA% path");
127 }
128#else
129 #if defined(__linux__)
130 app_data_folder = get_home_dir() / ".local"s / "share"s;
131 #elif defined(__APPLE__)
132 app_data_folder = get_home_dir() / "Library" / "Application Support";
133 #else
134 #error Unknown platform (please extended the code to check an appropriate macro)
135 #endif
136#endif
137
138 if (!std::filesystem::exists(app_data_folder))
139 {
140 throw cbeam::error::runtime_error("Path '" + app_data_folder.string() + "' is expected to exist on this system.");
141 }
142
143 return app_data_folder;
144 }
145
156 inline std::filesystem::path get_user_cache_dir()
157 {
158 using namespace std::string_literals;
159
160 static std::filesystem::path cache_dir;
161 static std::mutex mtx;
162 std::lock_guard<std::mutex> lock(mtx);
163
164#ifdef _WIN32
165 PWSTR pszPath = nullptr;
166 HRESULT hr = SHGetKnownFolderPath(FOLDERID_LocalAppData, 0, nullptr, &pszPath);
167
168 if (hr == S_OK && pszPath)
169 {
170 cache_dir = pszPath;
171 }
172 else
173 {
174 throw cbeam::error::runtime_error("Failed to determine %LOCALAPPDATA% path");
175 }
176#else
177 #if defined(__linux__)
178 cache_dir = get_home_dir() / ".cache"s;
179 #elif defined(__APPLE__)
180 cache_dir = get_home_dir() / "Library" / "Caches";
181 #else
182 #error Unknown platform (please extended the code to check an appropriate macro)
183 #endif
184#endif
185
186 if (!std::filesystem::exists(cache_dir))
187 {
188 throw cbeam::error::runtime_error("Path '" + cache_dir.string() + "' is expected to exist on this system.");
189 }
190
191 return cache_dir;
192 }
193}
A Cbeam-specific runtime error that also acts like std::runtime_error.
Definition runtime_error.hpp:46
Facilitates file I/O, path normalization, and directory operations in a cross-platform manner....
Definition io.hpp:36
std::filesystem::path get_user_cache_dir()
Retrieves the path for storing user-specific cache data.
Definition system_folders.hpp:156
std::filesystem::path get_user_data_dir()
Retrieves the path for storing user-specific application data.
Definition system_folders.hpp:108
std::filesystem::path get_home_dir()
Retrieves the path to the user's home directory, based on the operating system.
Definition system_folders.hpp:62
Header file to manage inclusion of windows.h with specific settings.