118 lines · cpp
1//===-- FileCache.cpp -----------------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "lldb/Host/FileCache.h"10 11#include "lldb/Host/File.h"12#include "lldb/Host/FileSystem.h"13 14using namespace lldb;15using namespace lldb_private;16 17FileCache *FileCache::m_instance = nullptr;18 19FileCache &FileCache::GetInstance() {20 if (m_instance == nullptr)21 m_instance = new FileCache();22 23 return *m_instance;24}25 26lldb::user_id_t FileCache::OpenFile(const FileSpec &file_spec,27 File::OpenOptions flags, uint32_t mode,28 Status &error) {29 if (!file_spec) {30 error = Status::FromErrorString("empty path");31 return UINT64_MAX;32 }33 auto file = FileSystem::Instance().Open(file_spec, flags, mode);34 if (!file) {35 error = Status::FromError(file.takeError());36 return UINT64_MAX;37 }38 lldb::user_id_t fd = file.get()->GetDescriptor();39 m_cache[fd] = std::move(file.get());40 return fd;41}42 43bool FileCache::CloseFile(lldb::user_id_t fd, Status &error) {44 if (fd == UINT64_MAX) {45 error = Status::FromErrorString("invalid file descriptor");46 return false;47 }48 FDToFileMap::iterator pos = m_cache.find(fd);49 if (pos == m_cache.end()) {50 error = Status::FromErrorStringWithFormat(51 "invalid host file descriptor %" PRIu64, fd);52 return false;53 }54 FileUP &file_up = pos->second;55 if (!file_up) {56 error = Status::FromErrorString("invalid host backing file");57 return false;58 }59 error = file_up->Close();60 m_cache.erase(pos);61 return error.Success();62}63 64uint64_t FileCache::WriteFile(lldb::user_id_t fd, uint64_t offset,65 const void *src, uint64_t src_len,66 Status &error) {67 if (fd == UINT64_MAX) {68 error = Status::FromErrorString("invalid file descriptor");69 return UINT64_MAX;70 }71 FDToFileMap::iterator pos = m_cache.find(fd);72 if (pos == m_cache.end()) {73 error = Status::FromErrorStringWithFormat(74 "invalid host file descriptor %" PRIu64, fd);75 return false;76 }77 FileUP &file_up = pos->second;78 if (!file_up) {79 error = Status::FromErrorString("invalid host backing file");80 return UINT64_MAX;81 }82 if (static_cast<uint64_t>(file_up->SeekFromStart(offset, &error)) != offset ||83 error.Fail())84 return UINT64_MAX;85 size_t bytes_written = src_len;86 error = file_up->Write(src, bytes_written);87 if (error.Fail())88 return UINT64_MAX;89 return bytes_written;90}91 92uint64_t FileCache::ReadFile(lldb::user_id_t fd, uint64_t offset, void *dst,93 uint64_t dst_len, Status &error) {94 if (fd == UINT64_MAX) {95 error = Status::FromErrorString("invalid file descriptor");96 return UINT64_MAX;97 }98 FDToFileMap::iterator pos = m_cache.find(fd);99 if (pos == m_cache.end()) {100 error = Status::FromErrorStringWithFormat(101 "invalid host file descriptor %" PRIu64, fd);102 return false;103 }104 FileUP &file_up = pos->second;105 if (!file_up) {106 error = Status::FromErrorString("invalid host backing file");107 return UINT64_MAX;108 }109 if (static_cast<uint64_t>(file_up->SeekFromStart(offset, &error)) != offset ||110 error.Fail())111 return UINT64_MAX;112 size_t bytes_read = dst_len;113 error = file_up->Read(dst, bytes_read);114 if (error.Fail())115 return UINT64_MAX;116 return bytes_read;117}118