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 & 20 FileCache::GetInstance() 21 { 22 if (m_instance == nullptr) 23 m_instance = new FileCache(); 24 25 return *m_instance; 26 } 27 28 lldb::user_id_t 29 FileCache::OpenFile(const FileSpec &file_spec, uint32_t flags, uint32_t mode, Error &error) 30 { 31 std::string path(file_spec.GetPath()); 32 if (path.empty()) 33 { 34 error.SetErrorString("empty path"); 35 return UINT64_MAX; 36 } 37 FileSP file_sp(new File()); 38 error = file_sp->Open(path.c_str(), flags, mode); 39 if (file_sp->IsValid() == false) 40 return UINT64_MAX; 41 lldb::user_id_t fd = file_sp->GetDescriptor(); 42 m_cache[fd] = file_sp; 43 return fd; 44 } 45 46 bool 47 FileCache::CloseFile(lldb::user_id_t fd, Error &error) 48 { 49 if (fd == UINT64_MAX) 50 { 51 error.SetErrorString("invalid file descriptor"); 52 return false; 53 } 54 FDToFileMap::iterator pos = m_cache.find(fd); 55 if (pos == m_cache.end()) 56 { 57 error.SetErrorStringWithFormat("invalid host file descriptor %" PRIu64, fd); 58 return false; 59 } 60 FileSP file_sp = pos->second; 61 if (!file_sp) 62 { 63 error.SetErrorString("invalid host backing file"); 64 return false; 65 } 66 error = file_sp->Close(); 67 m_cache.erase(pos); 68 return error.Success(); 69 } 70 71 uint64_t 72 FileCache::WriteFile(lldb::user_id_t fd, uint64_t offset, const void *src, uint64_t src_len, Error &error) 73 { 74 if (fd == UINT64_MAX) 75 { 76 error.SetErrorString("invalid file descriptor"); 77 return UINT64_MAX; 78 } 79 FDToFileMap::iterator pos = m_cache.find(fd); 80 if (pos == m_cache.end()) 81 { 82 error.SetErrorStringWithFormat("invalid host file descriptor %" PRIu64, fd); 83 return false; 84 } 85 FileSP file_sp = pos->second; 86 if (!file_sp) 87 { 88 error.SetErrorString("invalid host backing file"); 89 return UINT64_MAX; 90 } 91 if (static_cast<uint64_t>(file_sp->SeekFromStart(offset, &error)) != offset || error.Fail()) 92 return UINT64_MAX; 93 size_t bytes_written = src_len; 94 error = file_sp->Write(src, bytes_written); 95 if (error.Fail()) 96 return UINT64_MAX; 97 return bytes_written; 98 } 99 100 uint64_t 101 FileCache::ReadFile(lldb::user_id_t fd, uint64_t offset, void *dst, uint64_t dst_len, Error &error) 102 { 103 if (fd == UINT64_MAX) 104 { 105 error.SetErrorString("invalid file descriptor"); 106 return UINT64_MAX; 107 } 108 FDToFileMap::iterator pos = m_cache.find(fd); 109 if (pos == m_cache.end()) 110 { 111 error.SetErrorStringWithFormat("invalid host file descriptor %" PRIu64, fd); 112 return false; 113 } 114 FileSP file_sp = pos->second; 115 if (!file_sp) 116 { 117 error.SetErrorString("invalid host backing file"); 118 return UINT64_MAX; 119 } 120 if (static_cast<uint64_t>(file_sp->SeekFromStart(offset, &error)) != offset || error.Fail()) 121 return UINT64_MAX; 122 size_t bytes_read = dst_len; 123 error = file_sp->Read(dst, bytes_read); 124 if (error.Fail()) 125 return UINT64_MAX; 126 return bytes_read; 127 } 128