1275072Semaste//===-- FileCache.cpp -------------------------------------------*- C++ -*-===// 2275072Semaste// 3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4353358Sdim// See https://llvm.org/LICENSE.txt for license information. 5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6275072Semaste// 7275072Semaste//===----------------------------------------------------------------------===// 8275072Semaste 9275072Semaste#include "lldb/Host/FileCache.h" 10275072Semaste 11275072Semaste#include "lldb/Host/File.h" 12344779Sdim#include "lldb/Host/FileSystem.h" 13275072Semaste 14275072Semasteusing namespace lldb; 15275072Semasteusing namespace lldb_private; 16275072Semaste 17275072SemasteFileCache *FileCache::m_instance = nullptr; 18275072Semaste 19314564SdimFileCache &FileCache::GetInstance() { 20314564Sdim if (m_instance == nullptr) 21314564Sdim m_instance = new FileCache(); 22275072Semaste 23314564Sdim return *m_instance; 24275072Semaste} 25275072Semaste 26360784Sdimlldb::user_id_t FileCache::OpenFile(const FileSpec &file_spec, 27360784Sdim File::OpenOptions flags, uint32_t mode, 28360784Sdim Status &error) { 29344779Sdim if (!file_spec) { 30314564Sdim error.SetErrorString("empty path"); 31314564Sdim return UINT64_MAX; 32314564Sdim } 33360784Sdim auto file = FileSystem::Instance().Open(file_spec, flags, mode); 34360784Sdim if (!file) { 35360784Sdim error = file.takeError(); 36314564Sdim return UINT64_MAX; 37360784Sdim } 38360784Sdim lldb::user_id_t fd = file.get()->GetDescriptor(); 39360784Sdim m_cache[fd] = std::move(file.get()); 40314564Sdim return fd; 41275072Semaste} 42275072Semaste 43321369Sdimbool FileCache::CloseFile(lldb::user_id_t fd, Status &error) { 44314564Sdim if (fd == UINT64_MAX) { 45314564Sdim error.SetErrorString("invalid file descriptor"); 46314564Sdim return false; 47314564Sdim } 48314564Sdim FDToFileMap::iterator pos = m_cache.find(fd); 49314564Sdim if (pos == m_cache.end()) { 50314564Sdim error.SetErrorStringWithFormat("invalid host file descriptor %" PRIu64, fd); 51314564Sdim return false; 52314564Sdim } 53360784Sdim FileUP &file_up = pos->second; 54360784Sdim if (!file_up) { 55314564Sdim error.SetErrorString("invalid host backing file"); 56314564Sdim return false; 57314564Sdim } 58360784Sdim error = file_up->Close(); 59314564Sdim m_cache.erase(pos); 60314564Sdim return error.Success(); 61275072Semaste} 62275072Semaste 63314564Sdimuint64_t FileCache::WriteFile(lldb::user_id_t fd, uint64_t offset, 64321369Sdim const void *src, uint64_t src_len, 65321369Sdim Status &error) { 66314564Sdim if (fd == UINT64_MAX) { 67314564Sdim error.SetErrorString("invalid file descriptor"); 68314564Sdim return UINT64_MAX; 69314564Sdim } 70314564Sdim FDToFileMap::iterator pos = m_cache.find(fd); 71314564Sdim if (pos == m_cache.end()) { 72314564Sdim error.SetErrorStringWithFormat("invalid host file descriptor %" PRIu64, fd); 73314564Sdim return false; 74314564Sdim } 75360784Sdim FileUP &file_up = pos->second; 76360784Sdim if (!file_up) { 77314564Sdim error.SetErrorString("invalid host backing file"); 78314564Sdim return UINT64_MAX; 79314564Sdim } 80360784Sdim if (static_cast<uint64_t>(file_up->SeekFromStart(offset, &error)) != offset || 81314564Sdim error.Fail()) 82314564Sdim return UINT64_MAX; 83314564Sdim size_t bytes_written = src_len; 84360784Sdim error = file_up->Write(src, bytes_written); 85314564Sdim if (error.Fail()) 86314564Sdim return UINT64_MAX; 87314564Sdim return bytes_written; 88275072Semaste} 89275072Semaste 90314564Sdimuint64_t FileCache::ReadFile(lldb::user_id_t fd, uint64_t offset, void *dst, 91321369Sdim uint64_t dst_len, Status &error) { 92314564Sdim if (fd == UINT64_MAX) { 93314564Sdim error.SetErrorString("invalid file descriptor"); 94314564Sdim return UINT64_MAX; 95314564Sdim } 96314564Sdim FDToFileMap::iterator pos = m_cache.find(fd); 97314564Sdim if (pos == m_cache.end()) { 98314564Sdim error.SetErrorStringWithFormat("invalid host file descriptor %" PRIu64, fd); 99314564Sdim return false; 100314564Sdim } 101360784Sdim FileUP &file_up = pos->second; 102360784Sdim if (!file_up) { 103314564Sdim error.SetErrorString("invalid host backing file"); 104314564Sdim return UINT64_MAX; 105314564Sdim } 106360784Sdim if (static_cast<uint64_t>(file_up->SeekFromStart(offset, &error)) != offset || 107314564Sdim error.Fail()) 108314564Sdim return UINT64_MAX; 109314564Sdim size_t bytes_read = dst_len; 110360784Sdim error = file_up->Read(dst, bytes_read); 111314564Sdim if (error.Fail()) 112314564Sdim return UINT64_MAX; 113314564Sdim return bytes_read; 114275072Semaste} 115