openMSX
LocalFileReference.cc
Go to the documentation of this file.
1 #include "LocalFileReference.hh"
2 #include "File.hh"
3 #include "Filename.hh"
4 #include "FileOperations.hh"
5 #include "FileException.hh"
6 #include "build-info.hh"
7 #include <cstdio>
8 #include <cassert>
9 
10 namespace openmsx {
11 
13 {
14  init(file);
15 }
16 
18 {
19  File file(std::move(filename));
20  init(file);
21 }
22 
24  : LocalFileReference(filename.getResolved())
25 {
26 }
27 
29  : LocalFileReference(std::move(filename).getResolved())
30 {
31 }
32 
34  : tmpFile(std::move(other.tmpFile))
35  , tmpDir (std::move(other.tmpDir ))
36 {
37  other.tmpDir.clear();
38 }
39 
41 {
42  cleanup();
43  tmpFile = std::move(other.tmpFile);
44  tmpDir = std::move(other.tmpDir);
45  other.tmpDir.clear();
46  return *this;
47 }
48 
50 {
51  cleanup();
52 }
53 
54 void LocalFileReference::init(File& file)
55 {
56  tmpFile = file.getLocalReference();
57  if (!tmpFile.empty()) {
58  // file is backed on the (local) filesystem,
59  // we can simply use the path to that file
60  assert(tmpDir.empty()); // no need to delete file/dir later
61  return;
62  }
63 
64  // create temp dir
65 #if defined(_WIN32) || PLATFORM_ANDROID
67 #else
68  // TODO - why not just use getTempDir()?
69  tmpDir = strCat("/tmp/openmsx.", int(getpid()));
70 #endif
71  // it's possible this directory already exists, in that case the
72  // following function does nothing
73  FileOperations::mkdirp(tmpDir);
74 
75  // create temp file
76  auto fp = FileOperations::openUniqueFile(tmpDir, tmpFile);
77  if (!fp) {
78  throw FileException("Couldn't create temp file");
79  }
80 
81  // write temp file
82  auto mmap = file.mmap();
83  if (fwrite(mmap.data(), 1, mmap.size(), fp.get()) != mmap.size()) {
84  throw FileException("Couldn't write temp file");
85  }
86 }
87 
88 void LocalFileReference::cleanup()
89 {
90  if (!tmpDir.empty()) {
91  FileOperations::unlink(tmpFile);
92  // it's possible the directory is not empty, in that case
93  // the following function will fail, we ignore that error
94  FileOperations::rmdir(tmpDir);
95  }
96 }
97 
98 const std::string& LocalFileReference::getFilename() const
99 {
100  assert(!tmpFile.empty());
101  return tmpFile;
102 }
103 
104 } // namespace openmsx
span< const uint8_t > mmap()
Map file in memory.
Definition: File.cc:103
This class represents a filename.
Definition: Filename.hh:18
Helper class to use files in APIs other than openmsx::File.
LocalFileReference & operator=(const LocalFileReference &)=delete
const std::string & getFilename() const
Returns path to a local uncompressed version of this file.
FILE_t openUniqueFile(const std::string &directory, std::string &filename)
Open a new file with a unique name in the provided directory.
int rmdir(zstring_view path)
Call rmdir() in a platform-independent manner.
string getTempDir()
Get the name of the temp directory on the system.
void mkdirp(string path)
Acts like the unix command "mkdir -p".
int unlink(zstring_view path)
Call unlink() in a platform-independent manner.
This file implemented 3 utility functions:
Definition: Autofire.cc:9
constexpr const char *const filename
std::string strCat(Ts &&...ts)
Definition: strCat.hh:591