RCFProto
 All Classes Functions Typedefs
FileStream.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_FILESTREAM_HPP
20 #define INCLUDE_RCF_FILESTREAM_HPP
21 
22 #include <RCF/Config.hpp>
23 
24 #if RCF_FEATURE_FILETRANSFER==0
25 #error RCF_FEATURE_FILETRANSFER=1 must be defined
26 #endif
27 
28 #include <RCF/ByteBuffer.hpp>
29 #include <RCF/Export.hpp>
30 
31 #include <boost/enable_shared_from_this.hpp>
32 #include <boost/filesystem/path.hpp>
33 #include <boost/function.hpp>
34 
35 #if RCF_FEATURE_BOOST_SERIALIZATION==1
36 #include <boost/serialization/vector.hpp>
37 #include <boost/serialization/shared_ptr.hpp>
38 #endif
39 
40 namespace SF {
41 
42  class Archive;
43 
44 } // namespace SF
45 
46 namespace RCF {
47 
48  class FileUploadInfo;
49  typedef boost::shared_ptr<FileUploadInfo> FileUploadInfoPtr;
50 
51  class FileInfo;
52  class FileManifest;
53  class FileStreamImpl;
54 
55  typedef boost::shared_ptr<FileStreamImpl> FileStreamImplPtr;
56 
57  class ClientStub;
58 
59  class RCF_EXPORT FileInfo
60  {
61  public:
62  FileInfo() :
63  mIsDirectory(false),
64  mFileStartPos(0),
65  mFileSize(0),
66  mFileCrc(0),
67  mLastWriteTime(0)
68  {}
69 
70  bool mIsDirectory;
71  boost::filesystem::path mFilePath;
72  boost::uint64_t mFileStartPos;
73  boost::uint64_t mFileSize;
74  boost::uint32_t mFileCrc;
75  std::string mRenameFile;
76  boost::uint64_t mLastWriteTime;
77 
78 #if RCF_FEATURE_SF==1
79  void serialize(SF::Archive & ar);
80 #endif
81 
82 #if RCF_FEATURE_BOOST_SERIALIZATION==1
83  template<typename Archive>
84  void serialize(Archive & ar, const unsigned int)
85  {
86  ar
87  & mIsDirectory
88  & mFilePath
89  & mFileStartPos
90  & mFileSize
91  & mFileCrc
92  & mRenameFile;
93 
94  int runtimeVersion = getRuntimeVersionOfThisRemoteCall();
95  if (runtimeVersion >= 11)
96  {
97  ar & mLastWriteTime;
98  }
99  }
100 #endif
101 
102  };
103 
104  class RCF_EXPORT FileManifest
105  {
106  public:
107  typedef std::vector< FileInfo > Files;
108  Files mFiles;
109 
110  boost::filesystem::path mManifestBase;
111 
112  FileManifest() {}
113 
114  FileManifest(boost::filesystem::path pathToFiles);
115 
116  boost::uint64_t getTotalByteSize() const;
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  ar & mFiles;
127  }
128 #endif
129 
130  };
131 
132  class RCF_EXPORT FileStreamImpl : public boost::enable_shared_from_this<FileStreamImpl>
133  {
134  public:
135 
136  enum Direction
137  {
138  Unspecified,
139  Upload,
140  Download
141  };
142 
143 
144  FileStreamImpl();
145  FileStreamImpl(const std::string & filePath);
146  FileStreamImpl(const FileManifest & manifest);
147 
148  ~FileStreamImpl();
149 
150  void serializeGeneric(
151  bool isWriting,
152  boost::function2<void, boost::uint32_t &, Direction &> serializeImpl);
153 
154 #if RCF_FEATURE_SF==1
155  void serializeImplSf(SF::Archive & ar, boost::uint32_t & transferId, Direction & dir);
156  void serialize(SF::Archive & ar);
157 #endif
158 
159 #if RCF_FEATURE_BOOST_SERIALIZATION==1
160 
161  template<typename Archive>
162  void serializeImplBser(Archive & ar, boost::uint32_t & transferId, Direction & dir)
163  {
164  ar & transferId & dir;
165  }
166 
167  template<typename Archive>
168  void serialize(Archive & ar, const unsigned int)
169  {
170  typedef typename Archive::is_saving IsSaving;
171  const bool isSaving = IsSaving::value;
172 
173  serializeGeneric(
174  isSaving,
175  boost::bind(
176  &FileStreamImpl::serializeImplBser<Archive>,
177  this,
178  boost::ref(ar),
179  _1,
180  _2) );
181  }
182 
183 #endif
184 
185  std::string mUploadId;
186  boost::filesystem::path mDownloadToPath;
187  FileManifest mManifest;
188  boost::uint32_t mTransferRateBps;
189  boost::uint32_t mSessionLocalId;
190 
191  Direction mDirection;
192  };
193 
194  class RCF_EXPORT FileStream
195  {
196  protected:
197 
198  FileStream();
199  FileStream(FileStreamImplPtr implPtr);
200  FileStream(const std::string & filePath);
201  FileStream(const FileManifest & manifest);
202 
203  public:
204 
205  // Made this inline as it was not being linked in, in DLL builds.
206  FileStream & operator=(const FileStream & rhs)
207  {
208  *mImplPtr = *rhs.mImplPtr;
209  return *this;
210  }
211 
212  // FileStream recipient calls these.
213  std::string getLocalPath() const;
214  FileManifest & getManifest() const;
215 
216  // Client calls these.
217  void setDownloadToPath(const std::string & downloadToPath);
218  std::string getDownloadToPath() const;
219 
220  void setTransferRateBps(boost::uint32_t transferRateBps);
221  boost::uint32_t getTransferRateBps();
222 
223  void upload(RCF::ClientStub & clientStub);
224  void download(RCF::ClientStub & clientStub);
225 
226  FileStreamImplPtr mImplPtr;
227 
228 #if RCF_FEATURE_SF==1
229  void serialize(SF::Archive & ar);
230 #endif
231 
232 #if RCF_FEATURE_BOOST_SERIALIZATION==1
233  template<typename Archive>
234  void serialize(Archive & ar, const unsigned int)
235  {
236  ar & *mImplPtr;
237  }
238 #endif
239 
240  };
241 
242  class FileTransferProgress
243  {
244  public:
245 
246  FileTransferProgress() :
247  mBytesTotalToTransfer(0),
248  mBytesTransferredSoFar(0),
249  mServerLimitBps(0)
250  {
251 
252  }
253 
254  boost::uint64_t mBytesTotalToTransfer;
255  boost::uint64_t mBytesTransferredSoFar;
256  boost::uint32_t mServerLimitBps;
257  };
258 
259  class FileChunk
260  {
261  public:
262 
263  FileChunk() : mFileIndex(0), mOffset(0)
264  {}
265 
266  boost::uint32_t mFileIndex;
267  boost::uint64_t mOffset;
268  ByteBuffer mData;
269 
270 #if RCF_FEATURE_SF==1
271  void serialize(SF::Archive & ar);
272 #endif
273 
274 #if RCF_FEATURE_BOOST_SERIALIZATION==1
275  template<typename Archive>
276  void serialize(Archive & ar, const unsigned int)
277  {
278  ar & mFileIndex & mOffset & mData;
279  }
280 #endif
281 
282  };
283 
284  class FileTransferRequest
285  {
286  public:
287  FileTransferRequest() : mFile(0), mPos(0), mChunkSize(0)
288  {}
289 
290  boost::uint32_t mFile;
291  boost::uint64_t mPos;
292  boost::uint32_t mChunkSize;
293 
294 #if RCF_FEATURE_SF==1
295  void serialize(SF::Archive & ar);
296 #endif
297 
298 #if RCF_FEATURE_BOOST_SERIALIZATION==1
299  template<typename Archive>
300  void serialize(Archive & ar, const unsigned int)
301  {
302  ar & mFile & mPos & mChunkSize;
303  }
304 #endif
305 
306  };
307 
308 } // namespace RCF
309 
310 #endif // ! INCLUDE_RCF_FILESTREAM_HPP