FileListTransfer.h 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. /*
  2. * Copyright (c) 2014, Oculus VR, Inc.
  3. * All rights reserved.
  4. *
  5. * This source code is licensed under the BSD-style license found in the
  6. * LICENSE file in the root directory of this source tree. An additional grant
  7. * of patent rights can be found in the PATENTS file in the same directory.
  8. *
  9. */
  10. /// \file FileListTransfer.h
  11. /// \brief A plugin to provide a simple way to compress and incrementally send the files in the FileList structure.
  12. ///
  13. #include "NativeFeatureIncludes.h"
  14. #if _RAKNET_SUPPORT_FileListTransfer==1 && _RAKNET_SUPPORT_FileOperations==1
  15. #ifndef __FILE_LIST_TRANFER_H
  16. #define __FILE_LIST_TRANFER_H
  17. #include "RakNetTypes.h"
  18. #include "Export.h"
  19. #include "PluginInterface2.h"
  20. #include "DS_Map.h"
  21. #include "RakNetTypes.h"
  22. #include "PacketPriority.h"
  23. #include "RakMemoryOverride.h"
  24. #include "FileList.h"
  25. #include "DS_Queue.h"
  26. #include "SimpleMutex.h"
  27. #include "ThreadPool.h"
  28. namespace RakNet
  29. {
  30. /// Forward declarations
  31. class IncrementalReadInterface;
  32. class FileListTransferCBInterface;
  33. class FileListProgress;
  34. struct FileListReceiver;
  35. /// \defgroup FILE_LIST_TRANSFER_GROUP FileListTransfer
  36. /// \brief A plugin to provide a simple way to compress and incrementally send the files in the FileList structure.
  37. /// \details
  38. /// \ingroup PLUGINS_GROUP
  39. /// \brief A plugin to provide a simple way to compress and incrementally send the files in the FileList structure.
  40. /// \details Similar to the DirectoryDeltaTransfer plugin, except that it doesn't send deltas based on pre-existing files or actually write the files to disk.
  41. ///
  42. /// Usage:
  43. /// Call SetupReceive to allow one file set to arrive. The value returned by FileListTransfer::SetupReceive()<BR>
  44. /// is the setID that is allowed.<BR>
  45. /// It's up to you to transmit this value to the other system, along with information indicating what kind of files you want to get.<BR>
  46. /// The other system should then prepare a FileList and call FileListTransfer::Send(), passing the return value of FileListTransfer::SetupReceive()<BR>
  47. /// as the \a setID parameter to FileListTransfer::Send()
  48. /// \ingroup FILE_LIST_TRANSFER_GROUP
  49. class RAK_DLL_EXPORT FileListTransfer : public PluginInterface2
  50. {
  51. public:
  52. // GetInstance() and DestroyInstance(instance*)
  53. STATIC_FACTORY_DECLARATIONS(FileListTransfer)
  54. FileListTransfer();
  55. virtual ~FileListTransfer();
  56. /// \brief Optionally start worker threads when using _incrementalReadInterface for the Send() operation
  57. /// \param[in] numThreads how many worker threads to start
  58. /// \param[in] threadPriority Passed to the thread creation routine. Use THREAD_PRIORITY_NORMAL for Windows. For Linux based systems, you MUST pass something reasonable based on the thread priorities for your application.
  59. void StartIncrementalReadThreads(int numThreads, int threadPriority=-99999);
  60. /// \brief Allows one corresponding Send() call from another system to arrive.
  61. /// \param[in] handler The class to call on each file
  62. /// \param[in] deleteHandler True to delete the handler when it is no longer needed. False to not do so.
  63. /// \param[in] allowedSender Which system to allow files from.
  64. /// \return A set ID value, which should be passed as the \a setID value to the Send() call on the other system. This value will be returned in the callback and is unique per file set. Returns 65535 on failure (not connected to sender)
  65. unsigned short SetupReceive(FileListTransferCBInterface *handler, bool deleteHandler, SystemAddress allowedSender);
  66. /// \brief Send the FileList structure to another system, which must have previously called SetupReceive().
  67. /// \param[in] fileList A list of files. The data contained in FileList::data will be sent incrementally and compressed among all files in the set
  68. /// \param[in] rakPeer The instance of RakNet to use to send the message. Pass 0 to use the instance the plugin is attached to
  69. /// \param[in] recipient The address of the system to send to
  70. /// \param[in] setID The return value of SetupReceive() which was previously called on \a recipient
  71. /// \param[in] priority Passed to RakPeerInterface::Send()
  72. /// \param[in] orderingChannel Passed to RakPeerInterface::Send()
  73. /// \param[in] _incrementalReadInterface If a file in \a fileList has no data, _incrementalReadInterface will be used to read the file in chunks of size \a chunkSize
  74. /// \param[in] _chunkSize How large of a block of a file to read/send at once. Large values use more memory but transfer slightly faster.
  75. void Send(FileList *fileList, RakNet::RakPeerInterface *rakPeer, SystemAddress recipient, unsigned short setID, PacketPriority priority, char orderingChannel, IncrementalReadInterface *_incrementalReadInterface=0, unsigned int _chunkSize=262144*4*16);
  76. /// Return number of files waiting to go out to a particular address
  77. unsigned int GetPendingFilesToAddress(SystemAddress recipient);
  78. /// \brief Stop a download.
  79. void CancelReceive(unsigned short setId);
  80. /// \brief Remove all handlers associated with a particular system address.
  81. void RemoveReceiver(SystemAddress systemAddress);
  82. /// \brief Is a handler passed to SetupReceive still running?
  83. bool IsHandlerActive(unsigned short setId);
  84. /// \brief Adds a callback to get progress reports about what the file list instances do.
  85. /// \param[in] cb A pointer to an externally defined instance of FileListProgress. This pointer is held internally, so should remain valid as long as this class is valid.
  86. void AddCallback(FileListProgress *cb);
  87. /// \brief Removes a callback
  88. /// \param[in] cb A pointer to an externally defined instance of FileListProgress that was previously added with AddCallback()
  89. void RemoveCallback(FileListProgress *cb);
  90. /// \brief Removes all callbacks
  91. void ClearCallbacks(void);
  92. /// Returns all callbacks added with AddCallback()
  93. /// \param[out] callbacks The list is set to the list of callbacks
  94. void GetCallbacks(DataStructures::List<FileListProgress*> &callbacks);
  95. /// \internal For plugin handling
  96. virtual PluginReceiveResult OnReceive(Packet *packet);
  97. /// \internal For plugin handling
  98. virtual void OnRakPeerShutdown(void);
  99. /// \internal For plugin handling
  100. virtual void OnClosedConnection(const SystemAddress &systemAddress, RakNetGUID rakNetGUID, PI2_LostConnectionReason lostConnectionReason );
  101. /// \internal For plugin handling
  102. virtual void Update(void);
  103. protected:
  104. bool DecodeSetHeader(Packet *packet);
  105. bool DecodeFile(Packet *packet, bool fullFile);
  106. void Clear(void);
  107. void OnReferencePush(Packet *packet, bool fullFile);
  108. void OnReferencePushAck(Packet *packet);
  109. void SendIRIToAddress(SystemAddress systemAddress, unsigned short setId);
  110. DataStructures::Map<unsigned short, FileListReceiver*> fileListReceivers;
  111. unsigned short setId;
  112. DataStructures::List<FileListProgress*> fileListProgressCallbacks;
  113. struct FileToPush
  114. {
  115. FileListNode fileListNode;
  116. PacketPriority packetPriority;
  117. char orderingChannel;
  118. unsigned int currentOffset;
  119. ////unsigned short setID;
  120. unsigned int setIndex;
  121. IncrementalReadInterface *incrementalReadInterface;
  122. unsigned int chunkSize;
  123. };
  124. struct FileToPushRecipient
  125. {
  126. unsigned int refCount;
  127. SimpleMutex refCountMutex;
  128. void DeleteThis(void);
  129. void AddRef(void);
  130. void Deref(void);
  131. SystemAddress systemAddress;
  132. unsigned short setId;
  133. //// SimpleMutex filesToPushMutex;
  134. DataStructures::Queue<FileToPush*> filesToPush;
  135. };
  136. DataStructures::List< FileToPushRecipient* > fileToPushRecipientList;
  137. SimpleMutex fileToPushRecipientListMutex;
  138. void RemoveFromList(FileToPushRecipient *ftpr);
  139. struct ThreadData
  140. {
  141. FileListTransfer *fileListTransfer;
  142. SystemAddress systemAddress;
  143. unsigned short setId;
  144. };
  145. ThreadPool<ThreadData, int> threadPool;
  146. friend int SendIRIToAddressCB(FileListTransfer::ThreadData threadData, bool *returnOutput, void* perThreadData);
  147. };
  148. } // namespace RakNet
  149. #endif
  150. #endif // _RAKNET_SUPPORT_*
粤ICP备19079148号