llviewerassetstorage.cpp

Go to the documentation of this file.
00001 
00033 #include "linden_common.h"
00034 #include "llviewerprecompiledheaders.h"
00035 
00036 #include "llagent.h"
00037 #include "llviewerassetstorage.h"
00038 #include "llviewerbuild.h"
00039 #include "llvfile.h"
00040 #include "llvfs.h"
00041 
00042 LLViewerAssetStorage::LLViewerAssetStorage(LLMessageSystem *msg, LLXferManager *xfer,
00043                                                                                    LLVFS *vfs, const LLHost &upstream_host)
00044                 : LLAssetStorage(msg, xfer, vfs, upstream_host)
00045 {
00046 }
00047 
00048 
00049 LLViewerAssetStorage::LLViewerAssetStorage(LLMessageSystem *msg, LLXferManager *xfer,
00050                                                                                    LLVFS *vfs)
00051                 : LLAssetStorage(msg, xfer, vfs)
00052 {
00053 }
00054 
00055 // virtual 
00056 void LLViewerAssetStorage::storeAssetData(
00057         const LLTransactionID& tid,
00058         LLAssetType::EType asset_type,
00059         LLStoreAssetCallback callback,
00060         void* user_data,
00061         bool temp_file,
00062         bool is_priority,
00063         bool store_local,
00064         bool user_waiting,
00065         F64 timeout)
00066 {
00067         LLAssetID asset_id = tid.makeAssetID(gAgent.getSecureSessionID());
00068         llinfos << "LLViewerAssetStorage::storeAssetData (legacy) " << tid << ":" << LLAssetType::lookup(asset_type)
00069                         << " ASSET_ID: " << asset_id << llendl;
00070         
00071         if (mUpstreamHost.isOk())
00072         {
00073                 if (mVFS->getExists(asset_id, asset_type))
00074                 {
00075                         // Pack data into this packet if we can fit it.
00076                         U8 buffer[MTUBYTES];
00077                         buffer[0] = 0;
00078 
00079                         LLVFile vfile(mVFS, asset_id, asset_type, LLVFile::READ);
00080                         S32 asset_size = vfile.getSize();
00081 
00082                         LLAssetRequest *req = new LLAssetRequest(asset_id, asset_type);
00083                         req->mUpCallback = callback;
00084                         req->mUserData = user_data;
00085 
00086                         if (asset_size < 1)
00087                         {
00088                                 // This can happen if there's a bug in our code or if the VFS has been corrupted.
00089                                 llwarns << "LLViewerAssetStorage::storeAssetData()  Data _should_ already be in the VFS, but it's not! " << asset_id << llendl;
00090 
00091                                 delete req;
00092                                 if (callback)
00093                                 {
00094                                         callback(asset_id, user_data, LL_ERR_ASSET_REQUEST_FAILED, LL_EXSTAT_VFS_CORRUPT);
00095                                 }
00096                                 return;
00097                         }
00098                         else if(is_priority)
00099                         {
00100                                 mPendingUploads.push_front(req);
00101                         }
00102                         else
00103                         {
00104                                 mPendingUploads.push_back(req);
00105                         }
00106 
00107                         // Read the data from the VFS if it'll fit in this packet.
00108                         if (asset_size + 100 < MTUBYTES)
00109                         {
00110                                 BOOL res = vfile.read(buffer, asset_size);              /* Flawfinder: ignore */
00111                                 S32 bytes_read = res ? vfile.getLastBytesRead() : 0;
00112                                 
00113                                 if( bytes_read == asset_size )
00114                                 {
00115                                         req->mDataSentInFirstPacket = TRUE;
00116                                         //llinfos << "LLViewerAssetStorage::createAsset sending data in first packet" << llendl;
00117                                 }
00118                                 else
00119                                 {
00120                                         llwarns << "Probable corruption in VFS file, aborting store asset data" << llendl;
00121                                         if (callback)
00122                                         {
00123                                                 callback(asset_id, user_data, LL_ERR_ASSET_REQUEST_NONEXISTENT_FILE, LL_EXSTAT_VFS_CORRUPT);
00124                                         }
00125                                         return;
00126                                 }
00127                         }
00128                         else
00129                         {
00130                                 // Too big, do an xfer
00131                                 buffer[0] = 0;
00132                                 asset_size = 0;
00133                         }
00134                         mMessageSys->newMessageFast(_PREHASH_AssetUploadRequest);
00135                         mMessageSys->nextBlockFast(_PREHASH_AssetBlock);
00136                         mMessageSys->addUUIDFast(_PREHASH_TransactionID, tid);
00137                         mMessageSys->addS8Fast(_PREHASH_Type, (S8)asset_type);
00138                         mMessageSys->addBOOLFast(_PREHASH_Tempfile, temp_file);
00139                         mMessageSys->addBOOLFast(_PREHASH_StoreLocal, store_local);
00140                         mMessageSys->addBinaryDataFast( _PREHASH_AssetData, buffer, asset_size );
00141                         mMessageSys->sendReliable(mUpstreamHost);
00142                 }
00143                 else
00144                 {
00145                         llwarns << "AssetStorage: attempt to upload non-existent vfile " << asset_id << ":" << LLAssetType::lookup(asset_type) << llendl;
00146                         if (callback)
00147                         {
00148                                 callback(asset_id, user_data,  LL_ERR_ASSET_REQUEST_NONEXISTENT_FILE, LL_EXSTAT_NONEXISTENT_FILE);
00149                         }
00150                 }
00151         }
00152         else
00153         {
00154                 llwarns << "Attempt to move asset store request upstream w/o valid upstream provider" << llendl;
00155                 if (callback)
00156                 {
00157                         callback(asset_id, user_data, LL_ERR_CIRCUIT_GONE, LL_EXSTAT_NO_UPSTREAM);
00158                 }
00159         }
00160 }
00161 
00162 void LLViewerAssetStorage::storeAssetData(
00163         const char* filename,
00164         const LLTransactionID& tid,
00165         LLAssetType::EType asset_type,
00166         LLStoreAssetCallback callback,
00167         void* user_data,
00168         bool temp_file,
00169         bool is_priority,
00170         bool user_waiting,
00171         F64 timeout)
00172 {
00173         if(!filename)
00174         {
00175                 llerrs << "No filename specified" << llendl;
00176                 return;
00177         }
00178         
00179         LLAssetID asset_id = tid.makeAssetID(gAgent.getSecureSessionID());
00180         llinfos << "LLViewerAssetStorage::storeAssetData (legacy)" << asset_id << ":" << LLAssetType::lookup(asset_type) << llendl;
00181 
00182         llinfos << "ASSET_ID: " << asset_id << llendl;
00183 
00184         FILE* fp = LLFile::fopen(filename, "rb");
00185         if (fp)
00186         {
00187                 LLLegacyAssetRequest *legacy = new LLLegacyAssetRequest;
00188                 
00189                 legacy->mUpCallback = callback;
00190                 legacy->mUserData = user_data;
00191 
00192                 LLVFile file(mVFS, asset_id, asset_type, LLVFile::WRITE);
00193 
00194                 fseek(fp, 0, SEEK_END);
00195                 S32 size = ftell(fp);
00196                 fseek(fp, 0, SEEK_SET);
00197 
00198                 file.setMaxSize(size);
00199 
00200                 const S32 buf_size = 65536;
00201                 U8 copy_buf[buf_size];
00202                 while ((size = (S32)fread(copy_buf, 1, buf_size, fp)))
00203                 {
00204                         file.write(copy_buf, size);
00205                 }
00206                 fclose(fp);
00207 
00208                 // if this upload fails, the caller needs to setup a new tempfile for us
00209                 if (temp_file)
00210                 {
00211                         LLFile::remove(filename);
00212                 }
00213                 
00214                 LLViewerAssetStorage::storeAssetData(
00215                         tid,
00216                         asset_type,
00217                         legacyStoreDataCallback,
00218                         (void**)legacy,
00219                         temp_file,
00220                         is_priority);
00221         }
00222         else
00223         {
00224                 if (callback)
00225                 {
00226                         callback(asset_id, user_data, LL_ERR_CANNOT_OPEN_FILE, LL_EXSTAT_BLOCKED_FILE);
00227                 }
00228         }
00229 }

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