[wpiutil] Replace llvm filesystem with C++17 filesystem (#3401)

Use ghc::filesystem as fill on older GCC (e.g. RoboRIO).
This can be removed once all GCC platforms have upgraded to 8.1 or later.

File open functionality has been retained from LLVM but moved to "fs" namespace
and tweaked for improved consistency with std::filesystem (e.g. error_code is
passed by reference instead of returned).

Also update WPILibC's Filesystem functions to return std::string.
This commit is contained in:
Peter Johnson
2021-06-01 21:50:35 -07:00
committed by GitHub
parent 01dc0249de
commit fe570e000c
25 changed files with 6757 additions and 3538 deletions

View File

@@ -6,11 +6,10 @@
#include <uv.h>
#include <wpi/FileSystem.h>
#include <wpi/MimeTypes.h>
#include <wpi/Path.h>
#include <wpi/SmallVector.h>
#include <wpi/UrlParser.h>
#include <wpi/fs.h>
#include <wpi/raw_istream.h>
#include <wpi/raw_ostream.h>
#include <wpi/raw_uv_ostream.h>
@@ -104,35 +103,26 @@ void HALSimHttpConnection::SendFileResponse(int code,
const wpi::Twine& contentType,
const wpi::Twine& filename,
const wpi::Twine& extraHeader) {
// open file
int infd;
if (wpi::sys::fs::openFileForRead(filename, infd)) {
MySendError(404, "error opening file");
return;
}
std::string fn = filename.str();
std::error_code ec;
// get status (to get file size)
wpi::sys::fs::file_status status;
if (wpi::sys::fs::status(infd, status)) {
// get file size
auto size = fs::file_size(fn, ec);
if (ec) {
MySendError(404, "error getting file size");
wpi::sys::fs::file_t file = uv_get_osfhandle(infd);
wpi::sys::fs::closeFile(file);
return;
}
uv_os_fd_t outfd;
int err = uv_fileno(m_stream.GetRawHandle(), &outfd);
if (err < 0) {
m_stream.GetLoopRef().ReportError(err);
MySendError(404, "error getting fd");
wpi::sys::fs::file_t file = uv_get_osfhandle(infd);
wpi::sys::fs::closeFile(file);
// open file
wpi::raw_fd_istream is{fn, ec, true};
if (ec) {
MySendError(404, "error opening file");
return;
}
wpi::SmallVector<uv::Buffer, 4> toSend;
wpi::raw_uv_ostream os{toSend, 4096};
BuildHeader(os, code, codeText, contentType, status.getSize(), extraHeader);
BuildHeader(os, code, codeText, contentType, size, extraHeader);
SendData(os.bufs(), false);
Log(code);
@@ -141,11 +131,10 @@ void HALSimHttpConnection::SendFileResponse(int code,
wpi::SmallVector<uv::Buffer, 4> bodyData;
wpi::raw_uv_ostream bodyOs{bodyData, 4096};
wpi::raw_fd_istream is{infd, true};
std::string fileBuf;
size_t oldSize = 0;
while (fileBuf.size() < status.getSize()) {
while (fileBuf.size() < size) {
oldSize = fileBuf.size();
fileBuf.resize(oldSize + 1);
is.read(&(*fileBuf.begin()) + oldSize, 1);
@@ -174,33 +163,28 @@ void HALSimHttpConnection::ProcessRequest() {
}
if (m_request.GetMethod() == wpi::HTTP_GET && path.startswith("/") &&
!path.contains("..")) {
!path.contains("..") && !path.contains("//")) {
// convert to fs native representation
wpi::SmallVector<char, 32> nativePath;
wpi::sys::path::native(path, nativePath);
fs::path nativePath;
if (path.startswith("/user/")) {
std::string prefix = (wpi::sys::path::get_separator() + "user" +
wpi::sys::path::get_separator())
.str();
wpi::sys::path::replace_path_prefix(nativePath, prefix,
m_server->GetWebrootUser());
nativePath = fs::path{std::string{m_server->GetWebrootSys()}} /
fs::path{std::string{path.drop_front(6)},
fs::path::format::generic_format};
} else {
wpi::sys::path::replace_path_prefix(nativePath,
wpi::sys::path::get_separator(),
m_server->GetWebrootSys());
nativePath = fs::path{std::string{m_server->GetWebrootSys()}} /
fs::path{std::string{path.drop_front(1)},
fs::path::format::generic_format};
}
if (wpi::sys::fs::is_directory(nativePath)) {
wpi::sys::path::append(nativePath, "index.html");
if (fs::is_directory(nativePath)) {
nativePath.append("index.html");
}
if (!wpi::sys::fs::exists(nativePath) ||
wpi::sys::fs::is_directory(nativePath)) {
if (!fs::exists(nativePath) || fs::is_directory(nativePath)) {
MySendError(404, "Resource '" + path + "' not found");
} else {
auto contentType = wpi::MimeTypeFromPath(wpi::Twine(nativePath).str());
SendFileResponse(200, "OK", contentType, nativePath);
auto contentType = wpi::MimeTypeFromPath(nativePath.string());
SendFileResponse(200, "OK", contentType, nativePath.string());
}
} else {
MySendError(404, "Resource not found");

View File

@@ -4,12 +4,11 @@
#include "HALSimWeb.h"
#include <wpi/FileSystem.h>
#include <wpi/Path.h>
#include <wpi/SmallString.h>
#include <wpi/Twine.h>
#include <wpi/UrlParser.h>
#include <wpi/WebSocketServer.h>
#include <wpi/fs.h>
#include <wpi/raw_uv_ostream.h>
#include <wpi/uv/Loop.h>
#include <wpi/uv/Tcp.h>
@@ -42,31 +41,22 @@ bool HALSimWeb::Initialize() {
}
// determine where to get static content from
// wpi::SmallVector<char, 64> tmp;
wpi::SmallString<64> tmp;
fs::path path;
const char* webroot_sys = std::getenv("HALSIMWS_SYSROOT");
if (webroot_sys != nullptr) {
wpi::StringRef tstr(webroot_sys);
tmp.append(tstr);
path = webroot_sys;
} else {
wpi::sys::fs::current_path(tmp);
wpi::sys::path::append(tmp, "sim");
path = fs::current_path() / "sim";
}
wpi::sys::fs::make_absolute(tmp);
m_webroot_sys = wpi::Twine(tmp).str();
m_webroot_sys = fs::absolute(path).string();
tmp.clear();
const char* webroot_user = std::getenv("HALSIMWS_USERROOT");
if (webroot_user != nullptr) {
wpi::StringRef tstr(webroot_user);
tmp.append(tstr);
path = webroot_sys;
} else {
wpi::sys::fs::current_path(tmp);
wpi::sys::path::append(tmp, "sim", "user");
path = fs::current_path() / "sim" / "user";
}
wpi::sys::fs::make_absolute(tmp);
m_webroot_user = wpi::Twine(tmp).str();
m_webroot_user = fs::absolute(path).string();
const char* uri = std::getenv("HALSIMWS_URI");
if (uri != nullptr) {