diff options
Diffstat (limited to 'linden/indra/newview/llviewerassetstorage.cpp')
-rw-r--r-- | linden/indra/newview/llviewerassetstorage.cpp | 215 |
1 files changed, 215 insertions, 0 deletions
diff --git a/linden/indra/newview/llviewerassetstorage.cpp b/linden/indra/newview/llviewerassetstorage.cpp new file mode 100644 index 0000000..72af419 --- /dev/null +++ b/linden/indra/newview/llviewerassetstorage.cpp | |||
@@ -0,0 +1,215 @@ | |||
1 | /** | ||
2 | * @file llviewerassetstorage.cpp | ||
3 | * @brief Subclass capable of loading asset data to/from an external source. | ||
4 | * | ||
5 | * Copyright (c) 2003-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 | |||
29 | #include "linden_common.h" | ||
30 | #include "llviewerprecompiledheaders.h" | ||
31 | |||
32 | #include "llagent.h" | ||
33 | #include "llviewerassetstorage.h" | ||
34 | #include "llviewerbuild.h" | ||
35 | #include "llvfile.h" | ||
36 | #include "llvfs.h" | ||
37 | |||
38 | LLViewerAssetStorage::LLViewerAssetStorage(LLMessageSystem *msg, LLXferManager *xfer, | ||
39 | LLVFS *vfs, const LLHost &upstream_host) | ||
40 | : LLAssetStorage(msg, xfer, vfs, upstream_host) | ||
41 | { | ||
42 | } | ||
43 | |||
44 | |||
45 | LLViewerAssetStorage::LLViewerAssetStorage(LLMessageSystem *msg, LLXferManager *xfer, | ||
46 | LLVFS *vfs) | ||
47 | : LLAssetStorage(msg, xfer, vfs) | ||
48 | { | ||
49 | } | ||
50 | |||
51 | // virtual | ||
52 | void LLViewerAssetStorage::storeAssetData( | ||
53 | const LLTransactionID& tid, | ||
54 | LLAssetType::EType asset_type, | ||
55 | LLStoreAssetCallback callback, | ||
56 | void* user_data, | ||
57 | bool temp_file, | ||
58 | bool is_priority, | ||
59 | bool store_local) | ||
60 | { | ||
61 | LLAssetID asset_id = tid.makeAssetID(gAgent.getSecureSessionID()); | ||
62 | llinfos << "LLViewerAssetStorage::storeAssetData (legacy) " << tid << ":" << LLAssetType::lookup(asset_type) | ||
63 | << " ASSET_ID: " << asset_id << llendl; | ||
64 | |||
65 | if (mUpstreamHost.isOk()) | ||
66 | { | ||
67 | if (mVFS->getExists(asset_id, asset_type)) | ||
68 | { | ||
69 | // Pack data into this packet if we can fit it. | ||
70 | U8 buffer[MTUBYTES]; | ||
71 | buffer[0] = 0; | ||
72 | |||
73 | LLVFile vfile(mVFS, asset_id, asset_type, LLVFile::READ); | ||
74 | S32 asset_size = vfile.getSize(); | ||
75 | |||
76 | LLAssetRequest *req = new LLAssetRequest(asset_id, asset_type); | ||
77 | req->mUpCallback = callback; | ||
78 | req->mUserData = user_data; | ||
79 | |||
80 | if (asset_size < 1) | ||
81 | { | ||
82 | // This can happen if there's a bug in our code or if the VFS has been corrupted. | ||
83 | llwarns << "LLViewerAssetStorage::storeAssetData() Data _should_ already be in the VFS, but it's not! " << asset_id << llendl; | ||
84 | |||
85 | delete req; | ||
86 | if (callback) | ||
87 | { | ||
88 | callback(asset_id, user_data, LL_ERR_ASSET_REQUEST_FAILED); | ||
89 | } | ||
90 | return; | ||
91 | } | ||
92 | else if(is_priority) | ||
93 | { | ||
94 | mPendingUploads.push_front(req); | ||
95 | } | ||
96 | else | ||
97 | { | ||
98 | mPendingUploads.push_back(req); | ||
99 | } | ||
100 | |||
101 | // Read the data from the VFS if it'll fit in this packet. | ||
102 | if (asset_size + 100 < MTUBYTES) | ||
103 | { | ||
104 | BOOL res = vfile.read(buffer, asset_size); | ||
105 | S32 bytes_read = res ? vfile.getLastBytesRead() : 0; | ||
106 | |||
107 | if( bytes_read == asset_size ) | ||
108 | { | ||
109 | req->mDataSentInFirstPacket = TRUE; | ||
110 | //llinfos << "LLViewerAssetStorage::createAsset sending data in first packet" << llendl; | ||
111 | } | ||
112 | else | ||
113 | { | ||
114 | llwarns << "Probable corruption in VFS file, aborting store asset data" << llendl; | ||
115 | if (callback) | ||
116 | { | ||
117 | callback(asset_id, user_data, LL_ERR_ASSET_REQUEST_NONEXISTENT_FILE); | ||
118 | } | ||
119 | return; | ||
120 | } | ||
121 | } | ||
122 | else | ||
123 | { | ||
124 | // Too big, do an xfer | ||
125 | buffer[0] = 0; | ||
126 | asset_size = 0; | ||
127 | } | ||
128 | mMessageSys->newMessageFast(_PREHASH_AssetUploadRequest); | ||
129 | mMessageSys->nextBlockFast(_PREHASH_AssetBlock); | ||
130 | mMessageSys->addUUIDFast(_PREHASH_TransactionID, tid); | ||
131 | mMessageSys->addS8Fast(_PREHASH_Type, (S8)asset_type); | ||
132 | mMessageSys->addBOOLFast(_PREHASH_Tempfile, temp_file); | ||
133 | mMessageSys->addBOOLFast(_PREHASH_StoreLocal, store_local); | ||
134 | mMessageSys->addBinaryDataFast( _PREHASH_AssetData, buffer, asset_size ); | ||
135 | mMessageSys->sendReliable(mUpstreamHost); | ||
136 | } | ||
137 | else | ||
138 | { | ||
139 | llwarns << "AssetStorage: attempt to upload non-existent vfile " << asset_id << ":" << LLAssetType::lookup(asset_type) << llendl; | ||
140 | if (callback) | ||
141 | { | ||
142 | callback(asset_id, user_data, LL_ERR_ASSET_REQUEST_NONEXISTENT_FILE); | ||
143 | } | ||
144 | } | ||
145 | } | ||
146 | else | ||
147 | { | ||
148 | llwarns << "Attempt to move asset store request upstream w/o valid upstream provider" << llendl; | ||
149 | if (callback) | ||
150 | { | ||
151 | callback(asset_id, user_data, LL_ERR_CIRCUIT_GONE); | ||
152 | } | ||
153 | } | ||
154 | } | ||
155 | |||
156 | void LLViewerAssetStorage::storeAssetData( | ||
157 | const char* filename, | ||
158 | const LLTransactionID& tid, | ||
159 | LLAssetType::EType asset_type, | ||
160 | LLStoreAssetCallback callback, | ||
161 | void* user_data, | ||
162 | bool temp_file, | ||
163 | bool is_priority) | ||
164 | { | ||
165 | LLAssetID asset_id = tid.makeAssetID(gAgent.getSecureSessionID()); | ||
166 | llinfos << "LLViewerAssetStorage::storeAssetData (legacy)" << asset_id << ":" << LLAssetType::lookup(asset_type) << llendl; | ||
167 | |||
168 | LLLegacyAssetRequest *legacy = new LLLegacyAssetRequest; | ||
169 | |||
170 | llinfos << "ASSET_ID: " << asset_id << llendl; | ||
171 | |||
172 | legacy->mUpCallback = callback; | ||
173 | legacy->mUserData = user_data; | ||
174 | |||
175 | FILE *fp = LLFile::fopen(filename, "rb"); | ||
176 | if (fp) | ||
177 | { | ||
178 | LLVFile file(mVFS, asset_id, asset_type, LLVFile::WRITE); | ||
179 | |||
180 | fseek(fp, 0, SEEK_END); | ||
181 | S32 size = ftell(fp); | ||
182 | fseek(fp, 0, SEEK_SET); | ||
183 | |||
184 | file.setMaxSize(size); | ||
185 | |||
186 | const S32 buf_size = 65536; | ||
187 | U8 copy_buf[buf_size]; | ||
188 | while ((size = (S32)fread(copy_buf, 1, buf_size, fp))) | ||
189 | { | ||
190 | file.write(copy_buf, size); | ||
191 | } | ||
192 | fclose(fp); | ||
193 | |||
194 | // if this upload fails, the caller needs to setup a new tempfile for us | ||
195 | if (temp_file) | ||
196 | { | ||
197 | LLFile::remove(filename); | ||
198 | } | ||
199 | |||
200 | LLViewerAssetStorage::storeAssetData( | ||
201 | tid, | ||
202 | asset_type, | ||
203 | legacyStoreDataCallback, | ||
204 | (void**)legacy, | ||
205 | temp_file, | ||
206 | is_priority); | ||
207 | } | ||
208 | else | ||
209 | { | ||
210 | if (callback) | ||
211 | { | ||
212 | callback(asset_id, user_data, LL_ERR_CANNOT_OPEN_FILE); | ||
213 | } | ||
214 | } | ||
215 | } | ||