FileCache.cpp revision 275072
138363Swpaul//===-- FileCache.cpp -------------------------------------------*- C++ -*-===//
238363Swpaul//
338363Swpaul//                     The LLVM Compiler Infrastructure
438363Swpaul//
538363Swpaul// This file is distributed under the University of Illinois Open Source
638363Swpaul// License. See LICENSE.TXT for details.
738363Swpaul//
838363Swpaul//===----------------------------------------------------------------------===//
938363Swpaul
1038363Swpaul#include "lldb/Host/FileCache.h"
1138363Swpaul
1238363Swpaul#include "lldb/Host/File.h"
1338363Swpaul
1438363Swpaulusing namespace lldb;
1538363Swpaulusing namespace lldb_private;
1638363Swpaul
1738363SwpaulFileCache *FileCache::m_instance = nullptr;
1838363Swpaul
1938363SwpaulFileCache &
2038363SwpaulFileCache::GetInstance()
2138363Swpaul{
2238363Swpaul    if (m_instance == nullptr)
2338363Swpaul        m_instance = new FileCache();
2438363Swpaul
2538363Swpaul    return *m_instance;
2638363Swpaul}
2738363Swpaul
2838363Swpaullldb::user_id_t
2938363SwpaulFileCache::OpenFile(const FileSpec &file_spec, uint32_t flags, uint32_t mode, Error &error)
3038363Swpaul{
3138363Swpaul    std::string path(file_spec.GetPath());
3245629Swpaul    if (path.empty())
3338363Swpaul    {
3438363Swpaul        error.SetErrorString("empty path");
3538363Swpaul        return UINT64_MAX;
3638363Swpaul    }
3738363Swpaul    FileSP file_sp(new File());
3838363Swpaul    error = file_sp->Open(path.c_str(), flags, mode);
3938363Swpaul    if (file_sp->IsValid() == false)
4038363Swpaul        return UINT64_MAX;
4138363Swpaul    lldb::user_id_t fd = file_sp->GetDescriptor();
4238363Swpaul    m_cache[fd] = file_sp;
4338363Swpaul    return fd;
4438363Swpaul}
4538363Swpaul
4638363Swpaulbool
4738363SwpaulFileCache::CloseFile(lldb::user_id_t fd, Error &error)
4838363Swpaul{
4938363Swpaul    if (fd == UINT64_MAX)
5038363Swpaul    {
5138363Swpaul        error.SetErrorString("invalid file descriptor");
5238363Swpaul        return false;
5338363Swpaul    }
5438363Swpaul    FDToFileMap::iterator pos = m_cache.find(fd);
5538363Swpaul    if (pos == m_cache.end())
5638363Swpaul    {
5738363Swpaul        error.SetErrorStringWithFormat("invalid host file descriptor %" PRIu64, fd);
5838363Swpaul        return false;
5938363Swpaul    }
6038363Swpaul    FileSP file_sp = pos->second;
6138363Swpaul    if (!file_sp)
6238363Swpaul    {
6338363Swpaul        error.SetErrorString("invalid host backing file");
6438363Swpaul        return false;
6538363Swpaul    }
6638363Swpaul    error = file_sp->Close();
6738363Swpaul    m_cache.erase(pos);
6838363Swpaul    return error.Success();
6938363Swpaul}
7038363Swpaul
7138363Swpauluint64_t
7238363SwpaulFileCache::WriteFile(lldb::user_id_t fd, uint64_t offset, const void *src, uint64_t src_len, Error &error)
7338363Swpaul{
7438363Swpaul    if (fd == UINT64_MAX)
7538363Swpaul    {
7638363Swpaul        error.SetErrorString("invalid file descriptor");
7738363Swpaul        return UINT64_MAX;
7838363Swpaul    }
7938363Swpaul    FDToFileMap::iterator pos = m_cache.find(fd);
8038363Swpaul    if (pos == m_cache.end())
8138363Swpaul    {
8238363Swpaul        error.SetErrorStringWithFormat("invalid host file descriptor %" PRIu64, fd);
8338363Swpaul        return false;
8438363Swpaul    }
8538363Swpaul    FileSP file_sp = pos->second;
8638363Swpaul    if (!file_sp)
8738363Swpaul    {
8838363Swpaul        error.SetErrorString("invalid host backing file");
8938363Swpaul        return UINT64_MAX;
9038363Swpaul    }
9138363Swpaul    if (static_cast<uint64_t>(file_sp->SeekFromStart(offset, &error)) != offset || error.Fail())
9238363Swpaul        return UINT64_MAX;
9338363Swpaul    size_t bytes_written = src_len;
9438363Swpaul    error = file_sp->Write(src, bytes_written);
9538363Swpaul    if (error.Fail())
9638363Swpaul        return UINT64_MAX;
9738363Swpaul    return bytes_written;
9838363Swpaul}
9938363Swpaul
10038363Swpauluint64_t
10138363SwpaulFileCache::ReadFile(lldb::user_id_t fd, uint64_t offset, void *dst, uint64_t dst_len, Error &error)
10238363Swpaul{
10338363Swpaul    if (fd == UINT64_MAX)
10438363Swpaul    {
10538363Swpaul        error.SetErrorString("invalid file descriptor");
10638363Swpaul        return UINT64_MAX;
10738363Swpaul    }
10838363Swpaul    FDToFileMap::iterator pos = m_cache.find(fd);
10938363Swpaul    if (pos == m_cache.end())
11038363Swpaul    {
11138363Swpaul        error.SetErrorStringWithFormat("invalid host file descriptor %" PRIu64, fd);
11238363Swpaul        return false;
11338363Swpaul    }
11438363Swpaul    FileSP file_sp = pos->second;
11538363Swpaul    if (!file_sp)
11638363Swpaul    {
11738363Swpaul        error.SetErrorString("invalid host backing file");
11838363Swpaul        return UINT64_MAX;
11938363Swpaul    }
12038363Swpaul    if (static_cast<uint64_t>(file_sp->SeekFromStart(offset, &error)) != offset || error.Fail())
12138363Swpaul        return UINT64_MAX;
12238363Swpaul    size_t bytes_read = dst_len;
12338363Swpaul    error = file_sp->Read(dst, bytes_read);
12438363Swpaul    if (error.Fail())
12538363Swpaul        return UINT64_MAX;
12638363Swpaul    return bytes_read;
12738363Swpaul}
12838363Swpaul