Turi Create  4.0
s3_fstream.hpp
1 /* Copyright © 2020 Apple Inc. All rights reserved.
2  *
3  * Use of this source code is governed by a BSD-3-clause license that can
4  * be found in the LICENSE.txt file or at
5  * https://opensource.org/licenses/BSD-3-Clause
6  */
7 #include <boost/iostreams/stream.hpp>
8 #include <core/storage/fileio/read_caching_device.hpp>
9 #include <core/storage/fileio/s3_filesys.hpp>
10 #include <fstream>
11 #include <memory>
12 
13 #ifndef TC_DISABLE_REMOTEFS
14 
15 namespace turi {
16 
17 /**
18  * \ingroup fileio
19  * \internal
20  * s3 file source is used to construct boost iostreams
21  */
22 class s3_device {
23  public: // boost iostream concepts
24  typedef char char_type;
25  struct category : public boost::iostreams::device_tag,
26  public boost::iostreams::multichar_tag,
27  public boost::iostreams::closable_tag,
28  public boost::iostreams::bidirectional_seekable {};
29  // while this claims to be bidirectional_seekable, that is not true
30  // it is only read seekable. Will fail when seeking on write
31  private:
32  std::string remote_fname;
33  std::shared_ptr<fileio::s3::S3FileSystem> m_s3fs;
34  std::shared_ptr<fileio::s3::Stream> m_write_stream;
35  std::shared_ptr<fileio::s3::SeekStream> m_read_stream;
36  size_t m_filesize = (size_t)(-1);
37 
38  public:
39  s3_device() {}
40 
41  ~s3_device();
42 
43  s3_device(const std::string& filename, const bool write = false);
44 
45  // Because the device has bidirectional tag, close will be called
46  // twice, one with the std::ios_base::in, followed by out.
47  // Only close the file when the close tag matches the actual file type.
48  void close(std::ios_base::openmode mode = std::ios_base::openmode());
49 
50  /** the optimal buffer size is 0. */
51  inline std::streamsize optimal_buffer_size() const { return 0; }
52 
53  std::streamsize read(char* strm_ptr, std::streamsize n);
54 
55  std::streamsize write(const char* strm_ptr, std::streamsize n);
56 
57  bool good() const;
58 
59  /**
60  * Seeks to a different location.
61  */
62  std::streampos seek(std::streamoff off, std::ios_base::seekdir way,
63  std::ios_base::openmode);
64 
65  /**
66  * Returns the file size of the opened file.
67  * Returns (size_t)(-1) if there is no file opened, or if there is an
68  * error obtaining the file size.
69  */
70  size_t file_size() const;
71 
72  std::shared_ptr<std::istream> get_underlying_stream();
73  std::string m_filename;
74 }; // end of s3 device
75 
76 typedef boost::iostreams::stream<read_caching_device<s3_device>> s3_fstream;
77 } // namespace turi
78 
79 #endif // End ifndef TC_DISABLE_REMOTEFS
std::streamsize optimal_buffer_size() const
Definition: s3_fstream.hpp:51
std::streampos seek(std::streamoff off, std::ios_base::seekdir way, std::ios_base::openmode)
size_t file_size() const