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