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, Error &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, Error &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, Error &error) { 64 if (fd == UINT64_MAX) { 65 error.SetErrorString("invalid file descriptor"); 66 return UINT64_MAX; 67 } 68 FDToFileMap::iterator pos = m_cache.find(fd); 69 if (pos == m_cache.end()) { 70 error.SetErrorStringWithFormat("invalid host file descriptor %" PRIu64, fd); 71 return false; 72 } 73 FileSP file_sp = pos->second; 74 if (!file_sp) { 75 error.SetErrorString("invalid host backing file"); 76 return UINT64_MAX; 77 } 78 if (static_cast<uint64_t>(file_sp->SeekFromStart(offset, &error)) != offset || 79 error.Fail()) 80 return UINT64_MAX; 81 size_t bytes_written = src_len; 82 error = file_sp->Write(src, bytes_written); 83 if (error.Fail()) 84 return UINT64_MAX; 85 return bytes_written; 86 } 87 88 uint64_t FileCache::ReadFile(lldb::user_id_t fd, uint64_t offset, void *dst, 89 uint64_t dst_len, Error &error) { 90 if (fd == UINT64_MAX) { 91 error.SetErrorString("invalid file descriptor"); 92 return UINT64_MAX; 93 } 94 FDToFileMap::iterator pos = m_cache.find(fd); 95 if (pos == m_cache.end()) { 96 error.SetErrorStringWithFormat("invalid host file descriptor %" PRIu64, fd); 97 return false; 98 } 99 FileSP file_sp = pos->second; 100 if (!file_sp) { 101 error.SetErrorString("invalid host backing file"); 102 return UINT64_MAX; 103 } 104 if (static_cast<uint64_t>(file_sp->SeekFromStart(offset, &error)) != offset || 105 error.Fail()) 106 return UINT64_MAX; 107 size_t bytes_read = dst_len; 108 error = file_sp->Read(dst, bytes_read); 109 if (error.Fail()) 110 return UINT64_MAX; 111 return bytes_read; 112 } 113