lltransfersourceasset.cpp

Go to the documentation of this file.
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                 // *HACK: asset transfers will only be coming from the viewer
00059                 // to the simulator. This is subset of assets we allow to be
00060                 // simply pulled straight from the asset system.
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         //llinfos << "LLTransferSourceAsset::dataCallback" << llendl;
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                 // Something bad happened with the asset request!
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         // grab a buffer from the right place in the file
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))          /* Flawfinder: Ignore */
00132         {
00133                 // Crap, read failure, need to deal with it.
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         // No matter what happens, all we want to do is close the vfile if
00163         // we've got it open.
00164 }
00165 
00166 void LLTransferSourceAsset::packParams(LLDataPacker& dp) const
00167 {
00168         //llinfos << "LLTransferSourceAsset::packParams" << llendl;
00169         mParams.packParams(dp);
00170 }
00171 
00172 BOOL LLTransferSourceAsset::unpackParams(LLDataPacker &dp)
00173 {
00174         //llinfos << "LLTransferSourceAsset::unpackParams" << llendl;
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                 // Everything's OK.
00206                 LLVFile vf(gAssetStorage->mVFS, uuid, type, LLVFile::READ);
00207                 tsap->mSize = vf.getSize();
00208                 status = LLTS_OK;
00209         }
00210         else
00211         {
00212                 // Uh oh, something bad happened when we tried to get this asset!
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         // *FIX: Make this list smaller.
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         // *FIX: Make this list smaller.
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 }

Generated on Thu Jul 1 06:09:23 2010 for Second Life Viewer by  doxygen 1.4.7