1c00cf4a0SZachary Turner //===-- FileCache.cpp -------------------------------------------*- C++ -*-===// 2c00cf4a0SZachary Turner // 3c00cf4a0SZachary Turner // The LLVM Compiler Infrastructure 4c00cf4a0SZachary Turner // 5c00cf4a0SZachary Turner // This file is distributed under the University of Illinois Open Source 6c00cf4a0SZachary Turner // License. See LICENSE.TXT for details. 7c00cf4a0SZachary Turner // 8c00cf4a0SZachary Turner //===----------------------------------------------------------------------===// 9c00cf4a0SZachary Turner 10c00cf4a0SZachary Turner #include "lldb/Host/FileCache.h" 11c00cf4a0SZachary Turner 12c00cf4a0SZachary Turner #include "lldb/Host/File.h" 13*50bc1ed2SJonas Devlieghere #include "lldb/Host/FileSystem.h" 14c00cf4a0SZachary Turner 15c00cf4a0SZachary Turner using namespace lldb; 16c00cf4a0SZachary Turner using namespace lldb_private; 17c00cf4a0SZachary Turner 18c00cf4a0SZachary Turner FileCache *FileCache::m_instance = nullptr; 19c00cf4a0SZachary Turner 20b9c1b51eSKate Stone FileCache &FileCache::GetInstance() { 21c00cf4a0SZachary Turner if (m_instance == nullptr) 22c00cf4a0SZachary Turner m_instance = new FileCache(); 23c00cf4a0SZachary Turner 24c00cf4a0SZachary Turner return *m_instance; 25c00cf4a0SZachary Turner } 26c00cf4a0SZachary Turner 27b9c1b51eSKate Stone lldb::user_id_t FileCache::OpenFile(const FileSpec &file_spec, uint32_t flags, 2897206d57SZachary Turner uint32_t mode, Status &error) { 29*50bc1ed2SJonas Devlieghere if (!file_spec) { 30c00cf4a0SZachary Turner error.SetErrorString("empty path"); 31c00cf4a0SZachary Turner return UINT64_MAX; 32c00cf4a0SZachary Turner } 33c00cf4a0SZachary Turner FileSP file_sp(new File()); 34*50bc1ed2SJonas Devlieghere error = FileSystem::Instance().Open(*file_sp, file_spec, flags, mode); 35c00cf4a0SZachary Turner if (file_sp->IsValid() == false) 36c00cf4a0SZachary Turner return UINT64_MAX; 37c00cf4a0SZachary Turner lldb::user_id_t fd = file_sp->GetDescriptor(); 38c00cf4a0SZachary Turner m_cache[fd] = file_sp; 39c00cf4a0SZachary Turner return fd; 40c00cf4a0SZachary Turner } 41c00cf4a0SZachary Turner 4297206d57SZachary Turner bool FileCache::CloseFile(lldb::user_id_t fd, Status &error) { 43b9c1b51eSKate Stone if (fd == UINT64_MAX) { 44c00cf4a0SZachary Turner error.SetErrorString("invalid file descriptor"); 45c00cf4a0SZachary Turner return false; 46c00cf4a0SZachary Turner } 47c00cf4a0SZachary Turner FDToFileMap::iterator pos = m_cache.find(fd); 48b9c1b51eSKate Stone if (pos == m_cache.end()) { 49c00cf4a0SZachary Turner error.SetErrorStringWithFormat("invalid host file descriptor %" PRIu64, fd); 50c00cf4a0SZachary Turner return false; 51c00cf4a0SZachary Turner } 52c00cf4a0SZachary Turner FileSP file_sp = pos->second; 53b9c1b51eSKate Stone if (!file_sp) { 54c00cf4a0SZachary Turner error.SetErrorString("invalid host backing file"); 55c00cf4a0SZachary Turner return false; 56c00cf4a0SZachary Turner } 57c00cf4a0SZachary Turner error = file_sp->Close(); 58c00cf4a0SZachary Turner m_cache.erase(pos); 59c00cf4a0SZachary Turner return error.Success(); 60c00cf4a0SZachary Turner } 61c00cf4a0SZachary Turner 62b9c1b51eSKate Stone uint64_t FileCache::WriteFile(lldb::user_id_t fd, uint64_t offset, 6397206d57SZachary Turner const void *src, uint64_t src_len, 6497206d57SZachary Turner Status &error) { 65b9c1b51eSKate Stone if (fd == UINT64_MAX) { 66c00cf4a0SZachary Turner error.SetErrorString("invalid file descriptor"); 67c00cf4a0SZachary Turner return UINT64_MAX; 68c00cf4a0SZachary Turner } 69c00cf4a0SZachary Turner FDToFileMap::iterator pos = m_cache.find(fd); 70b9c1b51eSKate Stone if (pos == m_cache.end()) { 71c00cf4a0SZachary Turner error.SetErrorStringWithFormat("invalid host file descriptor %" PRIu64, fd); 72c00cf4a0SZachary Turner return false; 73c00cf4a0SZachary Turner } 74c00cf4a0SZachary Turner FileSP file_sp = pos->second; 75b9c1b51eSKate Stone if (!file_sp) { 76c00cf4a0SZachary Turner error.SetErrorString("invalid host backing file"); 77c00cf4a0SZachary Turner return UINT64_MAX; 78c00cf4a0SZachary Turner } 79b9c1b51eSKate Stone if (static_cast<uint64_t>(file_sp->SeekFromStart(offset, &error)) != offset || 80b9c1b51eSKate Stone error.Fail()) 81c00cf4a0SZachary Turner return UINT64_MAX; 82c00cf4a0SZachary Turner size_t bytes_written = src_len; 83c00cf4a0SZachary Turner error = file_sp->Write(src, bytes_written); 84c00cf4a0SZachary Turner if (error.Fail()) 85c00cf4a0SZachary Turner return UINT64_MAX; 86c00cf4a0SZachary Turner return bytes_written; 87c00cf4a0SZachary Turner } 88c00cf4a0SZachary Turner 89b9c1b51eSKate Stone uint64_t FileCache::ReadFile(lldb::user_id_t fd, uint64_t offset, void *dst, 9097206d57SZachary Turner uint64_t dst_len, Status &error) { 91b9c1b51eSKate Stone if (fd == UINT64_MAX) { 92c00cf4a0SZachary Turner error.SetErrorString("invalid file descriptor"); 93c00cf4a0SZachary Turner return UINT64_MAX; 94c00cf4a0SZachary Turner } 95c00cf4a0SZachary Turner FDToFileMap::iterator pos = m_cache.find(fd); 96b9c1b51eSKate Stone if (pos == m_cache.end()) { 97c00cf4a0SZachary Turner error.SetErrorStringWithFormat("invalid host file descriptor %" PRIu64, fd); 98c00cf4a0SZachary Turner return false; 99c00cf4a0SZachary Turner } 100c00cf4a0SZachary Turner FileSP file_sp = pos->second; 101b9c1b51eSKate Stone if (!file_sp) { 102c00cf4a0SZachary Turner error.SetErrorString("invalid host backing file"); 103c00cf4a0SZachary Turner return UINT64_MAX; 104c00cf4a0SZachary Turner } 105b9c1b51eSKate Stone if (static_cast<uint64_t>(file_sp->SeekFromStart(offset, &error)) != offset || 106b9c1b51eSKate Stone error.Fail()) 107c00cf4a0SZachary Turner return UINT64_MAX; 108c00cf4a0SZachary Turner size_t bytes_read = dst_len; 109c00cf4a0SZachary Turner error = file_sp->Read(dst, bytes_read); 110c00cf4a0SZachary Turner if (error.Fail()) 111c00cf4a0SZachary Turner return UINT64_MAX; 112c00cf4a0SZachary Turner return bytes_read; 113c00cf4a0SZachary Turner } 114