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