RCFProto
 All Classes Functions Typedefs
FileTransferService.hpp
1 
2 //******************************************************************************
3 // RCF - Remote Call Framework
4 //
5 // Copyright (c) 2005 - 2013, 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: 2.0
15 // Contact: support <at> deltavsoft.com
16 //
17 //******************************************************************************
18 
19 #ifndef INCLUDE_RCF_FILETRANSFERSERVICE_HPP
20 #define INCLUDE_RCF_FILETRANSFERSERVICE_HPP
21 
22 #include <fstream>
23 #include <map>
24 #include <set>
25 
26 #include <RCF/FileStream.hpp>
27 #include <RCF/RcfSession.hpp>
28 #include <RCF/Service.hpp>
29 
30 #include <SF/vector.hpp>
31 #include <SF/map.hpp>
32 
33 #include <boost/filesystem/path.hpp>
34 
35 #if RCF_FEATURE_SF==1
36 
37 namespace SF {
38 
39  RCF_EXPORT void serialize(SF::Archive &ar, boost::filesystem::path &p);
40 
41 } // namespace SF
42 
43 #endif
44 
45 #if RCF_FEATURE_BOOST_SERIALIZATION==1
46 
47 #include <boost/config.hpp>
48 #include <boost/version.hpp>
49 
50 #if BOOST_VERSION <= 104300
51 #define BOOST_FS_NAMESPACE filesystem
52 #elif BOOST_VERSION <= 104500
53 #define BOOST_FS_NAMESPACE filesystem2
54 #else
55 #define BOOST_FS_NAMESPACE filesystem3
56 #endif
57 
58 namespace boost { namespace BOOST_FS_NAMESPACE {
59 
60  template<typename Archive>
61  void serialize(Archive & ar, boost::BOOST_FS_NAMESPACE::path & p, const unsigned int)
62  {
63  typedef typename Archive::is_saving IsSaving;
64  const bool isSaving = IsSaving::value;
65 
66  if (isSaving)
67  {
68  std::string s = p.string();
69  ar & s;
70  }
71  else
72  {
73  std::string s;
74  ar & s;
75  p = path(s);
76  }
77  }
78 
79 } }
80 
81 #undef BOOST_FS_NAMESPACE
82 
83 #endif
84 
85 namespace RCF {
86 
87  std::string nativeString(const boost::filesystem::path & p);
88 
89  class FileTransferService;
90 
91  class FileUploadInfo;
92  class FileDownloadInfo;
93 
94  class RCF_EXPORT BandwidthQuota : boost::noncopyable
95  {
96  public:
97  BandwidthQuota();
98  BandwidthQuota(boost::uint32_t quotaBps);
99 
100  void setQuota(boost::uint32_t quotaBps);
101  boost::uint32_t calculateLineSpeedLimit();
102 
103  private:
104 
105  friend class FileUploadInfo;
106  friend class FileDownloadInfo;
107 
108  void addUpload(FileUploadInfo * pUpload);
109  void removeUpload(FileUploadInfo * pUpload);
110  void addDownload(FileDownloadInfo * pDownload);
111  void removeDownload(FileDownloadInfo * pDownload);
112 
113  private:
114 
115  Mutex mMutex;
116  boost::uint32_t mQuotaBps;
117 
118  std::set<FileDownloadInfo *> mDownloadsInProgress;
119  std::set<FileUploadInfo *> mUploadsInProgress;
120  };
121 
122  typedef boost::shared_ptr<BandwidthQuota> BandwidthQuotaPtr;
123 
124 
125  class FileUploadInfo;
126  class FileDownloadInfo;
127 
128  typedef boost::shared_ptr<FileUploadInfo> FileUploadInfoPtr;
129  typedef boost::shared_ptr<FileDownloadInfo> FileDownloadInfoPtr;
130 
131  typedef boost::function1<bool, const FileUploadInfo &> UploadAccessCallback;
132  typedef boost::function1<bool, const FileDownloadInfo &> DownloadAccessCallback;
133 
134  typedef boost::shared_ptr< std::ifstream > IfstreamPtr;
135  typedef boost::shared_ptr< std::ofstream > OfstreamPtr;
136 
137  class FileIoRequest;
138  typedef boost::shared_ptr<FileIoRequest> FileIoRequestPtr;
139 
140  class FileUploadInfo : boost::noncopyable
141  {
142  public:
143  FileUploadInfo(BandwidthQuotaPtr quotaPtr);
144  ~FileUploadInfo();
145 
146  FileManifest mManifest;
147  boost::filesystem::path mUploadPath;
148 
149  OfstreamPtr mFileStream;
150  boost::filesystem::path mFileStreamPath;
151  FileIoRequestPtr mWriteOp;
152 
153  bool mCompleted;
154  bool mResume;
155  boost::uint32_t mTimeStampMs;
156  boost::uint32_t mCurrentFile;
157  boost::uint64_t mCurrentPos;
158  boost::uint32_t mSessionLocalId;
159  std::string mUploadId;
160 
161  BandwidthQuotaPtr mQuotaPtr;
162  };
163 
164  class FileDownloadInfo : boost::noncopyable
165  {
166  public:
167  FileDownloadInfo(BandwidthQuotaPtr quotaPtr);
168  ~FileDownloadInfo();
169 
170  boost::filesystem::path mDownloadPath;
171  FileManifest mManifest;
172 
173  IfstreamPtr mFileStream;
174  boost::filesystem::path mFileStreamPath;
175  FileIoRequestPtr mReadOp;
176  ByteBuffer mReadBuffer;
177  ByteBuffer mSendBuffer;
178  ByteBuffer mSendBufferRemaining;
179 
180  boost::uint32_t mCurrentFile;
181  boost::uint64_t mCurrentPos;
182  bool mResume;
183 
184  Timer mTransferWindowTimer;
185  boost::uint32_t mTransferWindowBytesSoFar;
186  boost::uint32_t mTransferWindowBytesTotal;
187 
188  bool mCancel;
189 
190  boost::uint32_t mSessionLocalId;
191 
192  BandwidthQuotaPtr mQuotaPtr;
193  };
194 
195  typedef boost::shared_ptr<FileUploadInfo> FileUploadInfoPtr;
196  typedef boost::shared_ptr<FileDownloadInfo> FileDownloadInfoPtr;
197 
198  class FileChunk;
199  class FileTransferRequest;
200 
201  class RCF_EXPORT FileTransferService : public I_Service
202  {
203  public:
204  FileTransferService();
205 
206  typedef boost::function<void(RcfSession&, FileDownloadInfo &)> OnFileDownloadProgress;
207  typedef boost::function<void(RcfSession&, FileUploadInfo &)> OnFileUploadProgress;
208 
209  typedef boost::function1<BandwidthQuotaPtr, RcfSession &> BandwidthQuotaCallback;
210  typedef BandwidthQuotaCallback UploadQuotaCallback;
211  typedef BandwidthQuotaCallback DownloadQuotaCallback;
212 
213  // For testing.
214  void setTransferWindowS(boost::uint32_t transferWindowS);
215  boost::uint32_t getTransferWindowS();
216 
217  //----------------------------------------------------------------------
218  // Remotely accessible.
219 
220  void BeginUpload(
221  const FileManifest & manifest,
222  const std::vector<FileChunk> & chunks,
223  FileChunk & startPos,
224  boost::uint32_t & maxMessageLength,
225  std::string & uploadId,
226  boost::uint32_t & bps,
227  boost::uint32_t sessionLocalId);
228 
229  void UploadChunks(
230  const std::vector<FileChunk> & chunks,
231  boost::uint32_t & bps);
232 
233  void BeginDownload(
234  FileManifest & manifest,
235  const FileTransferRequest & request,
236  std::vector<FileChunk> & chunks,
237  boost::uint32_t & maxMessageLength,
238  boost::uint32_t & bps,
239  boost::uint32_t sessionLocalId);
240 
241  void TrimDownload(
242  const FileChunk & startPos);
243 
244  void DownloadChunks(
245  const FileTransferRequest & request,
246  std::vector<FileChunk> & chunks,
247  boost::uint32_t & adviseWaitMs,
248  boost::uint32_t & bps);
249 
250  //----------------------------------------------------------------------
251 
252  private:
253 
254  std::string addUpload(const boost::filesystem::path & uploadPath);
255  void removeUpload(const std::string & uploadId);
256  boost::filesystem::path findUpload(const std::string & uploadId);
257 
258  void processZeroSizeEntries(RCF::FileUploadInfo & uploadInfo);
259  void checkForUploadCompletion(FileUploadInfoPtr uploadInfoPtr);
260 
261  typedef std::map<
262  std::string,
263  boost::filesystem::path> UploadsInProgress;
264 
265  Mutex mUploadsInProgressMutex;
266  UploadsInProgress mUploadsInProgress;
267 
268  void onServerStart(RcfServer & server);
269  void onServerStop(RcfServer & server);
270 
271  boost::filesystem::path mUploadDirectory;
272 
273  OnFileDownloadProgress mOnFileDownloadProgress;
274  OnFileUploadProgress mOnFileUploadProgress;
275 
276  boost::uint32_t mTransferWindowS;
277 
278  BandwidthQuotaPtr mUploadQuota;
279  BandwidthQuotaPtr mDownloadQuota;
280 
281  BandwidthQuotaCallback mUploadQuotaCallback;
282  BandwidthQuotaCallback mDownloadQuotaCallback;
283  };
284 
285  typedef boost::shared_ptr<FileTransferService> FileTransferServicePtr;
286 
287 } // namespace RCF
288 
289 #endif // ! INCLUDE_RCF_FILETRANSFERSERVICE_HPP