SLProject  4.2.000
A platform independent 3D computer graphics framework for desktop OS, Android, iOS and online in web browsers
SLFileStorage.cpp
Go to the documentation of this file.
1 /**
2  * \file SLFileStorage.cpp
3  * \date October 2022
4  * \authors Marino von Wattenwyl
5  * \copyright http://opensource.org/licenses/GPL-3.0
6  * \remarks Please use clangformat to format the code. See more code style on
7  * https://github.com/cpvrlab/SLProject4/wiki/SLProject-Coding-Style
8 */
9 
10 #include <SLFileStorage.h>
11 
12 #include <cstring>
13 
14 #if defined(SL_STORAGE_FS)
15 # include <SLIONative.h>
16 #elif defined(SL_STORAGE_WEB)
17 # include <SLIOFetch.h>
18 # include <SLIOMemory.h>
19 # include <SLIOLocalStorage.h>
20 # include <SLIOBrowserPopup.h>
21 #endif
22 
23 //-----------------------------------------------------------------------------
24 //! Creates a copy of the data in the buffer
26 {
27  unsigned char* copy = new unsigned char[size];
28  std::memcpy(copy, data, size);
29  return SLIOBuffer{copy, size};
30 }
31 //-----------------------------------------------------------------------------
32 //! Deallocates the data owned by the buffer
34 {
35  delete[] data;
36 }
37 //-----------------------------------------------------------------------------
38 //! Opens a file stream for I/O operations
39 /*!
40  * Opens a file stream and prepares it for reading or writing. After usage,
41  * the stream should be closed by calling SLFileStorage::close. The function
42  * uses the kind and the mode to determine which kind of stream it should
43  * create. For example, in a web browser, configuration files are written to
44  * local storage.
45  * \param path Path to file
46  * \param kind Kind of file
47  * \param mode Mode to open the stream in
48  * \return Opened stream ready for I/O
49  */
50 SLIOStream* SLFileStorage::open(std::string path,
51  SLIOStreamKind kind,
53 {
54 #if defined(SL_STORAGE_FS)
55  if (mode == IOM_read)
56  return new SLIOReaderNative(path);
57  else if (mode == IOM_write)
58  return new SLIOWriterNative(path);
59  else
60  return nullptr;
61 #elif defined(SL_STORAGE_WEB)
62  Utils::log("I/O", "OPENING \"%s\", (%d)", path.c_str(), kind);
63 
64  if (mode == IOM_read)
65  {
66  if (kind == IOK_shader || kind == IOK_image || kind == IOK_model || kind == IOK_font)
67  {
68  // Shaders, images, models and fonts are always stored on the server.
69  return new SLIOReaderFetch(path);
70  }
71  else if (kind == IOK_config)
72  {
73  // Config files written by the application (e.g. by Dear ImGUI)
74  // are stored in the browsers local storage, other config files
75  // are stored on the server.
76 
77  if (SLIOLocalStorage::exists(path))
78  return new SLIOReaderLocalStorage(path);
79  else
80  return new SLIOReaderFetch(path);
81  }
82  }
83  else if (mode == IOM_write)
84  {
85  // Config files are written to local storage so they can be read when
86  // the website is reloaded, images (e.g. screenshots) are displayed in
87  // the browser window so the user can download them.
88 
89  if (kind == IOK_config)
90  return new SLIOWriterLocalStorage(path);
91  else if (kind == IOK_image)
92  return new SLIOWriterBrowserPopup(path);
93  }
94 
95  return nullptr;
96 #endif
97 }
98 //-----------------------------------------------------------------------------
99 //! Closes and deletes a stream
100 /*!
101  * First flushes the stream to make sure that all data is written and
102  * then deletes it. Implementations of SLIOStream will then close their
103  * backing streams in the destructor.
104  * \param stream Stream to close
105  */
107 {
108  stream->flush();
109  delete stream;
110 }
111 //-----------------------------------------------------------------------------
112 //! Checks whether a given file exists
113 /*!
114  * Checks whether a file exists at the given path and if it is of the given
115  * kind. When running in a web browser, the function may need to communicate
116  * with a server to check whether the file exists, which is quite slow.
117  * \param path Path to file
118  * \param kind Kind of file
119  * \return True if the file exists
120  */
121 bool SLFileStorage::exists(std::string path, SLIOStreamKind kind)
122 {
123 #if defined(SL_STORAGE_FS)
124  return Utils::fileExists(path);
125 #elif defined(SL_STORAGE_WEB)
126  if (path == "")
127  return false;
128 
129  if (kind == IOK_shader)
130  return SLIOReaderFetch::exists(path);
131  else if (kind == IOK_config)
133  else
134  return SLIOReaderFetch::exists(path);
135 #endif
136 }
137 //-----------------------------------------------------------------------------
138 //! Reads an entire file into memory
139 /*!
140  * Opens a stream from the path provided in read mode, allocates a buffer
141  * for its content, reads the content into the buffer and closes the stream.
142  * The buffer is owned by the caller and must be deallocated with a call to
143  * SLFileStorage::deleteBuffer after usage.
144  * \param path Path to the file to read
145  * \param kind Kind of the file to read
146  * \return Buffer holding the file contents and size
147  */
149 {
150  SLIOStream* stream = open(path, kind, IOM_read);
151  size_t size = stream->size();
152  unsigned char* data = new unsigned char[size];
153  stream->read(data, size);
154  close(stream);
155 
156  return SLIOBuffer{data, size};
157 }
158 //-----------------------------------------------------------------------------
159 //! Reads an entire file into a string
160 /*!
161  * Opens a stream from the path provided in read mode, allocates a strings
162  * for its content, reads the content into the string and closes the stream.
163  * Line endings are NOT converted to LF, which means that on Windows, the
164  * string may contain CRLF line endings.
165  * \param path Path to the file to read
166  * \param kind Kind of the file to read
167  * \return String containing the contents of the file
168  */
169 std::string SLFileStorage::readIntoString(std::string path, SLIOStreamKind kind)
170 {
171  SLIOStream* stream = open(path, kind, IOM_read);
172  size_t size = stream->size();
173  std::string string;
174  string.resize(size);
175  stream->read((void*)string.data(), size);
176  close(stream);
177 
178  return string;
179 }
180 //-----------------------------------------------------------------------------
181 //! Writes a string to a file
182 /*!
183  * Opens a stream to the path provided in write mode, writes the string to
184  * the file and closes the stream. Line endings are NOT converted to LF,
185  * which means that on Windows, the file may contain LF line endings after
186  * writing instead of CRLF line endings.
187  * \param path The path to the file to write to
188  * \param kind The kind of the file to write to
189  * \param string The string to write to the file
190  */
191 void SLFileStorage::writeString(std::string path,
192  SLIOStreamKind kind,
193  const std::string& string)
194 {
195  SLIOStream* stream = open(path, kind, IOM_write);
196  stream->write(string.c_str(), string.size());
197  close(stream);
198 }
199 //-----------------------------------------------------------------------------
SLIOStreamMode
Enum of stream opening modes.
Definition: SLFileStorage.h:49
@ IOM_read
Definition: SLFileStorage.h:50
@ IOM_write
Definition: SLFileStorage.h:51
SLIOStreamKind
Enum of file kinds.
Definition: SLFileStorage.h:38
@ IOK_font
Definition: SLFileStorage.h:43
@ IOK_config
Definition: SLFileStorage.h:44
@ IOK_image
Definition: SLFileStorage.h:40
@ IOK_shader
Definition: SLFileStorage.h:42
@ IOK_model
Definition: SLFileStorage.h:41
static WAI::ModeOrbSlam2 * mode
Definition: WAIInterface.cpp:5
SLIOStream implementation for downloading files from a web server.
Definition: SLIOFetch.h:25
static bool exists(std::string url)
Definition: SLIOFetch.cpp:19
SLIOStream implementation for reading from browser local storage.
SLIOStream implementation for reading from native files.
Definition: SLIONative.h:19
Interface for accessing external data using streams.
Definition: SLFileStorage.h:62
virtual void flush()
Definition: SLFileStorage.h:77
virtual size_t write(const void *buffer, size_t size)
Definition: SLFileStorage.h:73
virtual size_t read(void *buffer, size_t size)
Definition: SLFileStorage.h:72
virtual size_t size()
Definition: SLFileStorage.h:76
SLIOStream implementation to display PNG files in a browser popup.
SLIOStream implementation for writing to browser local storage.
SLIOStream implementation for writing to native files.
Definition: SLIONative.h:33
void close(SLIOStream *stream)
Closes and deletes a stream.
SLIOBuffer readIntoBuffer(std::string path, SLIOStreamKind kind)
Reads an entire file into memory.
bool exists(std::string path, SLIOStreamKind kind)
Checks whether a given file exists.
SLIOStream * open(std::string path, SLIOStreamKind kind, SLIOStreamMode mode)
Opens a file stream for I/O operations.
std::string readIntoString(std::string path, SLIOStreamKind kind)
Reads an entire file into a string.
void writeString(std::string path, SLIOStreamKind kind, const std::string &string)
Writes a string to a file.
bool exists(std::string path)
bool fileExists(const string &pathfilename)
Returns true if a file exists.
Definition: Utils.cpp:897
void log(const char *tag, const char *format,...)
logs a formatted string platform independently
Definition: Utils.cpp:1103
Utility struct that holds a pointer and its length.
Definition: SLFileStorage.h:28
SLIOBuffer copy()
Creates a copy of the data in the buffer.
void deallocate()
Deallocates the data owned by the buffer.
size_t size
Definition: SLFileStorage.h:30
unsigned char * data
Definition: SLFileStorage.h:29