Move FileSystem functions out of Host and into their own classes.

More specifically, this change can be summarized as follows:
1) Makes an lldbHostPosix library which contains code common to
   all posix platforms.
2) Creates Host/FileSystem.h which defines a common FileSystem
   interface.
3) Implements FileSystem.h in Host/windows and Host/posix.
4) Creates Host/FileCache.h, implemented in Host/common, which
   defines a class useful for storing handles to open files needed
   by the debugger.

Differential Revision: http://reviews.llvm.org/D4889

llvm-svn: 215775
diff --git a/lldb/source/Host/common/FileCache.cpp b/lldb/source/Host/common/FileCache.cpp
new file mode 100644
index 0000000..96b2a2e
--- /dev/null
+++ b/lldb/source/Host/common/FileCache.cpp
@@ -0,0 +1,127 @@
+//===-- FileCache.cpp -------------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Host/FileCache.h"
+
+#include "lldb/Host/File.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+FileCache *FileCache::m_instance = nullptr;
+
+FileCache &
+FileCache::GetInstance()
+{
+    if (m_instance == nullptr)
+        m_instance = new FileCache();
+
+    return *m_instance;
+}
+
+lldb::user_id_t
+FileCache::OpenFile(const FileSpec &file_spec, uint32_t flags, uint32_t mode, Error &error)
+{
+    std::string path(file_spec.GetPath());
+    if (path.empty())
+    {
+        error.SetErrorString("empty path");
+        return UINT64_MAX;
+    }
+    FileSP file_sp(new File());
+    error = file_sp->Open(path.c_str(), flags, mode);
+    if (file_sp->IsValid() == false)
+        return UINT64_MAX;
+    lldb::user_id_t fd = file_sp->GetDescriptor();
+    m_cache[fd] = file_sp;
+    return fd;
+}
+
+bool
+FileCache::CloseFile(lldb::user_id_t fd, Error &error)
+{
+    if (fd == UINT64_MAX)
+    {
+        error.SetErrorString("invalid file descriptor");
+        return false;
+    }
+    FDToFileMap::iterator pos = m_cache.find(fd);
+    if (pos == m_cache.end())
+    {
+        error.SetErrorStringWithFormat("invalid host file descriptor %" PRIu64, fd);
+        return false;
+    }
+    FileSP file_sp = pos->second;
+    if (!file_sp)
+    {
+        error.SetErrorString("invalid host backing file");
+        return false;
+    }
+    error = file_sp->Close();
+    m_cache.erase(pos);
+    return error.Success();
+}
+
+uint64_t
+FileCache::WriteFile(lldb::user_id_t fd, uint64_t offset, const void *src, uint64_t src_len, Error &error)
+{
+    if (fd == UINT64_MAX)
+    {
+        error.SetErrorString("invalid file descriptor");
+        return UINT64_MAX;
+    }
+    FDToFileMap::iterator pos = m_cache.find(fd);
+    if (pos == m_cache.end())
+    {
+        error.SetErrorStringWithFormat("invalid host file descriptor %" PRIu64, fd);
+        return false;
+    }
+    FileSP file_sp = pos->second;
+    if (!file_sp)
+    {
+        error.SetErrorString("invalid host backing file");
+        return UINT64_MAX;
+    }
+    if (static_cast<uint64_t>(file_sp->SeekFromStart(offset, &error)) != offset || error.Fail())
+        return UINT64_MAX;
+    size_t bytes_written = src_len;
+    error = file_sp->Write(src, bytes_written);
+    if (error.Fail())
+        return UINT64_MAX;
+    return bytes_written;
+}
+
+uint64_t
+FileCache::ReadFile(lldb::user_id_t fd, uint64_t offset, void *dst, uint64_t dst_len, Error &error)
+{
+    if (fd == UINT64_MAX)
+    {
+        error.SetErrorString("invalid file descriptor");
+        return UINT64_MAX;
+    }
+    FDToFileMap::iterator pos = m_cache.find(fd);
+    if (pos == m_cache.end())
+    {
+        error.SetErrorStringWithFormat("invalid host file descriptor %" PRIu64, fd);
+        return false;
+    }
+    FileSP file_sp = pos->second;
+    if (!file_sp)
+    {
+        error.SetErrorString("invalid host backing file");
+        return UINT64_MAX;
+    }
+    if (static_cast<uint64_t>(file_sp->SeekFromStart(offset, &error)) != offset || error.Fail())
+        return UINT64_MAX;
+    size_t bytes_read = dst_len;
+    error = file_sp->Read(dst, bytes_read);
+    if (error.Fail())
+        return UINT64_MAX;
+    return bytes_read;
+}