FileCache.cpp revision 344779
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#include "lldb/Host/FileSystem.h"
14
15using namespace lldb;
16using namespace lldb_private;
17
18FileCache *FileCache::m_instance = nullptr;
19
20FileCache &FileCache::GetInstance() {
21  if (m_instance == nullptr)
22    m_instance = new FileCache();
23
24  return *m_instance;
25}
26
27lldb::user_id_t FileCache::OpenFile(const FileSpec &file_spec, uint32_t flags,
28                                    uint32_t mode, Status &error) {
29  if (!file_spec) {
30    error.SetErrorString("empty path");
31    return UINT64_MAX;
32  }
33  FileSP file_sp(new File());
34  error = FileSystem::Instance().Open(*file_sp, file_spec, flags, mode);
35  if (!file_sp->IsValid())
36    return UINT64_MAX;
37  lldb::user_id_t fd = file_sp->GetDescriptor();
38  m_cache[fd] = file_sp;
39  return fd;
40}
41
42bool 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
62uint64_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
89uint64_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