00001
00032 #include "linden_common.h"
00033
00034 #include "lltransfersourceasset.h"
00035
00036 #include "llerror.h"
00037 #include "message.h"
00038 #include "lldatapacker.h"
00039 #include "lldir.h"
00040 #include "llvfile.h"
00041
00042 LLTransferSourceAsset::LLTransferSourceAsset(const LLUUID &request_id, const F32 priority) :
00043 LLTransferSource(LLTST_ASSET, request_id, priority),
00044 mGotResponse(FALSE),
00045 mCurPos(0)
00046 {
00047 }
00048
00049 LLTransferSourceAsset::~LLTransferSourceAsset()
00050 {
00051 }
00052
00053
00054 void LLTransferSourceAsset::initTransfer()
00055 {
00056 if (gAssetStorage)
00057 {
00058
00059
00060
00061 LLUUID* tidp;
00062 if(is_asset_fetch_by_id_allowed(mParams.getAssetType()))
00063 {
00064 tidp = new LLUUID(getID());
00065 gAssetStorage->getAssetData(
00066 mParams.getAssetID(),
00067 mParams.getAssetType(),
00068 LLTransferSourceAsset::responderCallback,
00069 tidp,
00070 FALSE);
00071 }
00072 else
00073 {
00074 llwarns << "Attempted to request blocked asset "
00075 << mParams.getAssetID() << ":"
00076 << LLAssetType::lookupHumanReadable(mParams.getAssetType())
00077 << llendl;
00078 sendTransferStatus(LLTS_ERROR);
00079 }
00080 }
00081 else
00082 {
00083 llwarns << "Attempted to request asset " << mParams.getAssetID()
00084 << ":" << LLAssetType::lookupHumanReadable(mParams.getAssetType())
00085 << " without an asset system!" << llendl;
00086 sendTransferStatus(LLTS_ERROR);
00087 }
00088 }
00089
00090 F32 LLTransferSourceAsset::updatePriority()
00091 {
00092 return 0.f;
00093 }
00094
00095 LLTSCode LLTransferSourceAsset::dataCallback(const S32 packet_id,
00096 const S32 max_bytes,
00097 U8 **data_handle,
00098 S32 &returned_bytes,
00099 BOOL &delete_returned)
00100 {
00101
00102 if (!mGotResponse)
00103 {
00104 return LLTS_SKIP;
00105 }
00106
00107 LLVFile vf(gAssetStorage->mVFS, mParams.getAssetID(), mParams.getAssetType(), LLVFile::READ);
00108
00109 if (!vf.getSize())
00110 {
00111
00112 return LLTS_ERROR;
00113 }
00114
00115 if (packet_id != mLastPacketID + 1)
00116 {
00117 llerrs << "Can't handle out of order file transfer yet!" << llendl;
00118 }
00119
00120
00121 if (!vf.seek(mCurPos, 0))
00122 {
00123 llwarns << "LLTransferSourceAsset Can't seek to " << mCurPos << " length " << vf.getSize() << llendl;
00124 llwarns << "While sending " << mParams.getAssetID() << llendl;
00125 return LLTS_ERROR;
00126 }
00127
00128 delete_returned = TRUE;
00129 U8 *tmpp = new U8[max_bytes];
00130 *data_handle = tmpp;
00131 if (!vf.read(tmpp, max_bytes))
00132 {
00133
00134 delete[] tmpp;
00135 *data_handle = NULL;
00136 returned_bytes = 0;
00137 delete_returned = FALSE;
00138 return LLTS_ERROR;
00139 }
00140
00141 returned_bytes = vf.getLastBytesRead();
00142 mCurPos += returned_bytes;
00143
00144
00145 if (vf.eof())
00146 {
00147 if (!returned_bytes)
00148 {
00149 delete[] tmpp;
00150 *data_handle = NULL;
00151 returned_bytes = 0;
00152 delete_returned = FALSE;
00153 }
00154 return LLTS_DONE;
00155 }
00156
00157 return LLTS_OK;
00158 }
00159
00160 void LLTransferSourceAsset::completionCallback(const LLTSCode status)
00161 {
00162
00163
00164 }
00165
00166 void LLTransferSourceAsset::packParams(LLDataPacker& dp) const
00167 {
00168
00169 mParams.packParams(dp);
00170 }
00171
00172 BOOL LLTransferSourceAsset::unpackParams(LLDataPacker &dp)
00173 {
00174
00175 return mParams.unpackParams(dp);
00176 }
00177
00178
00179 void LLTransferSourceAsset::responderCallback(LLVFS *vfs, const LLUUID& uuid, LLAssetType::EType type,
00180 void *user_data, S32 result, LLExtStat ext_status )
00181 {
00182 LLUUID *tidp = ((LLUUID*) user_data);
00183 LLUUID transfer_id = *(tidp);
00184 delete tidp;
00185 tidp = NULL;
00186
00187 LLTransferSourceAsset *tsap = (LLTransferSourceAsset *) gTransferManager.findTransferSource(transfer_id);
00188
00189 if (!tsap)
00190 {
00191 llinfos << "Aborting transfer " << transfer_id << " callback, transfer source went away" << llendl;
00192 return;
00193 }
00194
00195 if (result)
00196 {
00197 llinfos << "AssetStorage: Error " << gAssetStorage->getErrorString(result) << " downloading uuid " << uuid << llendl;
00198 }
00199
00200 LLTSCode status;
00201
00202 tsap->mGotResponse = TRUE;
00203 if (LL_ERR_NOERR == result)
00204 {
00205
00206 LLVFile vf(gAssetStorage->mVFS, uuid, type, LLVFile::READ);
00207 tsap->mSize = vf.getSize();
00208 status = LLTS_OK;
00209 }
00210 else
00211 {
00212
00213 switch (result)
00214 {
00215 case LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE:
00216 status = LLTS_UNKNOWN_SOURCE;
00217 break;
00218 default:
00219 status = LLTS_ERROR;
00220 }
00221 }
00222
00223 tsap->sendTransferStatus(status);
00224 }
00225
00226
00227
00228 LLTransferSourceParamsAsset::LLTransferSourceParamsAsset() : LLTransferSourceParams(LLTST_ASSET)
00229 {
00230 }
00231
00232 void LLTransferSourceParamsAsset::setAsset(const LLUUID &asset_id, const LLAssetType::EType asset_type)
00233 {
00234 mAssetID = asset_id;
00235 mAssetType = asset_type;
00236 }
00237
00238 void LLTransferSourceParamsAsset::packParams(LLDataPacker &dp) const
00239 {
00240 dp.packUUID(mAssetID, "AssetID");
00241 dp.packS32(mAssetType, "AssetType");
00242 }
00243
00244
00245 BOOL LLTransferSourceParamsAsset::unpackParams(LLDataPacker &dp)
00246 {
00247 S32 tmp_at;
00248
00249 dp.unpackUUID(mAssetID, "AssetID");
00250 dp.unpackS32(tmp_at, "AssetType");
00251
00252 mAssetType = (LLAssetType::EType)tmp_at;
00253
00254 return TRUE;
00255 }
00256
00260 bool is_asset_fetch_by_id_allowed(LLAssetType::EType type)
00261 {
00262
00263 bool rv = false;
00264 switch(type)
00265 {
00266 case LLAssetType::AT_SOUND:
00267 case LLAssetType::AT_LANDMARK:
00268 case LLAssetType::AT_CLOTHING:
00269 case LLAssetType::AT_BODYPART:
00270 case LLAssetType::AT_ANIMATION:
00271 case LLAssetType::AT_GESTURE:
00272 rv = true;
00273 break;
00274 default:
00275 break;
00276 }
00277 return rv;
00278 }
00279
00280 bool is_asset_id_knowable(LLAssetType::EType type)
00281 {
00282
00283 bool rv = false;
00284 switch(type)
00285 {
00286 case LLAssetType::AT_TEXTURE:
00287 case LLAssetType::AT_SOUND:
00288 case LLAssetType::AT_LANDMARK:
00289 case LLAssetType::AT_CLOTHING:
00290 case LLAssetType::AT_NOTECARD:
00291 case LLAssetType::AT_BODYPART:
00292 case LLAssetType::AT_ANIMATION:
00293 case LLAssetType::AT_GESTURE:
00294 rv = true;
00295 break;
00296 default:
00297 break;
00298 }
00299 return rv;
00300 }