libkazv
asio-std-file-handler.hpp
Go to the documentation of this file.
1 /*
2  * This file is part of libkazv.
3  * SPDX-FileCopyrightText: 2021 Tusooa Zhu <tusooa@kazv.moe>
4  * SPDX-License-Identifier: AGPL-3.0-or-later
5  */
6 
7 
8 #pragma once
9 #include "libkazv-config.hpp"
10 
11 #include <fstream>
12 
13 #include <boost/asio.hpp>
14 
15 #include "file-desc.hpp"
16 
17 namespace Kazv
18 {
19  template<class Exec>
21  {
22  public:
23  using DataT = FileContent;
31  inline AsioStdFileStream(Exec exec, std::string filename, FileOpenMode mode)
32  : m_executor(exec)
33  , m_filename(filename)
34  , m_mode(mode)
35  , m_stream(std::make_shared<std::fstream>(
36  m_filename,
37  (m_mode == FileOpenMode::Read
38  ? std::ios_base::in
39  : std::ios_base::out)
40  | std::ios_base::binary))
41  {}
42 
43  inline bool valid() { return !!m_stream; }
44 
45  template<class Callback>
46  void read(int maxSize, Callback readCallback) {
47  boost::asio::post(
48  m_executor,
49  [stream=m_stream, maxSize, readCallback=std::move(readCallback)]() {
50  auto buf = std::vector<char>(maxSize, '\0');
51  auto data = FileContent{};
52  auto actualSize = int{};
53 
54  try {
55  stream->read(buf.data(), maxSize);
56 
57  actualSize = stream->gcount();
58 
59  data = FileContent(buf.begin(), buf.begin() + actualSize);
60  } catch (const std::exception &) {
61  readCallback(FileOpRetCode::Error, FileContent{});
62  return;
63  }
64 
65  if (actualSize > 0) {
66  readCallback(FileOpRetCode::Success, data);
67  } else if (stream->eof()) {
68  readCallback(FileOpRetCode::Eof, FileContent{});
69  } else {
70  readCallback(FileOpRetCode::Error, FileContent{});
71  }
72  });
73  }
74 
75  template<class Callback>
76  void write(DataT data, Callback writeCallback) {
77  boost::asio::post(
78  m_executor,
79  [stream=m_stream, data, writeCallback=std::move(writeCallback)]() {
80  try {
81  auto buf = std::vector<char>(data.begin(), data.end());
82  stream->write(buf.data(), buf.size());
83  } catch (const std::exception &) {
84  writeCallback(FileOpRetCode::Error, 0);
85  return;
86  }
87 
88  if (stream->bad()) {
89  writeCallback(FileOpRetCode::Error, 0);
90  } else {
91  writeCallback(FileOpRetCode::Success, data.size());
92  }
93  });
94  }
95 
96  private:
97  Exec m_executor;
98  std::string m_filename;
99  FileOpenMode m_mode;
100  std::shared_ptr<std::fstream> m_stream;
101  };
102 
103  template<class Exec>
105  {
106  public:
108 
116  inline AsioStdFileProvider(Exec exec, std::string filename)
117  : m_executor(exec)
118  , m_filename(filename)
119  {}
120 
127  return FileStreamT(m_executor, m_filename, mode);
128  }
129 
130  private:
131  Exec m_executor;
132  std::string m_filename;
133  };
134 
135  template<class Exec>
137  {
138  public:
140 
147  inline AsioStdFileHandler(Exec exec)
148  : m_executor(exec)
149  {}
150 
158  // assert(desc.name())
159  return FileProviderT(m_executor, desc.name().value());
160  }
161  private:
162  Exec m_executor;
163  };
164 
165  template<class Exec>
166  AsioStdFileHandler(Exec)->AsioStdFileHandler<Exec>;
167 }
Kazv::AsioStdFileStream::read
void read(int maxSize, Callback readCallback)
Definition: asio-std-file-handler.hpp:46
Kazv::FileOpRetCode::Eof
@ Eof
Kazv::AsioStdFileProvider
Definition: asio-std-file-handler.hpp:104
Kazv::AsioStdFileStream::AsioStdFileStream
AsioStdFileStream(Exec exec, std::string filename, FileOpenMode mode)
Constructor.
Definition: asio-std-file-handler.hpp:31
Kazv::AsioStdFileHandler
Definition: asio-std-file-handler.hpp:136
Kazv::AsioStdFileProvider::getStream
FileStreamT getStream(FileOpenMode mode) const
Get the FileStream provided by this.
Definition: asio-std-file-handler.hpp:126
Kazv::FileOpenMode::Read
@ Read
Kazv::AsioStdFileHandler
AsioStdFileHandler(Exec) -> AsioStdFileHandler< Exec >
file-desc.hpp
Kazv::FileOpRetCode::Error
@ Error
Kazv
Definition: location.hpp:10
Kazv::AsioStdFileStream::valid
bool valid()
Definition: asio-std-file-handler.hpp:43
Kazv::AsioStdFileHandler::FileProviderT
AsioStdFileProvider< Exec > FileProviderT
Definition: asio-std-file-handler.hpp:139
Kazv::AsioStdFileStream::DataT
FileContent DataT
Definition: asio-std-file-handler.hpp:23
Kazv::AsioStdFileProvider::AsioStdFileProvider
AsioStdFileProvider(Exec exec, std::string filename)
Constructor.
Definition: asio-std-file-handler.hpp:116
Kazv::AsioStdFileHandler::getProviderFor
FileProviderT getProviderFor(FileDesc desc) const
Get the FileProvider for desc.
Definition: asio-std-file-handler.hpp:157
Kazv::FileContent
immer::flex_vector< char > FileContent
Definition: file-desc.hpp:33
Kazv::FileOpenMode
FileOpenMode
Definition: file-desc.hpp:27
Kazv::FileDesc::name
std::optional< std::string > name() const
Get the name for this FileDesc.
Definition: file-desc.hpp:258
Kazv::AsioStdFileStream::write
void write(DataT data, Callback writeCallback)
Definition: asio-std-file-handler.hpp:76
Kazv::FileOpRetCode::Success
@ Success
Kazv::AsioStdFileProvider::FileStreamT
AsioStdFileStream< Exec > FileStreamT
Definition: asio-std-file-handler.hpp:107
std
Definition: clientutil.hpp:216
Kazv::FileDesc
Definition: file-desc.hpp:224
libkazv-config.hpp
Kazv::AsioStdFileStream
Definition: asio-std-file-handler.hpp:20
Kazv::AsioStdFileHandler::AsioStdFileHandler
AsioStdFileHandler(Exec exec)
Constructor.
Definition: asio-std-file-handler.hpp:147