PageRenderTime 40ms CodeModel.GetById 17ms app.highlight 17ms RepoModel.GetById 1ms app.codeStats 1ms

/indra/llmessage/lltransfersourcefile.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 174 lines | 113 code | 27 blank | 34 comment | 16 complexity | 5b053788eaa45903f54cce005b17c7a6 MD5 | raw file
  1/** 
  2 * @file lltransfersourcefile.cpp
  3 * @brief Transfer system for sending a file.
  4 *
  5 * $LicenseInfo:firstyear=2006&license=viewerlgpl$
  6 * Second Life Viewer Source Code
  7 * Copyright (C) 2010, Linden Research, Inc.
  8 * 
  9 * This library is free software; you can redistribute it and/or
 10 * modify it under the terms of the GNU Lesser General Public
 11 * License as published by the Free Software Foundation;
 12 * version 2.1 of the License only.
 13 * 
 14 * This library is distributed in the hope that it will be useful,
 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 17 * Lesser General Public License for more details.
 18 * 
 19 * You should have received a copy of the GNU Lesser General Public
 20 * License along with this library; if not, write to the Free Software
 21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 22 * 
 23 * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 24 * $/LicenseInfo$
 25 */
 26
 27#include "linden_common.h"
 28
 29#include "lltransfersourcefile.h"
 30
 31#include "llerror.h"
 32#include "message.h"
 33#include "lldatapacker.h"
 34#include "lldir.h"
 35
 36LLTransferSourceFile::LLTransferSourceFile(const LLUUID &request_id, const F32 priority) :
 37	LLTransferSource(LLTST_FILE, request_id, priority),
 38	mFP(NULL)
 39{
 40}
 41
 42LLTransferSourceFile::~LLTransferSourceFile()
 43{
 44	if (mFP)
 45	{
 46		llerrs << "Destructor called without the completion callback being called!" << llendl;
 47	}
 48}
 49
 50void LLTransferSourceFile::initTransfer()
 51{
 52	std::string filename = mParams.getFilename();
 53	std::string delimiter = gDirUtilp->getDirDelimiter();
 54
 55	if((filename == ".")
 56	   || (filename == "..")
 57	   || (filename.find(delimiter[0]) != std::string::npos))
 58	{
 59		llwarns << "Attempting to transfer file " << filename << " with path delimiter, aborting!" << llendl;
 60
 61		sendTransferStatus(LLTS_ERROR);
 62		return;
 63	}
 64	// Look for the file.
 65	mFP = LLFile::fopen(mParams.getFilename(), "rb");		/* Flawfinder: ignore */
 66	if (!mFP)
 67	{
 68		sendTransferStatus(LLTS_ERROR);
 69		return;
 70	}
 71
 72	// Get the size of the file using the hack from
 73	fseek(mFP,0,SEEK_END);
 74	mSize = ftell(mFP);
 75	fseek(mFP,0,SEEK_SET);
 76
 77	sendTransferStatus(LLTS_OK);
 78}
 79
 80F32 LLTransferSourceFile::updatePriority()
 81{
 82	return 0.f;
 83}
 84
 85LLTSCode LLTransferSourceFile::dataCallback(const S32 packet_id,
 86											const S32 max_bytes,
 87											U8 **data_handle,
 88											S32 &returned_bytes,
 89											BOOL &delete_returned)
 90{
 91	//llinfos << "LLTransferSourceFile::dataCallback" << llendl;
 92
 93	if (!mFP)
 94	{
 95		llerrs << "Data callback without file set!" << llendl;
 96		return LLTS_ERROR;
 97	}
 98
 99	if (packet_id != mLastPacketID + 1)
100	{
101		llerrs << "Can't handle out of order file transfer yet!" << llendl;
102	}
103
104	// Grab up until the max number of bytes from the file.
105	delete_returned = TRUE;
106	U8 *tmpp = new U8[max_bytes];
107	*data_handle = tmpp;
108	returned_bytes = (S32)fread(tmpp, 1, max_bytes, mFP);
109	if (!returned_bytes)
110	{
111		delete[] tmpp;
112		*data_handle = NULL;
113		returned_bytes = 0;
114		delete_returned = FALSE;
115		return LLTS_DONE;
116	}
117
118	return LLTS_OK;
119}
120
121void LLTransferSourceFile::completionCallback(const LLTSCode status)
122{
123	// No matter what happens, all we want to do is close the file pointer if
124	// we've got it open.
125	if (mFP)
126	{
127		fclose(mFP);
128		mFP = NULL;
129
130	}
131	// Delete the file iff the filename begins with "TEMP"
132	if (mParams.getDeleteOnCompletion() && mParams.getFilename().substr(0, 4) == "TEMP")
133	{
134		LLFile::remove(mParams.getFilename());
135	}
136}
137
138void LLTransferSourceFile::packParams(LLDataPacker& dp) const
139{
140	//llinfos << "LLTransferSourceFile::packParams" << llendl;
141	mParams.packParams(dp);
142}
143
144BOOL LLTransferSourceFile::unpackParams(LLDataPacker &dp)
145{
146	//llinfos << "LLTransferSourceFile::unpackParams" << llendl;
147	return mParams.unpackParams(dp);
148}
149
150
151LLTransferSourceParamsFile::LLTransferSourceParamsFile() :
152	LLTransferSourceParams(LLTST_FILE),
153	mDeleteOnCompletion(FALSE)
154{
155}
156
157
158void LLTransferSourceParamsFile::packParams(LLDataPacker &dp) const
159{
160	dp.packString(mFilename, "Filename");
161	dp.packU8((U8)mDeleteOnCompletion, "Delete");
162}
163
164
165BOOL LLTransferSourceParamsFile::unpackParams(LLDataPacker &dp)
166{
167	dp.unpackString(mFilename, "Filename");
168	U8 delete_flag;
169	dp.unpackU8(delete_flag, "Delete");
170	mDeleteOnCompletion = delete_flag;
171
172	llinfos << "Unpacked filename: " << mFilename << llendl;
173	return TRUE;
174}