1*80814287SRaphael Isemann //===-- FileCache.cpp -----------------------------------------------------===//
2c00cf4a0SZachary Turner //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6c00cf4a0SZachary Turner //
7c00cf4a0SZachary Turner //===----------------------------------------------------------------------===//
8c00cf4a0SZachary Turner
9c00cf4a0SZachary Turner #include "lldb/Host/FileCache.h"
10c00cf4a0SZachary Turner
11c00cf4a0SZachary Turner #include "lldb/Host/File.h"
1250bc1ed2SJonas Devlieghere #include "lldb/Host/FileSystem.h"
13c00cf4a0SZachary Turner
14c00cf4a0SZachary Turner using namespace lldb;
15c00cf4a0SZachary Turner using namespace lldb_private;
16c00cf4a0SZachary Turner
17c00cf4a0SZachary Turner FileCache *FileCache::m_instance = nullptr;
18c00cf4a0SZachary Turner
GetInstance()19b9c1b51eSKate Stone FileCache &FileCache::GetInstance() {
20c00cf4a0SZachary Turner if (m_instance == nullptr)
21c00cf4a0SZachary Turner m_instance = new FileCache();
22c00cf4a0SZachary Turner
23c00cf4a0SZachary Turner return *m_instance;
24c00cf4a0SZachary Turner }
25c00cf4a0SZachary Turner
OpenFile(const FileSpec & file_spec,File::OpenOptions flags,uint32_t mode,Status & error)2662c9fe42SLawrence D'Anna lldb::user_id_t FileCache::OpenFile(const FileSpec &file_spec,
2762c9fe42SLawrence D'Anna File::OpenOptions flags, uint32_t mode,
2862c9fe42SLawrence D'Anna Status &error) {
2950bc1ed2SJonas Devlieghere if (!file_spec) {
30c00cf4a0SZachary Turner error.SetErrorString("empty path");
31c00cf4a0SZachary Turner return UINT64_MAX;
32c00cf4a0SZachary Turner }
332fce1137SLawrence D'Anna auto file = FileSystem::Instance().Open(file_spec, flags, mode);
342fce1137SLawrence D'Anna if (!file) {
352fce1137SLawrence D'Anna error = file.takeError();
36c00cf4a0SZachary Turner return UINT64_MAX;
372fce1137SLawrence D'Anna }
382fce1137SLawrence D'Anna lldb::user_id_t fd = file.get()->GetDescriptor();
392fce1137SLawrence D'Anna m_cache[fd] = std::move(file.get());
40c00cf4a0SZachary Turner return fd;
41c00cf4a0SZachary Turner }
42c00cf4a0SZachary Turner
CloseFile(lldb::user_id_t fd,Status & error)4397206d57SZachary Turner bool FileCache::CloseFile(lldb::user_id_t fd, Status &error) {
44b9c1b51eSKate Stone if (fd == UINT64_MAX) {
45c00cf4a0SZachary Turner error.SetErrorString("invalid file descriptor");
46c00cf4a0SZachary Turner return false;
47c00cf4a0SZachary Turner }
48c00cf4a0SZachary Turner FDToFileMap::iterator pos = m_cache.find(fd);
49b9c1b51eSKate Stone if (pos == m_cache.end()) {
50c00cf4a0SZachary Turner error.SetErrorStringWithFormat("invalid host file descriptor %" PRIu64, fd);
51c00cf4a0SZachary Turner return false;
52c00cf4a0SZachary Turner }
532fce1137SLawrence D'Anna FileUP &file_up = pos->second;
542fce1137SLawrence D'Anna if (!file_up) {
55c00cf4a0SZachary Turner error.SetErrorString("invalid host backing file");
56c00cf4a0SZachary Turner return false;
57c00cf4a0SZachary Turner }
582fce1137SLawrence D'Anna error = file_up->Close();
59c00cf4a0SZachary Turner m_cache.erase(pos);
60c00cf4a0SZachary Turner return error.Success();
61c00cf4a0SZachary Turner }
62c00cf4a0SZachary Turner
WriteFile(lldb::user_id_t fd,uint64_t offset,const void * src,uint64_t src_len,Status & error)63b9c1b51eSKate Stone uint64_t FileCache::WriteFile(lldb::user_id_t fd, uint64_t offset,
6497206d57SZachary Turner const void *src, uint64_t src_len,
6597206d57SZachary Turner Status &error) {
66b9c1b51eSKate Stone if (fd == UINT64_MAX) {
67c00cf4a0SZachary Turner error.SetErrorString("invalid file descriptor");
68c00cf4a0SZachary Turner return UINT64_MAX;
69c00cf4a0SZachary Turner }
70c00cf4a0SZachary Turner FDToFileMap::iterator pos = m_cache.find(fd);
71b9c1b51eSKate Stone if (pos == m_cache.end()) {
72c00cf4a0SZachary Turner error.SetErrorStringWithFormat("invalid host file descriptor %" PRIu64, fd);
73c00cf4a0SZachary Turner return false;
74c00cf4a0SZachary Turner }
752fce1137SLawrence D'Anna FileUP &file_up = pos->second;
762fce1137SLawrence D'Anna if (!file_up) {
77c00cf4a0SZachary Turner error.SetErrorString("invalid host backing file");
78c00cf4a0SZachary Turner return UINT64_MAX;
79c00cf4a0SZachary Turner }
802fce1137SLawrence D'Anna if (static_cast<uint64_t>(file_up->SeekFromStart(offset, &error)) != offset ||
81b9c1b51eSKate Stone error.Fail())
82c00cf4a0SZachary Turner return UINT64_MAX;
83c00cf4a0SZachary Turner size_t bytes_written = src_len;
842fce1137SLawrence D'Anna error = file_up->Write(src, bytes_written);
85c00cf4a0SZachary Turner if (error.Fail())
86c00cf4a0SZachary Turner return UINT64_MAX;
87c00cf4a0SZachary Turner return bytes_written;
88c00cf4a0SZachary Turner }
89c00cf4a0SZachary Turner
ReadFile(lldb::user_id_t fd,uint64_t offset,void * dst,uint64_t dst_len,Status & error)90b9c1b51eSKate Stone uint64_t FileCache::ReadFile(lldb::user_id_t fd, uint64_t offset, void *dst,
9197206d57SZachary Turner uint64_t dst_len, Status &error) {
92b9c1b51eSKate Stone if (fd == UINT64_MAX) {
93c00cf4a0SZachary Turner error.SetErrorString("invalid file descriptor");
94c00cf4a0SZachary Turner return UINT64_MAX;
95c00cf4a0SZachary Turner }
96c00cf4a0SZachary Turner FDToFileMap::iterator pos = m_cache.find(fd);
97b9c1b51eSKate Stone if (pos == m_cache.end()) {
98c00cf4a0SZachary Turner error.SetErrorStringWithFormat("invalid host file descriptor %" PRIu64, fd);
99c00cf4a0SZachary Turner return false;
100c00cf4a0SZachary Turner }
1012fce1137SLawrence D'Anna FileUP &file_up = pos->second;
1022fce1137SLawrence D'Anna if (!file_up) {
103c00cf4a0SZachary Turner error.SetErrorString("invalid host backing file");
104c00cf4a0SZachary Turner return UINT64_MAX;
105c00cf4a0SZachary Turner }
1062fce1137SLawrence D'Anna if (static_cast<uint64_t>(file_up->SeekFromStart(offset, &error)) != offset ||
107b9c1b51eSKate Stone error.Fail())
108c00cf4a0SZachary Turner return UINT64_MAX;
109c00cf4a0SZachary Turner size_t bytes_read = dst_len;
1102fce1137SLawrence D'Anna error = file_up->Read(dst, bytes_read);
111c00cf4a0SZachary Turner if (error.Fail())
112c00cf4a0SZachary Turner return UINT64_MAX;
113c00cf4a0SZachary Turner return bytes_read;
114c00cf4a0SZachary Turner }
115