Remote Call Framework 3.4
FileStream.hpp
Go to the documentation of this file.
1 
2 //******************************************************************************
3 // RCF - Remote Call Framework
4 //
5 // Copyright (c) 2005 - 2023, Delta V Software. All rights reserved.
6 // https://www.deltavsoft.com
7 //
8 // RCF is distributed under dual licenses - closed source or GPL.
9 // Consult your particular license for conditions of use.
10 //
11 // If you have not purchased a commercial license, you are using RCF under GPL terms.
12 //
13 // Version: 3.4
14 // Contact: support <at> deltavsoft.com
15 //
16 //******************************************************************************
17 
19 
20 #ifndef INCLUDE_RCF_FILESTREAM_HPP
21 #define INCLUDE_RCF_FILESTREAM_HPP
22 
23 #include <RCF/Config.hpp>
24 
25 #if RCF_FEATURE_FILETRANSFER==0
26 #error RCF_FEATURE_FILETRANSFER=1 must be defined
27 #endif
28 
29 #include <RCF/ByteBuffer.hpp>
30 #include <RCF/Exception.hpp>
31 #include <RCF/FileSystem.hpp>
32 #include <RCF/Export.hpp>
33 #include <RCF/RcfFwd.hpp>
34 #include <RCF/ThreadLibrary.hpp>
35 #include <RCF/Tools.hpp>
36 
37 #include <functional>
38 #include <set>
39 #include <stdio.h>
40 
41 #if RCF_FEATURE_BOOST_SERIALIZATION==1
42 #include <boost/serialization/vector.hpp>
43 #include <boost/serialization/shared_ptr.hpp>
44 #endif
45 
46 namespace SF {
47 
48  class Archive;
49 
50 } // namespace SF
51 
52 namespace RCF {
53 
54  class RCF_EXPORT FileHandle
55  {
56  public:
57 
58  enum OpenMode
59  {
60  Read,
61  WriteTruncate,
62  WriteAppend,
63  };
64 
65  FileHandle();
66  FileHandle(const Path& filePath, OpenMode mode);
67  ~FileHandle();
68 
69  void open(const Path& filePath, OpenMode mode);
70  void close();
71  void flush();
72  void seek(std::uint64_t newPos);
73  std::uint64_t tell();
74 
75  std::size_t read(const ByteBuffer& buffer);
76  std::size_t write(const ByteBuffer& buffer);
77 
78  Exception err() const;
79 
80  Path getFilePath();
81 
82  private:
83 
84  FILE * mpFile = NULL;
85  Path mFilePath;
86  OpenMode mOpenMode = Read;
87  std::size_t mBeginPos = 0;
88  Exception mErr;
89  };
90 
91  typedef std::shared_ptr< FileHandle > FileHandlePtr;
92 
93  class FileUploadInfo;
94  typedef std::shared_ptr<FileUploadInfo> FileUploadInfoPtr;
95 
96  class FileInfo;
97  class FileManifest;
98  class FileStreamImpl;
99 
100  typedef std::shared_ptr<FileStreamImpl> FileStreamImplPtr;
101 
102  class ClientStub;
103 
104  class RCF_EXPORT FileInfo
105  {
106  public:
107  FileInfo();
108 
109  bool mIsDirectory;
110  Path mFilePath;
111  std::uint64_t mFileStartPos;
112  std::uint64_t mFileSize;
113  std::uint32_t mFileCrc;
114  std::string mRenameFile;
115  std::uint64_t mLastWriteTime;
116 
117 #if RCF_FEATURE_SF==1
118  void serialize(SF::Archive & ar);
119 #endif
120 
121 #if RCF_FEATURE_BOOST_SERIALIZATION==1
122  template<typename Archive>
123  void serialize(Archive & ar, const unsigned int)
124  {
125  RCF_UNUSED_VARIABLE(ar);
126  RCF_THROW(Exception(RcfError_BSerFileTransferNotSupported));
127  }
128 #endif
129 
130  };
131 
132  class RCF_EXPORT FileManifest
133  {
134  public:
135  typedef std::vector< FileInfo > Files;
136  Files mFiles;
137 
138  Path mManifestBase;
139 
140  FileManifest();
141 
142  FileManifest(const Path& pathToFiles);
143 
144  std::uint64_t getTotalByteSize() const;
145 
146 #if RCF_FEATURE_SF==1
147  void serialize(SF::Archive & ar);
148 #endif
149 
150 #if RCF_FEATURE_BOOST_SERIALIZATION==1
151  template<typename Archive>
152  void serialize(Archive & ar, const unsigned int)
153  {
154  RCF_UNUSED_VARIABLE(ar);
155  RCF_THROW(Exception(RcfError_BSerFileTransferNotSupported));
156  }
157 #endif
158 
159  };
160 
161  class RCF_EXPORT FileStreamImpl : public std::enable_shared_from_this<FileStreamImpl>
162  {
163  public:
164 
165  enum Direction
166  {
167  Unspecified,
168  Upload,
169  Download
170  };
171 
172 
173  FileStreamImpl();
174  FileStreamImpl(const std::string & filePath);
175  FileStreamImpl(const FileManifest & manifest);
176 
177  ~FileStreamImpl();
178 
179  void serializeGeneric(
180  bool isWriting,
181  std::function<void(std::uint32_t &, Direction &)> serializeImpl);
182 
183 #if RCF_FEATURE_SF==1
184  void serializeImplSf(SF::Archive & ar, std::uint32_t & transferId, Direction & dir);
185  void serialize(SF::Archive & ar);
186 #endif
187 
188 #if RCF_FEATURE_BOOST_SERIALIZATION==1
189 
190  template<typename Archive>
191  void serializeImplBser(Archive & ar, std::uint32_t & transferId, Direction & dir)
192  {
193  ar & transferId & dir;
194  }
195 
196  template<typename Archive>
197  void serialize(Archive & ar, const unsigned int)
198  {
199  RCF_UNUSED_VARIABLE(ar);
200  RCF_THROW(Exception(RcfError_BSerFileTransferNotSupported));
201  }
202 
203 #endif
204 
205  std::string mUploadId;
206  Path mDownloadToPath;
207  FileManifest mManifest;
208  std::uint32_t mTransferRateBps;
209  std::uint32_t mSessionLocalId;
210 
211  Direction mDirection;
212  };
213 
214  class RCF_EXPORT FileStream
215  {
216  protected:
217 
218  FileStream();
219  FileStream(FileStreamImplPtr implPtr);
220  FileStream(const std::string & filePath);
221  FileStream(const FileManifest & manifest);
222 
223  public:
224 
225  // Made this inline as it was not being linked in, in DLL builds.
226  FileStream & operator=(const FileStream & rhs)
227  {
228  *mImplPtr = *rhs.mImplPtr;
229  return *this;
230  }
231 
232  // FileStream recipient calls these.
233  std::string getLocalPath() const;
234  FileManifest & getManifest() const;
235 
236  // Client calls these.
237  void setDownloadToPath(const std::string & downloadToPath);
238  std::string getDownloadToPath() const;
239 
240  void setTransferRateBps(std::uint32_t transferRateBps);
241  std::uint32_t getTransferRateBps();
242 
243  void upload(RCF::ClientStub & clientStub);
244  void download(RCF::ClientStub & clientStub);
245 
246 
247  FileStreamImplPtr mImplPtr;
248 
249 #if RCF_FEATURE_SF==1
250  void serialize(SF::Archive & ar);
251 #endif
252 
253 #if RCF_FEATURE_BOOST_SERIALIZATION==1
254  template<typename Archive>
255  void serialize(Archive & ar, const unsigned int)
256  {
257  RCF_UNUSED_VARIABLE(ar);
258  RCF_THROW(Exception(RcfError_BSerFileTransferNotSupported));
259  }
260 #endif
261 
262  };
263 
266  {
267  public:
268 
270 
273 
275  std::uint64_t mBytesTotalToTransfer;
276 
278  std::uint64_t mBytesTransferredSoFar;
279 
281  std::uint32_t mServerLimitBps;
282  };
283 
284  class FileChunk
285  {
286  public:
287 
288  FileChunk();
289 
290  bool isEmpty() const;
291 
292  std::uint32_t mFileIndex;
293  std::uint64_t mOffset;
294  ByteBuffer mData;
295 
296 #if RCF_FEATURE_SF==1
297  void serialize(SF::Archive & ar);
298 #endif
299 
300 #if RCF_FEATURE_BOOST_SERIALIZATION==1
301  template<typename Archive>
302  void serialize(Archive & ar, const unsigned int)
303  {
304  RCF_UNUSED_VARIABLE(ar);
305  RCF_THROW(Exception(RcfError_BSerFileTransferNotSupported));
306  }
307 #endif
308 
309  };
310 
311  class FileTransferRequest
312  {
313  public:
314  FileTransferRequest();
315 
316  std::uint32_t mFile;
317  std::uint64_t mPos;
318  std::uint32_t mChunkSize;
319 
320 #if RCF_FEATURE_SF==1
321  void serialize(SF::Archive & ar);
322 #endif
323 
324 #if RCF_FEATURE_BOOST_SERIALIZATION==1
325  template<typename Archive>
326  void serialize(Archive & ar, const unsigned int)
327  {
328  RCF_UNUSED_VARIABLE(ar);
329  RCF_THROW(Exception(RcfError_BSerFileTransferNotSupported));
330  }
331 #endif
332 
333  };
334 
336  class RCF_EXPORT BandwidthQuota : Noncopyable
337  {
338  public:
339 
340  BandwidthQuota();
341 
343  BandwidthQuota(std::uint32_t quotaBps);
344 
346  void setQuota(std::uint32_t quotaBps);
347 
348  std::uint32_t calculateLineSpeedLimit();
349 
350  private:
351 
352  friend class FileUploadInfo;
353  friend class FileDownloadInfo;
354 
355  void addUpload(FileUploadInfo * pUpload);
356  void removeUpload(FileUploadInfo * pUpload);
357  void addDownload(FileDownloadInfo * pDownload);
358  void removeDownload(FileDownloadInfo * pDownload);
359 
360  private:
361 
362  Mutex mMutex;
363  std::uint32_t mQuotaBps;
364 
365  std::set<FileDownloadInfo *> mDownloadsInProgress;
366  std::set<FileUploadInfo *> mUploadsInProgress;
367  };
368 
371  {
372  public:
373 
375  std::uint32_t mBandwidthLimitBps = 0;
376 
379 
381  std::uint64_t mStartPos = 0;
382 
384  std::uint64_t mEndPos = 0;
385 
388 
389  // For test purposes.
390  std::uint32_t mChunkSize = 0;
391  };
392 
393 
394 } // namespace RCF
395 
396 #endif // ! INCLUDE_RCF_FILESTREAM_HPP
Represents an archive, in which serialized objects are stored.
Definition: Archive.hpp:31
RCF_FILESYSTEM_NS::path Path
Typedef for standard C++ path type.
Definition: FileSystem.hpp:31
FileProgressCallback mProgressCallback
Progress callback. Called during the transfer to provide progress information.
Definition: FileStream.hpp:387
Path mDownloadPath
Local path a file is being downloaded to. Only relevant to downloads.
Definition: FileStream.hpp:272
Client side options for downloading and uploading files.
Definition: FileStream.hpp:370
std::shared_ptr< BandwidthQuota > BandwidthQuotaPtr
Reference counted wrapper for RCF::BandwidthQuota.
Definition: RcfFwd.hpp:127
Controls the client side of a RCF connection.
Definition: ClientStub.hpp:82
Server-side information about a file download taking place from a RcfServer.
Definition: FileTransferService.hpp:97
Base class for all RCF exceptions.
Definition: Exception.hpp:67
std::function< void(const FileTransferProgress &, RemoteCallAction &)> FileProgressCallback
Describes user-provided callback functions for client-side monitoring of a file transfer (download or...
Definition: RcfFwd.hpp:131
Definition: ByteBuffer.hpp:188
BandwidthQuotaPtr mBandwidthQuotaPtr
Bandwidth quota associated with the transfer.
Definition: FileStream.hpp:378
Describes a unit of bandwidth, to be used by downloads or uploads, for a single connection or a group...
Definition: FileStream.hpp:336
std::uint64_t mBytesTotalToTransfer
Total number of bytes that are to be transferred.
Definition: FileStream.hpp:275
Definition: ByteBuffer.hpp:39
Definition: AmiIoHandler.hpp:23
Server-side information about a file upload taking place to a RcfServer.
Definition: FileTransferService.hpp:65
std::uint64_t mBytesTransferredSoFar
Bytes that have been transferred so far.
Definition: FileStream.hpp:278
Describes progress of a file download or upload.
Definition: FileStream.hpp:265
std::uint32_t mServerLimitBps
Bandwidth limit (bytes per second) imposed by server, if any.
Definition: FileStream.hpp:281