llxfer_vfile.cpp
上传用户:king477883
上传日期:2021-03-01
资源大小:9553k
文件大小:8k
源码类别:

游戏引擎

开发平台:

C++ Builder

  1. /** 
  2.  * @file llxfer_vfile.cpp
  3.  * @brief implementation of LLXfer_VFile class for a single xfer (vfile).
  4.  *
  5.  * $LicenseInfo:firstyear=2002&license=viewergpl$
  6.  * 
  7.  * Copyright (c) 2002-2010, Linden Research, Inc.
  8.  * 
  9.  * Second Life Viewer Source Code
  10.  * The source code in this file ("Source Code") is provided by Linden Lab
  11.  * to you under the terms of the GNU General Public License, version 2.0
  12.  * ("GPL"), unless you have obtained a separate licensing agreement
  13.  * ("Other License"), formally executed by you and Linden Lab.  Terms of
  14.  * the GPL can be found in doc/GPL-license.txt in this distribution, or
  15.  * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
  16.  * 
  17.  * There are special exceptions to the terms and conditions of the GPL as
  18.  * it is applied to this Source Code. View the full text of the exception
  19.  * in the file doc/FLOSS-exception.txt in this software distribution, or
  20.  * online at
  21.  * http://secondlifegrid.net/programs/open_source/licensing/flossexception
  22.  * 
  23.  * By copying, modifying or distributing this software, you acknowledge
  24.  * that you have read and understood your obligations described above,
  25.  * and agree to abide by those obligations.
  26.  * 
  27.  * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
  28.  * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
  29.  * COMPLETENESS OR PERFORMANCE.
  30.  * $/LicenseInfo$
  31.  */
  32. #include "linden_common.h"
  33. #include "llxfer_vfile.h"
  34. #include "lluuid.h"
  35. #include "llerror.h"
  36. #include "llmath.h"
  37. #include "llvfile.h"
  38. #include "llvfs.h"
  39. #include "lldir.h"
  40. // size of chunks read from/written to disk
  41. const U32 LL_MAX_XFER_FILE_BUFFER = 65536;
  42. ///////////////////////////////////////////////////////////
  43. LLXfer_VFile::LLXfer_VFile ()
  44. : LLXfer(-1)
  45. {
  46. init(NULL, LLUUID::null, LLAssetType::AT_NONE);
  47. }
  48. LLXfer_VFile::LLXfer_VFile (LLVFS *vfs, const LLUUID &local_id, LLAssetType::EType type)
  49. : LLXfer(-1)
  50. {
  51. init(vfs, local_id, type);
  52. }
  53. ///////////////////////////////////////////////////////////
  54. LLXfer_VFile::~LLXfer_VFile ()
  55. {
  56. cleanup();
  57. }
  58. ///////////////////////////////////////////////////////////
  59. void LLXfer_VFile::init (LLVFS *vfs, const LLUUID &local_id, LLAssetType::EType type)
  60. {
  61. mVFS = vfs;
  62. mLocalID = local_id;
  63. mType = type;
  64. mVFile = NULL;
  65. std::string id_string;
  66. mLocalID.toString(id_string);
  67. mName = llformat("VFile %s:%s", id_string.c_str(), LLAssetType::lookup(mType));
  68. }
  69. ///////////////////////////////////////////////////////////
  70. void LLXfer_VFile::cleanup ()
  71. {
  72. LLVFile file(mVFS, mTempID, mType, LLVFile::WRITE);
  73. file.remove();
  74. delete mVFile;
  75. mVFile = NULL;
  76. LLXfer::cleanup();
  77. }
  78. ///////////////////////////////////////////////////////////
  79. S32 LLXfer_VFile::initializeRequest(U64 xfer_id,
  80. LLVFS* vfs,
  81. const LLUUID& local_id,
  82. const LLUUID& remote_id,
  83. LLAssetType::EType type,
  84. const LLHost& remote_host,
  85. void (*callback)(void**,S32,LLExtStat),
  86. void** user_data)
  87. {
  88.   S32 retval = 0;  // presume success
  89. mRemoteHost = remote_host;
  90. mVFS = vfs;
  91. mLocalID = local_id;
  92. mRemoteID = remote_id;
  93. mType = type;
  94. mID = xfer_id;
  95. mCallback = callback;
  96. mCallbackDataHandle = user_data;
  97. mCallbackResult = LL_ERR_NOERR;
  98. std::string id_string;
  99. mLocalID.toString(id_string);
  100. mName = llformat("VFile %s:%s", id_string.c_str(), LLAssetType::lookup(mType));
  101. llinfos << "Requesting " << mName << llendl;
  102. if (mBuffer)
  103. {
  104. delete[] mBuffer;
  105. mBuffer = NULL;
  106. }
  107. mBuffer = new char[LL_MAX_XFER_FILE_BUFFER];
  108. mBufferLength = 0;
  109. mPacketNum = 0;
  110. mTempID.generate();
  111.   mStatus = e_LL_XFER_PENDING;
  112. return retval;
  113. }
  114. //////////////////////////////////////////////////////////
  115. S32 LLXfer_VFile::startDownload()
  116. {
  117.   S32 retval = 0;  // presume success
  118. LLVFile file(mVFS, mTempID, mType, LLVFile::APPEND);
  119. gMessageSystem->newMessageFast(_PREHASH_RequestXfer);
  120. gMessageSystem->nextBlockFast(_PREHASH_XferID);
  121. gMessageSystem->addU64Fast(_PREHASH_ID, mID);
  122. gMessageSystem->addStringFast(_PREHASH_Filename, "");
  123. gMessageSystem->addU8("FilePath", (U8) LL_PATH_NONE);
  124. gMessageSystem->addBOOL("DeleteOnCompletion", FALSE);
  125. gMessageSystem->addBOOL("UseBigPackets", BOOL(mChunkSize == LL_XFER_LARGE_PAYLOAD));
  126. gMessageSystem->addUUIDFast(_PREHASH_VFileID, mRemoteID);
  127. gMessageSystem->addS16Fast(_PREHASH_VFileType, (S16)mType);
  128. gMessageSystem->sendReliable(mRemoteHost);
  129. mStatus = e_LL_XFER_IN_PROGRESS;
  130. return (retval);
  131. }
  132. ///////////////////////////////////////////////////////////
  133. S32 LLXfer_VFile::startSend (U64 xfer_id, const LLHost &remote_host)
  134. {
  135. S32 retval = LL_ERR_NOERR;  // presume success
  136.     mRemoteHost = remote_host;
  137. mID = xfer_id;
  138.     mPacketNum = -1;
  139. // cout << "Sending file: " << mLocalFilename << endl;
  140. delete [] mBuffer;
  141. mBuffer = new char[LL_MAX_XFER_FILE_BUFFER];
  142. mBufferLength = 0;
  143. mBufferStartOffset = 0;
  144. delete mVFile;
  145. mVFile = NULL;
  146. if(mVFS->getExists(mLocalID, mType))
  147. {
  148. mVFile = new LLVFile(mVFS, mLocalID, mType, LLVFile::READ);
  149. if (mVFile->getSize() <= 0)
  150. {
  151. delete mVFile;
  152. mVFile = NULL;
  153. return LL_ERR_FILE_EMPTY;
  154. }
  155. }
  156. if(mVFile)
  157. {
  158. setXferSize(mVFile->getSize());
  159. mStatus = e_LL_XFER_PENDING;
  160. }
  161. else
  162. {
  163. retval = LL_ERR_FILE_NOT_FOUND;
  164. }
  165. return (retval);
  166. }
  167. ///////////////////////////////////////////////////////////
  168. void LLXfer_VFile::setXferSize (S32 xfer_size)
  169. {
  170. LLXfer::setXferSize(xfer_size);
  171. // Don't do this on the server side, where we have a persistent mVFile
  172. // It would be nice if LLXFers could tell which end of the pipe they were
  173. if (! mVFile)
  174. {
  175. LLVFile file(mVFS, mTempID, mType, LLVFile::APPEND);
  176. file.setMaxSize(xfer_size);
  177. }
  178. }
  179. ///////////////////////////////////////////////////////////
  180. S32 LLXfer_VFile::getMaxBufferSize ()
  181. {
  182. return(LL_MAX_XFER_FILE_BUFFER);
  183. }
  184. ///////////////////////////////////////////////////////////
  185. S32 LLXfer_VFile::suck(S32 start_position)
  186. {
  187. S32 retval = 0;
  188. if (mVFile)
  189. {
  190. // grab a buffer from the right place in the file
  191. if (! mVFile->seek(start_position, 0))
  192. {
  193. llwarns << "VFile Xfer Can't seek to position " << start_position << ", file length " << mVFile->getSize() << llendl;
  194. llwarns << "While sending file " << mLocalID << llendl;
  195. return -1;
  196. }
  197. if (mVFile->read((U8*)mBuffer, LL_MAX_XFER_FILE_BUFFER)) /* Flawfinder : ignore */
  198. {
  199. mBufferLength = mVFile->getLastBytesRead();
  200. mBufferStartOffset = start_position;
  201. mBufferContainsEOF = mVFile->eof();
  202. }
  203. else
  204. {
  205. retval = -1;
  206. }
  207. }
  208. else
  209. {
  210. retval = -1;
  211. }
  212. return (retval);
  213. }
  214. ///////////////////////////////////////////////////////////
  215. S32 LLXfer_VFile::flush()
  216. {
  217. S32 retval = 0;
  218. if (mBufferLength)
  219. {
  220. LLVFile file(mVFS, mTempID, mType, LLVFile::APPEND);
  221. file.write((U8*)mBuffer, mBufferLength);
  222. mBufferLength = 0;
  223. }
  224. return (retval);
  225. }
  226. ///////////////////////////////////////////////////////////
  227. S32 LLXfer_VFile::processEOF()
  228. {
  229. S32 retval = 0;
  230. mStatus = e_LL_XFER_COMPLETE;
  231. flush();
  232. if (!mCallbackResult)
  233. {
  234. LLVFile file(mVFS, mTempID, mType, LLVFile::WRITE);
  235. if (! file.rename(mLocalID, mType))
  236. {
  237. llinfos << "copy from temp file failed: unable to rename to " << mLocalID << llendl;
  238. }
  239. }
  240. if (mVFile)
  241. {
  242. delete mVFile;
  243. mVFile = NULL;
  244. }
  245. retval = LLXfer::processEOF();
  246. return(retval);
  247. }
  248. ////////////////////////////////////////////////////////////
  249. BOOL LLXfer_VFile::matchesLocalFile(const LLUUID &id, LLAssetType::EType type)
  250. {
  251. return (id == mLocalID && type == mType);
  252. }
  253. //////////////////////////////////////////////////////////
  254. BOOL LLXfer_VFile::matchesRemoteFile(const LLUUID &id, LLAssetType::EType type)
  255. {
  256. return (id == mRemoteID && type == mType);
  257. }
  258. //////////////////////////////////////////////////////////
  259. std::string LLXfer_VFile::getFileName() 
  260. {
  261. return mName;
  262. }
  263. //////////////////////////////////////////////////////////
  264. // hacky - doesn't matter what this is
  265. // as long as it's different from the other classes
  266. U32 LLXfer_VFile::getXferTypeTag()
  267. {
  268. return LLXfer::XFER_VFILE;
  269. }