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