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