diff options
| author | Don Kjer <don@lindenlab.com> | 2012-09-20 04:29:17 +0000 | 
|---|---|---|
| committer | Don Kjer <don@lindenlab.com> | 2012-09-20 04:29:17 +0000 | 
| commit | 7153d1db11c00245a379fa9601f092020152ea73 (patch) | |
| tree | 816eb5f9d965379ebc2a4c4b030c2f9f97549726 /indra | |
| parent | 7b75bd089834a84ab5062c96870edeee6fa22861 (diff) | |
Partial rewrite of llifstream and llofstream (Windows implementation pending).  Moved more functionality from llviewerwearable to llwearable
Diffstat (limited to 'indra')
25 files changed, 1392 insertions, 754 deletions
| diff --git a/indra/llappearance/llavatarappearance.h b/indra/llappearance/llavatarappearance.h index 5726ff62d1..4f57335688 100644 --- a/indra/llappearance/llavatarappearance.h +++ b/indra/llappearance/llavatarappearance.h @@ -37,6 +37,7 @@  class LLTexLayerSet;  class LLTexGlobalColor; +class LLTexGlobalColorInfo;  class LLWearableData;  class LLAvatarBoneInfo;  class LLAvatarSkeletonInfo; diff --git a/indra/llappearance/llavatarappearancedefines.h b/indra/llappearance/llavatarappearancedefines.h index e7c94104cc..0351f28429 100644 --- a/indra/llappearance/llavatarappearancedefines.h +++ b/indra/llappearance/llavatarappearancedefines.h @@ -29,9 +29,10 @@  #define LL_AVATARAPPEARANCE_DEFINES_H  #include <vector> -#include "llwearable.h"  #include "lljointpickname.h"  #include "lldictionary.h" +#include "llwearabletype.h" +#include "lluuid.h"  namespace LLAvatarAppearanceDefines  { diff --git a/indra/llappearance/lllocaltextureobject.h b/indra/llappearance/lllocaltextureobject.h index 6f14448cca..9b9f41fd19 100644 --- a/indra/llappearance/lllocaltextureobject.h +++ b/indra/llappearance/lllocaltextureobject.h @@ -32,7 +32,6 @@  #include "llpointer.h"  #include "llgltexture.h" -class LLUUID;  class LLTexLayer;  class LLTexLayerTemplate;  class LLWearable; diff --git a/indra/llappearance/lltexlayer.h b/indra/llappearance/lltexlayer.h index 0d7fad349c..692cfa1a38 100644 --- a/indra/llappearance/lltexlayer.h +++ b/indra/llappearance/lltexlayer.h @@ -36,6 +36,7 @@  class LLAvatarAppearance;  class LLImageTGA;  class LLImageRaw; +class LLLocalTextureObject;  class LLXmlTreeNode;  class LLTexLayerSet;  class LLTexLayerSetInfo; diff --git a/indra/llappearance/lltexturemanagerbridge.h b/indra/llappearance/lltexturemanagerbridge.h index 99c01755d4..4b814b522d 100644 --- a/indra/llappearance/lltexturemanagerbridge.h +++ b/indra/llappearance/lltexturemanagerbridge.h @@ -27,6 +27,7 @@  #ifndef LL_TEXTUREMANAGERBRIDGE_H  #define LL_TEXTUREMANAGERBRIDGE_H +#include "llavatarappearancedefines.h"  #include "llpointer.h"  #include "llgltexture.h" diff --git a/indra/llappearance/llwearable.cpp b/indra/llappearance/llwearable.cpp index 9e73a6669a..78ff510909 100755 --- a/indra/llappearance/llwearable.cpp +++ b/indra/llappearance/llwearable.cpp @@ -62,52 +62,41 @@ LLAssetType::EType LLWearable::getAssetType() const  	return LLWearableType::getAssetType(mType);  } +BOOL LLWearable::exportFile(LLFILE* fp) const +{ +	llofstream ofs(fp); +	return exportStream(ofs); +} +  // virtual -BOOL LLWearable::exportFile(LLFILE* file) const +BOOL LLWearable::exportStream( std::ostream& output_stream ) const  { -	// header and version -	if( fprintf( file, "LLWearable version %d\n", mDefinitionVersion ) < 0 ) -	{ -		return FALSE; -	} +	if (!output_stream.good()) return FALSE; +	// header and version +	output_stream << "LLWearable version " << mDefinitionVersion  << "\n";  	// name -	if( fprintf( file, "%s\n", mName.c_str() ) < 0 ) -	{ -		return FALSE; -	} - +	output_stream << mName << "\n";  	// description -	if( fprintf( file, "%s\n", mDescription.c_str() ) < 0 ) -	{ -		return FALSE; -	} -	 +	output_stream << mDescription << "\n"; +  	// permissions -	if( !mPermissions.exportFile( file ) ) +	if( !mPermissions.exportStream( output_stream ) )  	{  		return FALSE;  	}  	// sale info -	if( !mSaleInfo.exportFile( file ) ) +	if( !mSaleInfo.exportStream( output_stream ) )  	{  		return FALSE;  	}  	// wearable type -	S32 type = (S32)mType; -	if( fprintf( file, "type %d\n", type ) < 0 ) -	{ -		return FALSE; -	} +	output_stream << "type " << (S32) getType() << "\n";  	// parameters -	S32 num_parameters = mVisualParamIndexMap.size(); -	if( fprintf( file, "parameters %d\n", num_parameters ) < 0 ) -	{ -		return FALSE; -	} +	output_stream << "parameters " << mVisualParamIndexMap.size() << "\n";  	for (visual_param_index_map_t::const_iterator iter = mVisualParamIndexMap.begin();  		 iter != mVisualParamIndexMap.end();  @@ -116,27 +105,17 @@ BOOL LLWearable::exportFile(LLFILE* file) const  		S32 param_id = iter->first;  		const LLVisualParam* param = iter->second;  		F32 param_weight = param->getWeight(); -		if( fprintf( file, "%d %s\n", param_id, terse_F32_to_string( param_weight ).c_str() ) < 0 ) -		{ -			return FALSE; -		} +		output_stream << param_id << " " << terse_F32_to_string( param_weight ) << "\n";  	}  	// texture entries -	S32 num_textures = mTEMap.size(); -	if( fprintf( file, "textures %d\n", num_textures ) < 0 ) -	{ -			return FALSE; -	} +	output_stream << "textures " << mTEMap.size() << "\n";  	for (te_map_t::const_iterator iter = mTEMap.begin(); iter != mTEMap.end(); ++iter)  	{  			S32 te = iter->first;  			const LLUUID& image_id = iter->second->getID(); -			if( fprintf( file, "%d %s\n", te, image_id.asString().c_str()) < 0 ) -			{ -					return FALSE; -			} +			output_stream << te << " " << image_id << "\n";  	}  	return TRUE;  } @@ -195,29 +174,49 @@ void LLWearable::createLayers(S32 te, LLAvatarAppearance *avatarp)  	}  } +LLWearable::EImportResult LLWearable::importFile(LLFILE* fp, LLAvatarAppearance* avatarp ) +{ +	llifstream ifs(fp); +	return importStream(ifs, avatarp); +} +  // virtual -LLWearable::EImportResult LLWearable::importFile( LLFILE* file, LLAvatarAppearance* avatarp ) +LLWearable::EImportResult LLWearable::importStream( std::istream& input_stream, LLAvatarAppearance* avatarp )  {  	// *NOTE: changing the type or size of this buffer will require -	// changes in the fscanf() code below. You would be better off -	// rewriting this to use streams and not require an open FILE. -	char text_buffer[2048];		/* Flawfinder: ignore */ -	S32 fields_read = 0; +	// changes in the fscanf() code below. +	// We are using a local max buffer size here to avoid issues +	// if MAX_STRING size changes. +	const U32 PARSE_BUFFER_SIZE = 2048; +	char buffer[2048];		/* Flawfinder: ignore */ +	char uuid_buffer[37];	/* Flawfinder: ignore */ + +	// This data is being generated on the viewer. +	// Impose some sane limits on parameter and texture counts. +	const S32 MAX_WEARABLE_ASSET_TEXTURES = 100; +	const S32 MAX_WEARABLE_ASSET_PARAMETERS = 1000; -	// read header and version  -	fields_read = fscanf( file, "LLWearable version %d\n", &mDefinitionVersion ); -	if( fields_read != 1 ) +	if(!avatarp)  	{ -		return LLWearable::BAD_HEADER; +		return LLWearable::FAILURE;  	} -	if(!avatarp) +	// read header and version  +	if (!input_stream.good())  	{ +		llwarns << "Failed to read wearable asset input stream." << llendl;  		return LLWearable::FAILURE;  	} +	input_stream.getline(buffer, PARSE_BUFFER_SIZE); +	if ( 1 != sscanf( /* Flawfinder: ignore */ +				buffer, +				"LLWearable version %d\n", +				&mDefinitionVersion ) ) +	{ +		return LLWearable::BAD_HEADER; +	} - -	// Temporary hack to allow wearables with definition version 24 to still load. +	// Hack to allow wearables with definition version 24 to still load.  	// This should only affect lindens and NDA'd testers who have saved wearables in 2.0  	// the extra check for version == 24 can be removed before release, once internal testers  	// have loaded these wearables again. See hack pt 2 at bottom of function to ensure that @@ -229,68 +228,58 @@ LLWearable::EImportResult LLWearable::importFile( LLFILE* file, LLAvatarAppearan  	}  	// name -	int next_char = fgetc( file );		/* Flawfinder: ignore */ -	if( '\n' == next_char ) -	{ -		// no name -		mName = ""; -	} -	else +	if (!input_stream.good())  	{ -		ungetc( next_char, file ); -		fields_read = fscanf(	/* Flawfinder: ignore */ -			file, -			"%2047[^\n]", -			text_buffer); -		if( (1 != fields_read) || (fgetc( file ) != '\n') )		/* Flawfinder: ignore */ -		{ -			llwarns << "Bad Wearable asset: early end of file" << llendl; -			return LLWearable::FAILURE; -		} -		mName = text_buffer; +		llwarns << "Bad Wearable asset: early end of input stream "  +				<< "while reading name" << llendl; +		return LLWearable::FAILURE;  	} +	input_stream.getline(buffer, PARSE_BUFFER_SIZE); +	mName = buffer;  	// description -	next_char = fgetc( file );		/* Flawfinder: ignore */ -	if( '\n' == next_char ) +	if (!input_stream.good())  	{ -		// no description -		mDescription = ""; -	} -	else -	{ -		ungetc( next_char, file ); -		fields_read = fscanf(	/* Flawfinder: ignore */ -			file, -			"%2047[^\n]", -			text_buffer ); -		if( (1 != fields_read) || (fgetc( file ) != '\n') )		/* Flawfinder: ignore */ -		{ -			llwarns << "Bad Wearable asset: early end of file" << llendl; -			return LLWearable::FAILURE; -		} -		mDescription = text_buffer; +		llwarns << "Bad Wearable asset: early end of input stream "  +				<< "while reading description" << llendl; +		return LLWearable::FAILURE;  	} +	input_stream.getline(buffer, PARSE_BUFFER_SIZE); +	mDescription = buffer;  	// permissions -	S32 perm_version; -	fields_read = fscanf( file, " permissions %d\n", &perm_version ); -	if( (fields_read != 1) || (perm_version != 0) ) +	if (!input_stream.good()) +	{ +		llwarns << "Bad Wearable asset: early end of input stream "  +				<< "while reading permissions" << llendl; +		return LLWearable::FAILURE; +	} +	input_stream.getline(buffer, PARSE_BUFFER_SIZE); +	S32 perm_version = -1; +	if ( 1 != sscanf( buffer, " permissions %d\n", &perm_version ) || +		 perm_version != 0 )  	{ -		llwarns << "Bad Wearable asset: missing permissions" << llendl; +		llwarns << "Bad Wearable asset: missing valid permissions" << llendl;  		return LLWearable::FAILURE;  	} -	if( !mPermissions.importFile( file ) ) +	if( !mPermissions.importStream( input_stream ) )  	{  		return LLWearable::FAILURE;  	}  	// sale info -	S32 sale_info_version; -	fields_read = fscanf( file, " sale_info %d\n", &sale_info_version ); -	if( (fields_read != 1) || (sale_info_version != 0) ) +	if (!input_stream.good())  	{ -		llwarns << "Bad Wearable asset: missing sale_info" << llendl; +		llwarns << "Bad Wearable asset: early end of input stream "  +				<< "while reading sale info" << llendl; +		return LLWearable::FAILURE; +	} +	input_stream.getline(buffer, PARSE_BUFFER_SIZE); +	S32 sale_info_version = -1; +	if ( 1 != sscanf( buffer, " sale_info %d\n", &sale_info_version ) || +		sale_info_version != 0 ) +	{ +		llwarns << "Bad Wearable asset: missing valid sale_info" << llendl;  		return LLWearable::FAILURE;  	}  	// Sale info used to contain next owner perm. It is now in the @@ -299,7 +288,7 @@ LLWearable::EImportResult LLWearable::importFile( LLFILE* file, LLAvatarAppearan  	// up the vast majority of the tasks.  	BOOL has_perm_mask = FALSE;  	U32 perm_mask = 0; -	if( !mSaleInfo.importFile(file, has_perm_mask, perm_mask) ) +	if( !mSaleInfo.importStream(input_stream, has_perm_mask, perm_mask) )  	{  		return LLWearable::FAILURE;  	} @@ -314,9 +303,15 @@ LLWearable::EImportResult LLWearable::importFile( LLFILE* file, LLAvatarAppearan  	}  	// wearable type +	if (!input_stream.good()) +	{ +		llwarns << "Bad Wearable asset: early end of input stream "  +				<< "while reading type" << llendl; +		return LLWearable::FAILURE; +	} +	input_stream.getline(buffer, PARSE_BUFFER_SIZE);  	S32 type = -1; -	fields_read = fscanf( file, "type %d\n", &type ); -	if( fields_read != 1 ) +	if ( 1 != sscanf( buffer, "type %d\n", &type ) )  	{  		llwarns << "Bad Wearable asset: bad type" << llendl;  		return LLWearable::FAILURE; @@ -333,27 +328,48 @@ LLWearable::EImportResult LLWearable::importFile( LLFILE* file, LLAvatarAppearan  	}  	// parameters header -	S32 num_parameters = 0; -	fields_read = fscanf( file, "parameters %d\n", &num_parameters ); -	if( fields_read != 1 ) +	if (!input_stream.good()) +	{ +		llwarns << "Bad Wearable asset: early end of input stream "  +				<< "while reading parameters header" << llendl; +		return LLWearable::FAILURE; +	} +	input_stream.getline(buffer, PARSE_BUFFER_SIZE); +	S32 num_parameters = -1; +	if ( 1 != sscanf( buffer, "parameters %d\n", &num_parameters ) )  	{  		llwarns << "Bad Wearable asset: missing parameters block" << llendl;  		return LLWearable::FAILURE;  	} - +	if ( num_parameters > MAX_WEARABLE_ASSET_PARAMETERS ) +	{ +		llwarns << "Bad Wearable asset: too many parameters, " +				<< num_parameters << llendl; +		return LLWearable::FAILURE; +	}  	if( num_parameters != mVisualParamIndexMap.size() )  	{ -		llwarns << "Wearable parameter mismatch. Reading in " << num_parameters << " from file, but created " << mVisualParamIndexMap.size() << " from avatar parameters. type: " <<  mType << llendl; +		llwarns << "Wearable parameter mismatch. Reading in "  +				<< num_parameters << " from file, but created "  +				<< mVisualParamIndexMap.size()  +				<< " from avatar parameters. type: "  +				<<  getType() << llendl;  	}  	// parameters  	S32 i;  	for( i = 0; i < num_parameters; i++ )  	{ +		if (!input_stream.good()) +		{ +			llwarns << "Bad Wearable asset: early end of input stream "  +					<< "while reading parameter #" << i << llendl; +			return LLWearable::FAILURE; +		} +		input_stream.getline(buffer, PARSE_BUFFER_SIZE);  		S32 param_id = 0;  		F32 param_weight = 0.f; -		fields_read = fscanf( file, "%d %f\n", ¶m_id, ¶m_weight ); -		if( fields_read != 2 ) +		if ( 2 != sscanf( buffer, "%d %f\n", ¶m_id, ¶m_weight ) )  		{  			llwarns << "Bad Wearable asset: bad parameter, #" << i << llendl;  			return LLWearable::FAILURE; @@ -362,34 +378,53 @@ LLWearable::EImportResult LLWearable::importFile( LLFILE* file, LLAvatarAppearan  	}  	// textures header -	S32 num_textures = 0; -	fields_read = fscanf( file, "textures %d\n", &num_textures); -	if( fields_read != 1 ) +	if (!input_stream.good()) +	{ +		llwarns << "Bad Wearable asset: early end of input stream "  +				<< "while reading textures header" << i << llendl; +		return LLWearable::FAILURE; +	} +	input_stream.getline(buffer, PARSE_BUFFER_SIZE); +	S32 num_textures = -1; +	if ( 1 != sscanf( buffer, "textures %d\n", &num_textures) )  	{  		llwarns << "Bad Wearable asset: missing textures block" << llendl;  		return LLWearable::FAILURE;  	} +	if ( num_textures > MAX_WEARABLE_ASSET_TEXTURES ) +	{ +		llwarns << "Bad Wearable asset: too many textures, " +				<< num_textures << llendl; +		return LLWearable::FAILURE; +	}  	// textures  	for( i = 0; i < num_textures; i++ )  	{ +		if (!input_stream.good()) +		{ +			llwarns << "Bad Wearable asset: early end of input stream "  +					<< "while reading textures #" << i << llendl; +			return LLWearable::FAILURE; +		} +		input_stream.getline(buffer, PARSE_BUFFER_SIZE);  		S32 te = 0; -		fields_read = fscanf(   /* Flawfinder: ignore */ -				file, -				"%d %2047s\n", -				&te, text_buffer); -		if( fields_read != 2 ) +		if ( 2 != sscanf(   /* Flawfinder: ignore */ +				buffer, +				"%d %36s\n", +				&te, uuid_buffer) )  		{  				llwarns << "Bad Wearable asset: bad texture, #" << i << llendl;  				return LLWearable::FAILURE;  		} -		if( !LLUUID::validate( text_buffer ) ) +		if( !LLUUID::validate( uuid_buffer ) )  		{ -				llwarns << "Bad Wearable asset: bad texture uuid: " << text_buffer << llendl; +				llwarns << "Bad Wearable asset: bad texture uuid: "  +						<< uuid_buffer << llendl;  				return LLWearable::FAILURE;  		} -		LLUUID id = LLUUID(text_buffer); +		LLUUID id = LLUUID(uuid_buffer);  		LLGLTexture* image = gTextureManagerBridgep->getFetchedTexture( id );  		if( mTEMap.find(te) != mTEMap.end() )  		{ @@ -400,12 +435,15 @@ LLWearable::EImportResult LLWearable::importFile( LLFILE* file, LLAvatarAppearan  				delete mSavedTEMap[te];  		} -		LLUUID textureid(text_buffer); +		LLUUID textureid(uuid_buffer);  		mTEMap[te] = new LLLocalTextureObject(image, textureid);  		mSavedTEMap[te] = new LLLocalTextureObject(image, textureid);  		createLayers(te, avatarp);  	} +	// copy all saved param values to working params +	revertValues(); +  	return LLWearable::SUCCESS;  } @@ -417,6 +455,171 @@ void LLWearable::setType(LLWearableType::EType type, LLAvatarAppearance *avatarp  } +LLLocalTextureObject* LLWearable::getLocalTextureObject(S32 index) +{ +	te_map_t::iterator iter = mTEMap.find(index); +	if( iter != mTEMap.end() ) +	{ +		LLLocalTextureObject* lto = iter->second; +		return lto; +	} +	return NULL; +} + +const LLLocalTextureObject* LLWearable::getLocalTextureObject(S32 index) const +{ +	te_map_t::const_iterator iter = mTEMap.find(index); +	if( iter != mTEMap.end() ) +	{ +		const LLLocalTextureObject* lto = iter->second; +		return lto; +	} +	return NULL; +} + +std::vector<LLLocalTextureObject*> LLWearable::getLocalTextureListSeq() +{ +	std::vector<LLLocalTextureObject*> result; + +	for(te_map_t::const_iterator iter = mTEMap.begin(); +		iter != mTEMap.end(); iter++) +	{ +		LLLocalTextureObject* lto = iter->second; +		result.push_back(lto); +	} + +	return result; +} + +void LLWearable::setLocalTextureObject(S32 index, LLLocalTextureObject <o) +{ +	if( mTEMap.find(index) != mTEMap.end() ) +	{ +		mTEMap.erase(index); +	} +	mTEMap[index] = new LLLocalTextureObject(lto); +} + +void LLWearable::revertValues() +{ +	//update saved settings so wearable is no longer dirty +	// non-driver params first +	for (param_map_t::const_iterator iter = mSavedVisualParamMap.begin(); iter != mSavedVisualParamMap.end(); iter++) +	{ +		S32 id = iter->first; +		F32 value = iter->second; +		LLVisualParam *param = getVisualParam(id); +		if(param &&  !dynamic_cast<LLDriverParam*>(param) ) +		{ +			setVisualParamWeight(id, value, TRUE); +		} +	} + +	//then driver params +	for (param_map_t::const_iterator iter = mSavedVisualParamMap.begin(); iter != mSavedVisualParamMap.end(); iter++) +	{ +		S32 id = iter->first; +		F32 value = iter->second; +		LLVisualParam *param = getVisualParam(id); +		if(param &&  dynamic_cast<LLDriverParam*>(param) ) +		{ +			setVisualParamWeight(id, value, TRUE); +		} +	} + +	// make sure that saved values are sane +	for (param_map_t::const_iterator iter = mSavedVisualParamMap.begin(); iter != mSavedVisualParamMap.end(); iter++) +	{ +		S32 id = iter->first; +		LLVisualParam *param = getVisualParam(id); +		if( param ) +		{ +			mSavedVisualParamMap[id] = param->getWeight(); +		} +	} + +	syncImages(mSavedTEMap, mTEMap); +} + +void LLWearable::saveValues() +{ +	//update saved settings so wearable is no longer dirty +	mSavedVisualParamMap.clear(); +	for (visual_param_index_map_t::const_iterator iter = mVisualParamIndexMap.begin(); iter != mVisualParamIndexMap.end(); ++iter) +	{ +		S32 id = iter->first; +		LLVisualParam *wearable_param = iter->second; +		F32 value = wearable_param->getWeight(); +		mSavedVisualParamMap[id] = value; +	} + +	// Deep copy of mTEMap (copies only those tes that are current, filling in defaults where needed) +	syncImages(mTEMap, mSavedTEMap); +} + +void LLWearable::syncImages(te_map_t &src, te_map_t &dst) +{ +	// Deep copy of src (copies only those tes that are current, filling in defaults where needed) +	for( S32 te = 0; te < TEX_NUM_INDICES; te++ ) +	{ +		if (LLAvatarAppearanceDictionary::getTEWearableType((ETextureIndex) te) == mType) +		{ +			te_map_t::const_iterator iter = src.find(te); +			LLUUID image_id; +			LLGLTexture *image = NULL; +			LLLocalTextureObject *lto = NULL; +			if(iter != src.end()) +			{ +				// there's a Local Texture Object in the source image map. Use this to populate the values to store in the destination image map. +				lto = iter->second; +				image = lto->getImage(); +				image_id = lto->getID(); +			} +			else +			{ +				// there is no Local Texture Object in the source image map. Get defaults values for populating the destination image map. +				image_id = getDefaultTextureImageID((ETextureIndex) te); +				image = gTextureManagerBridgep->getFetchedTexture( image_id ); +			} + +			if( dst.find(te) != dst.end() ) +			{ +				// there's already an entry in the destination map for the texture. Just update its values. +				dst[te]->setImage(image); +				dst[te]->setID(image_id); +			} +			else +			{ +				// no entry found in the destination map, we need to create a new Local Texture Object +				dst[te] = new LLLocalTextureObject(image, image_id); +			} + +			if( lto ) +			{ +				// If we pulled values from a Local Texture Object in the source map, make sure the proper flags are set in the new (or updated) entry in the destination map. +				dst[te]->setBakedReady(lto->getBakedReady()); +				dst[te]->setDiscard(lto->getDiscard()); +			} +		} +	} +} + +void LLWearable::destroyTextures() +{ +	for( te_map_t::iterator iter = mTEMap.begin(); iter != mTEMap.end(); ++iter ) +	{ +		LLLocalTextureObject *lto = iter->second; +		delete lto; +	} +	mTEMap.clear(); +	for( te_map_t::iterator iter = mSavedTEMap.begin(); iter != mSavedTEMap.end(); ++iter ) +	{ +		LLLocalTextureObject *lto = iter->second; +		delete lto; +	} +	mSavedTEMap.clear(); +} +  void LLWearable::addVisualParam(LLVisualParam *param)  {  	if( mVisualParamIndexMap[param->getID()] ) diff --git a/indra/llappearance/llwearable.h b/indra/llappearance/llwearable.h index b8bbf82a6e..bc73ed4d8c 100644 --- a/indra/llappearance/llwearable.h +++ b/indra/llappearance/llwearable.h @@ -27,6 +27,7 @@  #ifndef LL_LLWEARABLE_H  #define LL_LLWEARABLE_H +#include "llavatarappearancedefines.h"  #include "llextendedstatus.h"  #include "llpermissions.h"  #include "llsaleinfo.h" @@ -79,14 +80,19 @@ public:  		SUCCESS,  		BAD_HEADER  	}; -	virtual BOOL				exportFile(LLFILE* file) const; -	virtual EImportResult		importFile(LLFILE* file, LLAvatarAppearance* avatarp); - - +	BOOL				exportFile(LLFILE* file) const; +	EImportResult		importFile(LLFILE* file, LLAvatarAppearance* avatarp ); +	virtual BOOL				exportStream( std::ostream& output_stream ) const; +	virtual EImportResult		importStream( std::istream& input_stream, LLAvatarAppearance* avatarp );  	static void			setCurrentDefinitionVersion( S32 version ) { LLWearable::sCurrentDefinitionVersion = version; } +	virtual LLUUID		getDefaultTextureImageID(LLAvatarAppearanceDefines::ETextureIndex index) const = 0; + +	LLLocalTextureObject* getLocalTextureObject(S32 index); +	const LLLocalTextureObject* getLocalTextureObject(S32 index) const; +	std::vector<LLLocalTextureObject*> getLocalTextureListSeq(); -	virtual LLLocalTextureObject* getLocalTextureObject(S32 index) = 0; +	void				setLocalTextureObject(S32 index, LLLocalTextureObject <o);  	void				addVisualParam(LLVisualParam *param);  	void 				setVisualParamWeight(S32 index, F32 value, BOOL upload_bake);  	F32					getVisualParamWeight(S32 index) const; @@ -97,6 +103,9 @@ public:  	LLColor4			getClothesColor(S32 te) const;  	void 				setClothesColor( S32 te, const LLColor4& new_color, BOOL upload_bake ); +	virtual void		revertValues(); +	virtual void		saveValues(); +  	// Something happened that requires the wearable to be updated (e.g. worn/unworn).  	virtual void		setUpdated() const = 0; @@ -104,6 +113,9 @@ public:  	virtual void		addToBakedTextureHash(LLMD5& hash) const = 0;  protected: +	typedef std::map<S32, LLLocalTextureObject*> te_map_t; +	void				syncImages(te_map_t &src, te_map_t &dst); +	void				destroyTextures();  	void			 	createVisualParams(LLAvatarAppearance *avatarp);  	void 				createLayers(S32 te, LLAvatarAppearance *avatarp); @@ -121,7 +133,6 @@ protected:  	typedef std::map<S32, LLVisualParam *>    visual_param_index_map_t;  	visual_param_index_map_t mVisualParamIndexMap; -	typedef std::map<S32, LLLocalTextureObject*> te_map_t;  	te_map_t mTEMap;				// maps TE to LocalTextureObject  	te_map_t mSavedTEMap;			// last saved version of TEMap  }; diff --git a/indra/llappearance/llwearabledata.h b/indra/llappearance/llwearabledata.h index 2931424131..379384a989 100644 --- a/indra/llappearance/llwearabledata.h +++ b/indra/llappearance/llwearabledata.h @@ -28,6 +28,7 @@  #define LL_WEARABLEDATA_H  #include "llavatarappearancedefines.h" +#include "llwearable.h"  #include "llerror.h"  class LLAvatarAppearance; diff --git a/indra/llcommon/lldictionary.h b/indra/llcommon/lldictionary.h index bc3bc3e74a..c752859a36 100644 --- a/indra/llcommon/lldictionary.h +++ b/indra/llcommon/lldictionary.h @@ -30,6 +30,8 @@  #include <map>  #include <string> +#include "llerror.h" +  struct LL_COMMON_API LLDictionaryEntry  {  	LLDictionaryEntry(const std::string &name); diff --git a/indra/llcommon/llfile.cpp b/indra/llcommon/llfile.cpp index c51d042a3d..38b0dfdaf1 100644 --- a/indra/llcommon/llfile.cpp +++ b/indra/llcommon/llfile.cpp @@ -56,6 +56,8 @@ std::string strerr(int errn)  	return buffer;  } +typedef std::basic_ios<char,std::char_traits < char > > _Myios; +  #else  // On Posix we want to call strerror_r(), but alarmingly, there are two  // different variants. The one that returns int always populates the passed @@ -324,9 +326,10 @@ const char *LLFile::tmpdir()  /***************** Modified file stream created to overcome the incorrect behaviour of posix fopen in windows *******************/ -#if USE_LLFILESTREAMS +#if LL_WINDOWS -LLFILE *	LLFile::_Fiopen(const std::string& filename, std::ios::openmode mode,int)	// protection currently unused +LLFILE *	LLFile::_Fiopen(const std::string& filename,  +		std::ios::openmode mode,int)	// protection currently unused  {	// open a file  	static const char *mods[] =  	{	// fopen mode strings corresponding to valid[i] @@ -385,117 +388,677 @@ LLFILE *	LLFile::_Fiopen(const std::string& filename, std::ios::openmode mode,in  	return (0);  } -/************** input file stream ********************************/ +#endif /* LL_WINDOWS */ -void llifstream::close() -{	// close the C stream -	if (_Filebuffer && _Filebuffer->close() == 0) +/************** llstdio file buffer ********************************/ + + +//llstdio_filebuf* llstdio_filebuf::open(const char *_Filename, +//	ios_base::openmode _Mode) +//{ +//#if LL_WINDOWS +//	_Filet *_File; +//	if (is_open() || (_File = LLFILE::_Fiopen(_Filename, _Mode)) == 0) +//		return (0);	// open failed +// +//	_Init(_File, _Openfl); +//	_Initcvt(&_USE(_Mysb::getloc(), _Cvt)); +//	return (this);	// open succeeded +//#else +//	std::filebuf* _file = std::filebuf::open(_Filename, _Mode); +//	if (NULL == _file) return NULL; +//	return this; +//#endif +//} + +llstdio_filebuf::int_type llstdio_filebuf::overflow(llstdio_filebuf::int_type __c) +{ +	int_type __ret = traits_type::eof(); +	const bool __testeof = traits_type::eq_int_type(__c, __ret); +	const bool __testout = _M_mode & ios_base::out; +	if (__testout && !_M_reading)  	{ -		_Myios::setstate(ios_base::failbit);	/*Flawfinder: ignore*/ +		if (this->pbase() < this->pptr()) +		{ +			// If appropriate, append the overflow char. +			if (!__testeof) +			{ +				*this->pptr() = traits_type::to_char_type(__c); +				this->pbump(1); +			} + +			// Convert pending sequence to external representation, +			// and output. +			if (_convert_to_external(this->pbase(), +					 this->pptr() - this->pbase())) +			{ +				_M_set_buffer(0); +				__ret = traits_type::not_eof(__c); +			} +		} +		else if (_M_buf_size > 1) +		{ +			// Overflow in 'uncommitted' mode: set _M_writing, set +			// the buffer to the initial 'write' mode, and put __c +			// into the buffer. +			_M_set_buffer(0); +			_M_writing = true; +			if (!__testeof) +			{ +				*this->pptr() = traits_type::to_char_type(__c); +				this->pbump(1); +			} +			__ret = traits_type::not_eof(__c); +		} +		else +		{ +			// Unbuffered. +			char_type __conv = traits_type::to_char_type(__c); +			if (__testeof || _convert_to_external(&__conv, 1)) +			{ +				_M_writing = true; +				__ret = traits_type::not_eof(__c); +			} +		}  	} +	return __ret;  } -void llifstream::open(const std::string& _Filename,	/* Flawfinder: ignore */ -	ios_base::openmode _Mode, -	int _Prot) -{	// open a C stream with specified mode +bool llstdio_filebuf::_convert_to_external(char_type* __ibuf, +						std::streamsize __ilen) +{ +	// Sizes of external and pending output. +	streamsize __elen; +	streamsize __plen; +	if (__check_facet(_M_codecvt).always_noconv()) +	{ +		//__elen = _M_file.xsputn(reinterpret_cast<char*>(__ibuf), __ilen); +		__elen = fwrite(reinterpret_cast<void*>(__ibuf), 1, +						__ilen, _M_file.file()); +		__plen = __ilen; +	} +	else +	{ +		// Worst-case number of external bytes needed. +		// XXX Not done encoding() == -1. +		streamsize __blen = __ilen * _M_codecvt->max_length(); +		char* __buf = static_cast<char*>(__builtin_alloca(__blen)); + +		char* __bend; +		const char_type* __iend; +		codecvt_base::result __r; +		__r = _M_codecvt->out(_M_state_cur, __ibuf, __ibuf + __ilen, +				__iend, __buf, __buf + __blen, __bend); -	LLFILE* filep = LLFile::_Fiopen(_Filename,_Mode | ios_base::in, _Prot); -	if(filep == NULL) +		if (__r == codecvt_base::ok || __r == codecvt_base::partial) +			__blen = __bend - __buf; +		else if (__r == codecvt_base::noconv) +		{ +			// Same as the always_noconv case above. +			__buf = reinterpret_cast<char*>(__ibuf); +			__blen = __ilen; +		} +		else +			__throw_ios_failure(__N("llstdio_filebuf::_convert_to_external " +									"conversion error")); +   +		//__elen = _M_file.xsputn(__buf, __blen); +		__elen = fwrite(__buf, 1, __blen, _M_file.file()); +		__plen = __blen; + +		// Try once more for partial conversions. +		if (__r == codecvt_base::partial && __elen == __plen) +		{ +			const char_type* __iresume = __iend; +			streamsize __rlen = this->pptr() - __iend; +			__r = _M_codecvt->out(_M_state_cur, __iresume, +					__iresume + __rlen, __iend, __buf, +					__buf + __blen, __bend); +			if (__r != codecvt_base::error) +			{ +				__rlen = __bend - __buf; +				//__elen = _M_file.xsputn(__buf, __rlen); +				__elen = fwrite(__buf, 1, __rlen, _M_file.file()); +				__plen = __rlen; +			} +			else +			{ +				__throw_ios_failure(__N("llstdio_filebuf::_convert_to_external " +										"conversion error")); +			} +		} +	} +	return __elen == __plen; +} + +llstdio_filebuf::int_type llstdio_filebuf::underflow() +{ +	int_type __ret = traits_type::eof(); +	const bool __testin = _M_mode & ios_base::in; +	if (__testin)  	{ -		_Myios::setstate(ios_base::failbit);	/*Flawfinder: ignore*/ -		return; +		if (_M_writing) +		{ +			if (overflow() == traits_type::eof()) +			return __ret; +			//_M_set_buffer(-1); +			//_M_writing = false; +		} +		// Check for pback madness, and if so switch back to the +		// normal buffers and jet outta here before expensive +		// fileops happen... +		_M_destroy_pback(); + +		if (this->gptr() < this->egptr()) +			return traits_type::to_int_type(*this->gptr()); + +		// Get and convert input sequence. +		const size_t __buflen = _M_buf_size > 1 ? _M_buf_size - 1 : 1; + +		// Will be set to true if ::fread() returns 0 indicating EOF. +		bool __got_eof = false; +		// Number of internal characters produced. +		streamsize __ilen = 0; +		codecvt_base::result __r = codecvt_base::ok; +		if (__check_facet(_M_codecvt).always_noconv()) +		{ +			//__ilen = _M_file.xsgetn(reinterpret_cast<char*>(this->eback()), +			//			__buflen); +			__ilen = fread(reinterpret_cast<void*>(this->eback()), 1, +						__buflen, _M_file.file()); +			if (__ilen == 0) +				__got_eof = true; +		} +		else +	    { +			// Worst-case number of external bytes. +			// XXX Not done encoding() == -1. +			const int __enc = _M_codecvt->encoding(); +			streamsize __blen; // Minimum buffer size. +			streamsize __rlen; // Number of chars to read. +			if (__enc > 0) +				__blen = __rlen = __buflen * __enc; +			else +			{ +				__blen = __buflen + _M_codecvt->max_length() - 1; +				__rlen = __buflen; +			} +			const streamsize __remainder = _M_ext_end - _M_ext_next; +			__rlen = __rlen > __remainder ? __rlen - __remainder : 0; + +			// An imbue in 'read' mode implies first converting the external +			// chars already present. +			if (_M_reading && this->egptr() == this->eback() && __remainder) +				__rlen = 0; + +			// Allocate buffer if necessary and move unconverted +			// bytes to front. +			if (_M_ext_buf_size < __blen) +			{ +				char* __buf = new char[__blen]; +				if (__remainder) +					__builtin_memcpy(__buf, _M_ext_next, __remainder); + +				delete [] _M_ext_buf; +				_M_ext_buf = __buf; +				_M_ext_buf_size = __blen; +			} +			else if (__remainder) +				__builtin_memmove(_M_ext_buf, _M_ext_next, __remainder); + +			_M_ext_next = _M_ext_buf; +			_M_ext_end = _M_ext_buf + __remainder; +			_M_state_last = _M_state_cur; + +			do +			{ +				if (__rlen > 0) +				{ +					// Sanity check! +					// This may fail if the return value of +					// codecvt::max_length() is bogus. +					if (_M_ext_end - _M_ext_buf + __rlen > _M_ext_buf_size) +					{ +						__throw_ios_failure(__N("llstdio_filebuf::underflow " +							"codecvt::max_length() " +							"is not valid")); +					} +					//streamsize __elen = _M_file.xsgetn(_M_ext_end, __rlen); +					streamsize __elen = fread(_M_ext_end, 1, +						__rlen, _M_file.file()); +					if (__elen == 0) +						__got_eof = true; +					else if (__elen == -1) +					break; +					//_M_ext_end += __elen; +				} + +				char_type* __iend = this->eback(); +				if (_M_ext_next < _M_ext_end) +				{ +					__r = _M_codecvt->in(_M_state_cur, _M_ext_next, +							_M_ext_end, _M_ext_next, +							this->eback(), +							this->eback() + __buflen, __iend); +				} +				if (__r == codecvt_base::noconv) +				{ +					size_t __avail = _M_ext_end - _M_ext_buf; +					__ilen = std::min(__avail, __buflen); +					traits_type::copy(this->eback(), +						reinterpret_cast<char_type*> +						(_M_ext_buf), __ilen); +					_M_ext_next = _M_ext_buf + __ilen; +				} +				else +					__ilen = __iend - this->eback(); + +				// _M_codecvt->in may return error while __ilen > 0: this is +				// ok, and actually occurs in case of mixed encodings (e.g., +				// XML files). +				if (__r == codecvt_base::error) +					break; + +				__rlen = 1; +			} while (__ilen == 0 && !__got_eof); +		} + +		if (__ilen > 0) +		{ +			_M_set_buffer(__ilen); +			_M_reading = true; +			__ret = traits_type::to_int_type(*this->gptr()); +		} +		else if (__got_eof) +		{ +			// If the actual end of file is reached, set 'uncommitted' +			// mode, thus allowing an immediate write without an +			// intervening seek. +			_M_set_buffer(-1); +			_M_reading = false; +			// However, reaching it while looping on partial means that +			// the file has got an incomplete character. +			if (__r == codecvt_base::partial) +				__throw_ios_failure(__N("llstdio_filebuf::underflow " +					"incomplete character in file")); +		} +		else if (__r == codecvt_base::error) +			__throw_ios_failure(__N("llstdio_filebuf::underflow " +					"invalid byte sequence in file")); +		else +			__throw_ios_failure(__N("llstdio_filebuf::underflow " +					"error reading the file"));  	} -	llassert(_Filebuffer == NULL); -	_Filebuffer = new _Myfb(filep); -	_ShouldClose = true; -	_Myios::init(_Filebuffer); +	return __ret;  } -bool llifstream::is_open() const -{	// test if C stream has been opened -	if(_Filebuffer) -		return (_Filebuffer->is_open()); -	return false; +std::streamsize llstdio_filebuf::xsgetn(char_type* __s, std::streamsize __n) +{ +	// Clear out pback buffer before going on to the real deal... +	streamsize __ret = 0; +	if (_M_pback_init) +	{ +		if (__n > 0 && this->gptr() == this->eback()) +		{ +			*__s++ = *this->gptr(); +			this->gbump(1); +			__ret = 1; +			--__n; +		} +		_M_destroy_pback(); +	} +        +	// Optimization in the always_noconv() case, to be generalized in the +	// future: when __n > __buflen we read directly instead of using the +	// buffer repeatedly. +	const bool __testin = _M_mode & ios_base::in; +	const streamsize __buflen = _M_buf_size > 1 ? _M_buf_size - 1 : 1; + +	if (__n > __buflen && __check_facet(_M_codecvt).always_noconv() +		&& __testin && !_M_writing) +	{ +		// First, copy the chars already present in the buffer. +		const streamsize __avail = this->egptr() - this->gptr(); +		if (__avail != 0) +		{ +			if (__avail == 1) +				*__s = *this->gptr(); +			else +				traits_type::copy(__s, this->gptr(), __avail); +			__s += __avail; +			this->gbump(__avail); +			__ret += __avail; +			__n -= __avail; +		} + +		// Need to loop in case of short reads (relatively common +		// with pipes). +		streamsize __len; +		for (;;) +		{ +			//__len = _M_file.xsgetn(reinterpret_cast<char*>(__s), __n); +			__len = fread(reinterpret_cast<void*>(__s), 1,  +						__n, _M_file.file()); +			if (__len == -1) +				__throw_ios_failure(__N("llstdio_filebuf::xsgetn " +										"error reading the file")); +			if (__len == 0) +				break; + +			__n -= __len; +			__ret += __len; +			if (__n == 0) +				break; + +			__s += __len; +		} + +		if (__n == 0) +		{ +			_M_set_buffer(0); +			_M_reading = true; +		} +		else if (__len == 0) +		{ +			// If end of file is reached, set 'uncommitted' +			// mode, thus allowing an immediate write without +			// an intervening seek. +			_M_set_buffer(-1); +			_M_reading = false; +		} +	} +	else +		__ret += __streambuf_type::xsgetn(__s, __n); + +	return __ret;  } -llifstream::~llifstream() + +std::streamsize llstdio_filebuf::xsputn(char_type* __s, std::streamsize __n)  { -	if (_ShouldClose) +	// Optimization in the always_noconv() case, to be generalized in the +	// future: when __n is sufficiently large we write directly instead of +	// using the buffer. +	streamsize __ret = 0; +	const bool __testout = _M_mode & ios_base::out; +	if (__check_facet(_M_codecvt).always_noconv() +		&& __testout && !_M_reading)  	{ -		close(); +		// Measurement would reveal the best choice. +		const streamsize __chunk = 1ul << 10; +		streamsize __bufavail = this->epptr() - this->pptr(); + +		// Don't mistake 'uncommitted' mode buffered with unbuffered. +		if (!_M_writing && _M_buf_size > 1) +			__bufavail = _M_buf_size - 1; + +		const streamsize __limit = std::min(__chunk, __bufavail); +		if (__n >= __limit) +		{ +			const streamsize __buffill = this->pptr() - this->pbase(); +			const char* __buf = reinterpret_cast<const char*>(this->pbase()); +			//__ret = _M_file.xsputn_2(__buf, __buffill, +			//			reinterpret_cast<const char*>(__s), __n); +			if (__buffill) +			{ +				__ret = fwrite(__buf, 1, __buffill, _M_file.file()); +			} +			if (__ret == __buffill) +			{ +				__ret += fwrite(reinterpret_cast<const char*>(__s), 1, +								__n, _M_file.file()); +			} +			if (__ret == __buffill + __n) +			{ +				_M_set_buffer(0); +				_M_writing = true; +			} +			if (__ret > __buffill) +				__ret -= __buffill; +			else +				__ret = 0; +		} +		else +			__ret = __streambuf_type::xsputn(__s, __n);  	} -	delete _Filebuffer; +	else +		__ret = __streambuf_type::xsputn(__s, __n); +    return __ret;  } -llifstream::llifstream(const std::string& _Filename, -	ios_base::openmode _Mode, -	int _Prot) -	: std::basic_istream< char , std::char_traits< char > >(NULL,true),_Filebuffer(NULL),_ShouldClose(false) +int llstdio_filebuf::sync() +{ +	return (_M_file.sync() == 0 ? 0 : -1); +} -{	// construct with named file and specified mode -	open(_Filename, _Mode | ios_base::in, _Prot);	/* Flawfinder: ignore */ +/************** input file stream ********************************/ + + +llifstream::llifstream() : _M_filebuf(), +#if LL_WINDOWS +	std::istream(&_M_filebuf) {} +#else +	std::istream() +{ +	this->init(&_M_filebuf); +} +#endif + +// explicit +llifstream::llifstream(const std::string& _Filename,  +		ios_base::openmode _Mode) : _M_filebuf(), +#if LL_WINDOWS +	std::istream(&_M_filebuf) +{ +	if (_M_filebuf.open(_Filename.c_str(), _Mode | ios_base::in) == 0) +	{ +		_Myios::setstate(ios_base::failbit); +	} +} +#else +	std::istream() +{ +	this->init(&_M_filebuf); +	this->open(_Filename.c_str(), _Mode | ios_base::in);  } +#endif +// explicit +llifstream::llifstream(const char* _Filename,  +		ios_base::openmode _Mode) : _M_filebuf(), +#if LL_WINDOWS +	std::istream(&_M_filebuf) +{ +	if (_M_filebuf.open(_Filename, _Mode | ios_base::in) == 0) +	{ +		_Myios::setstate(ios_base::failbit); +	} +} +#else +	std::istream() +{ +	this->init(&_M_filebuf); +	this->open(_Filename, _Mode | ios_base::in); +} +#endif -/************** output file stream ********************************/ -bool llofstream::is_open() const +// explicit +llifstream::llifstream(_Filet *_File, +		ios_base::openmode _Mode, size_t _Size) : +	_M_filebuf(_File, _Mode, _Size), +#if LL_WINDOWS +	std::istream(&_M_filebuf) {} +#else +	std::istream() +{ +	this->init(&_M_filebuf); +} +#endif + +#if LL_WINDOWS +// explicit +llifstream::llifstream(int __fd, +		ios_base::openmode _Mode, size_t _Size) : +	_M_filebuf(__fd, _Mode, _Size), +	std::istream() +{ +	this->init(&_M_filebuf); +} +#endif + +bool llifstream::is_open() const  {	// test if C stream has been opened -	if(_Filebuffer) -		return (_Filebuffer->is_open()); -	return false; +	return _M_filebuf.is_open();  } -void llofstream::open(const std::string& _Filename,	/* Flawfinder: ignore */ -	ios_base::openmode _Mode, -	int _Prot) +void llifstream::open(const char* _Filename, ios_base::openmode _Mode)  {	// open a C stream with specified mode - -	LLFILE* filep = LLFile::_Fiopen(_Filename,_Mode | ios_base::out, _Prot); -	if(filep == NULL) +	if (_M_filebuf.open(_Filename, _Mode | ios_base::in) == 0) +#if LL_WINDOWS  	{ -		_Myios::setstate(ios_base::failbit);	/*Flawfinder: ignore*/ -		return; +		_Myios::setstate(ios_base::failbit);  	} -	llassert(_Filebuffer==NULL); -	_Filebuffer = new _Myfb(filep); -	_ShouldClose = true; -	_Myios::init(_Filebuffer); +	else +	{ +		_Myios::clear(); +	} +#else +	{ +		this->setstate(ios_base::failbit); +	} +	else +	{ +		this->clear(); +	} +#endif  } -void llofstream::close() +void llifstream::close()  {	// close the C stream -	if(is_open()) +	if (_M_filebuf.close() == 0)  	{ -		if (_Filebuffer->close() == 0) -		{ -			_Myios::setstate(ios_base::failbit);	/*Flawfinder: ignore*/ -		} -		delete _Filebuffer; -		_Filebuffer = NULL; -		_ShouldClose = false; +#if LL_WINDOWS +		_Myios::setstate(ios_base::failbit); +#else +		this->setstate(ios_base::failbit); +#endif  	}  } + +/************** output file stream ********************************/ + + +llofstream::llofstream() : _M_filebuf(), +#if LL_WINDOWS +	std::ostream(&_M_filebuf) {} +#else +	std::ostream() +{ +	this->init(&_M_filebuf); +} +#endif + +// explicit  llofstream::llofstream(const std::string& _Filename, -	std::ios_base::openmode _Mode, -	int _Prot) -		: std::basic_ostream<char,std::char_traits < char > >(NULL,true),_Filebuffer(NULL),_ShouldClose(false) -{	// construct with named file and specified mode -	open(_Filename, _Mode , _Prot);	/* Flawfinder: ignore */ +		ios_base::openmode _Mode) : _M_filebuf(), +#if LL_WINDOWS +	std::ostream(&_M_filebuf) +{ +	if (_M_filebuf.open(_Filename.c_str(), _Mode | ios_base::out) == 0) +	{ +		_Myios::setstate(ios_base::failbit); +	} +} +#else +	std::ostream() +{ +	this->init(&_M_filebuf); +	this->open(_Filename.c_str(), _Mode | ios_base::out); +} +#endif + +// explicit +llofstream::llofstream(const char* _Filename, +		ios_base::openmode _Mode) : _M_filebuf(), +#if LL_WINDOWS +	std::ostream(&_M_filebuf) +{ +	if (_M_filebuf.open(_Filename, _Mode | ios_base::out) == 0) +	{ +		_Myios::setstate(ios_base::failbit); +	} +} +#else +	std::ostream() +{ +	this->init(&_M_filebuf); +	this->open(_Filename, _Mode | ios_base::out); +} +#endif + +// explicit +llofstream::llofstream(_Filet *_File, +			ios_base::openmode _Mode, size_t _Size) : +	_M_filebuf(_File, _Mode, _Size), +#if LL_WINDOWS +	std::ostream(&_M_filebuf) {} +#else +	std::ostream() +{ +	this->init(&_M_filebuf);  } +#endif -llofstream::~llofstream() +#if LL_WINDOWS +// explicit +llofstream::llofstream(int __fd, +			ios_base::openmode _Mode, size_t _Size) : +	_M_filebuf(__fd, _Mode, _Size), +	std::ostream()  { -	// destroy the object -	if (_ShouldClose) +	this->init(&_M_filebuf); +} +#endif + +bool llofstream::is_open() const +{	// test if C stream has been opened +	return _M_filebuf.is_open(); +} + +void llofstream::open(const char* _Filename, ios_base::openmode _Mode) +{	// open a C stream with specified mode +	if (_M_filebuf.open(_Filename, _Mode | ios_base::out) == 0) +#if LL_WINDOWS +	{ +		_Myios::setstate(ios_base::failbit); +	} +	else  	{ -		close(); +		_Myios::clear();  	} -	delete _Filebuffer; +#else +	{ +		this->setstate(ios_base::failbit); +	} +	else +	{ +		this->clear(); +	} +#endif  } -#endif // #if USE_LLFILESTREAMS +void llofstream::close() +{	// close the C stream +	if (_M_filebuf.close() == 0) +	{ +#if LL_WINDOWS +		_Myios::setstate(ios_base::failbit); +#else +		this->setstate(ios_base::failbit); +#endif +	} +}  /************** helper functions ********************************/ diff --git a/indra/llcommon/llfile.h b/indra/llcommon/llfile.h index dd7d36513a..7049ab1396 100644 --- a/indra/llcommon/llfile.h +++ b/indra/llcommon/llfile.h @@ -35,16 +35,10 @@   * Attempts to mostly mirror the POSIX style IO functions.   */ -typedef FILE	LLFILE; +typedef FILE LLFILE;  #include <fstream> - -#ifdef LL_WINDOWS -#define	USE_LLFILESTREAMS	1 -#else -#define	USE_LLFILESTREAMS	0 -#endif - +#include <bits/postypes.h>  #include <sys/stat.h>  #if LL_WINDOWS @@ -52,6 +46,7 @@ typedef FILE	LLFILE;  typedef struct _stat	llstat;  #else  typedef struct stat		llstat; +#include <ext/stdio_filebuf.h>  #endif  #ifndef S_ISREG @@ -83,142 +78,342 @@ public:  	static	int		stat(const std::string&	filename,llstat*	file_status);  	static	bool	isdir(const std::string&	filename);  	static	bool	isfile(const std::string&	filename); -	static	LLFILE *	_Fiopen(const std::string& filename, std::ios::openmode mode,int);	// protection currently unused +	static	LLFILE *	_Fiopen(const std::string& filename,  +			std::ios::openmode mode);  	static  const char * tmpdir();  }; +/** + *  @brief Provides a layer of compatibility for C/POSIX. + * + *  This is taken from both the GNU __gnu_cxx::stdio_filebuf extension and  + *  VC's basic_filebuf implementation. + *  This file buffer provides extensions for working with standard C FILE*'s  + *  and POSIX file descriptors for platforms that support this. +*/ +namespace +{ +#if LL_WINDOWS +typedef std::filebuf						_Myfb; +#else +typedef  __gnu_cxx::stdio_filebuf< char >	_Myfb; +typedef std::__c_file						_Filet; +#endif /* LL_WINDOWS */ +} -#if USE_LLFILESTREAMS - -class LL_COMMON_API llifstream	:	public	std::basic_istream < char , std::char_traits < char > > +class LL_COMMON_API llstdio_filebuf : public _Myfb  { -	// input stream associated with a C stream  public: -	typedef std::basic_ifstream<char,std::char_traits < char > > _Myt; -	typedef std::basic_filebuf<char,std::char_traits< char > > _Myfb; -	typedef std::basic_ios<char,std::char_traits< char > > _Myios; - -	llifstream() -		: std::basic_istream<char,std::char_traits< char > >(NULL,true),_Filebuffer(NULL),_ShouldClose(false) -	{	// construct unopened -	} +	/** +	 * deferred initialization / destruction +	*/ +	llstdio_filebuf() : _Myfb() {} +	virtual ~llstdio_filebuf() {}  + +	/** +	 *  @param  f  An open @c FILE*. +	 *  @param  mode  Same meaning as in a standard filebuf. +	 *  @param  size  Optimal or preferred size of internal buffer, in chars. +	 *                Defaults to system's @c BUFSIZ. +	 * +	 *  This constructor associates a file stream buffer with an open +	 *  C @c FILE*.  The @c FILE* will not be automatically closed when the +	 *  stdio_filebuf is closed/destroyed. +	*/ +	llstdio_filebuf(_Filet* __f, std::ios_base::openmode __mode, +		    //size_t __size = static_cast<size_t>(BUFSIZ)) : +		    size_t __size = static_cast<size_t>(1)) : +#if LL_WINDOWS +		_Myfb(__f) {} +#else +		_Myfb(__f, __mode, __size) {} +#endif -	explicit llifstream(const std::string& _Filename, -		ios_base::openmode _Mode = ios_base::in, -		int _Prot = (int)ios_base::_Openprot); - -	explicit llifstream(_Filet *_File) -		: std::basic_istream<char,std::char_traits< char > >(NULL,true), -			_Filebuffer(new _Myfb(_File)), -			_ShouldClose(false) -	{	// construct with specified C stream -	} -	virtual ~llifstream(); - -	_Myfb *rdbuf() const -	{	// return pointer to file buffer -		return _Filebuffer; -	} -	bool is_open() const; -	void open(const std::string& _Filename,	/* Flawfinder: ignore */ -		ios_base::openmode _Mode = ios_base::in, -		int _Prot = (int)ios_base::_Openprot);	 -	void close(); +	/** +	 *  @brief  Opens an external file. +	 *  @param  s  The name of the file. +	 *  @param  mode  The open mode flags. +	 *  @return  @c this on success, NULL on failure +	 * +	 *  If a file is already open, this function immediately fails. +	 *  Otherwise it tries to open the file named @a s using the flags +	 *  given in @a mode. +	*/ +	//llstdio_filebuf* open(const char *_Filename, +	//		std::ios_base::openmode _Mode); + +	/** +	 *  @param  fd  An open file descriptor. +	 *  @param  mode  Same meaning as in a standard filebuf. +	 *  @param  size  Optimal or preferred size of internal buffer, in chars. +	 * +	 *  This constructor associates a file stream buffer with an open +	 *  POSIX file descriptor. The file descriptor will be automatically +	 *  closed when the stdio_filebuf is closed/destroyed. +	*/ +#if !LL_WINDOWS +	llstdio_filebuf(int __fd, std::ios_base::openmode __mode, +		//size_t __size = static_cast<size_t>(BUFSIZ)) : +		size_t __size = static_cast<size_t>(1)) : +		_Myfb(__fd, __mode, __size) {} +#endif -private: -	_Myfb* _Filebuffer;	// the file buffer -	bool _ShouldClose; +// *TODO: Seek the underlying c stream for better cross-platform compatibility? +#if !LL_WINDOWS +protected: +	/** underflow() and uflow() functions are called to get the next +	 *  character from the real input source when the buffer is empty. +	 *  Buffered input uses underflow() +	*/ +	/*virtual*/ int_type underflow(); + +	/*  Convert internal byte sequence to external, char-based +	 * sequence via codecvt. +	*/ +	bool _convert_to_external(char_type*, std::streamsize); + +	/** The overflow() function is called to transfer characters to the +	 *  real output destination when the buffer is full. A call to +	 *  overflow(c) outputs the contents of the buffer plus the +	 *  character c. +	 *  Consume some sequence of the characters in the pending sequence. +	*/ +	/*virtual*/ int_type overflow(int_type __c = traits_type::eof()); + +	/** sync() flushes the underlying @c FILE* stream. +	*/ +	/*virtual*/ int sync(); + +	std::streamsize xsgetn(char_type*, std::streamsize); +	std::streamsize xsputn(char_type*, std::streamsize); +#endif  }; -class LL_COMMON_API llofstream	:	public	std::basic_ostream< char , std::char_traits < char > > +/** + *  @brief  Controlling input for files. + * + *  This class supports reading from named files, using the inherited + *  functions from std::basic_istream.  To control the associated + *  sequence, an instance of std::basic_filebuf (or a platform-specific derivative) + *  which allows construction using a pre-exisintg file stream buffer.  + *  We refer to this std::basic_filebuf (or derivative) as @c sb. +*/ +class LL_COMMON_API llifstream	:	public	std::istream  { +	// input stream associated with a C stream  public: -	typedef std::basic_ostream< char , std::char_traits < char > > _Myt; -	typedef std::basic_filebuf< char , std::char_traits < char > > _Myfb; -	typedef std::basic_ios<char,std::char_traits < char > > _Myios; - -	llofstream() -		: std::basic_ostream<char,std::char_traits < char > >(NULL,true),_Filebuffer(NULL),_ShouldClose(false) -	{	// construct unopened -	} - -	explicit llofstream(const std::string& _Filename, -		std::ios_base::openmode _Mode = ios_base::out, -		int _Prot = (int)std::ios_base::_Openprot); -	 - -	explicit llofstream(_Filet *_File) -		: std::basic_ostream<char,std::char_traits < char > >(NULL,true), -			_Filebuffer(new _Myfb(_File)),//_File) -			_ShouldClose(false) -	{	// construct with specified C stream -	} - -	virtual ~llofstream(); - -	_Myfb *rdbuf() const -	{	// return pointer to file buffer -		return _Filebuffer; -	} +	// Constructors: +	/** +	 *  @brief  Default constructor. +	 * +	 *  Initializes @c sb using its default constructor, and passes +	 *  @c &sb to the base class initializer.  Does not open any files +	 *  (you haven't given it a filename to open). +	*/ +	llifstream(); + +	/** +	 *  @brief  Create an input file stream. +	 *  @param  Filename  String specifying the filename. +	 *  @param  Mode  Open file in specified mode (see std::ios_base). +	 * +     *  @c ios_base::in is automatically included in @a mode. +	*/ +	explicit llifstream(const std::string& _Filename, +			ios_base::openmode _Mode = ios_base::in); +	explicit llifstream(const char* _Filename, +			ios_base::openmode _Mode = ios_base::in); + +	/** +	 *  @brief  Create a stream using an open c file stream. +	 *  @param  File  An open @c FILE*. +        @param  Mode  Same meaning as in a standard filebuf. +        @param  Size  Optimal or preferred size of internal buffer, in chars. +                      Defaults to system's @c BUFSIZ. +	*/ +	explicit llifstream(_Filet *_File, +			ios_base::openmode _Mode = ios_base::in, +			//size_t _Size = static_cast<size_t>(BUFSIZ)); +			size_t _Size = static_cast<size_t>(1)); + +	/** +	 *  @brief  Create a stream using an open file descriptor. +	 *  @param  fd    An open file descriptor. +        @param  Mode  Same meaning as in a standard filebuf. +        @param  Size  Optimal or preferred size of internal buffer, in chars. +                      Defaults to system's @c BUFSIZ. +	*/ +#if !LL_WINDOWS +	explicit llifstream(int __fd, +			ios_base::openmode _Mode = ios_base::in, +			//size_t _Size = static_cast<size_t>(BUFSIZ)); +			size_t _Size = static_cast<size_t>(1)); +#endif +	/** +	 *  @brief  The destructor does nothing. +	 * +	 *  The file is closed by the filebuf object, not the formatting +	 *  stream. +	*/ +	virtual ~llifstream() {} + +	// Members: +	/** +	 *  @brief  Accessing the underlying buffer. +	 *  @return  The current basic_filebuf buffer. +	 * +	 *  This hides both signatures of std::basic_ios::rdbuf(). +	*/ +	llstdio_filebuf* rdbuf() const +	{ return const_cast<llstdio_filebuf*>(&_M_filebuf); } + +	/** +	 *  @brief  Wrapper to test for an open file. +	 *  @return  @c rdbuf()->is_open() +	*/  	bool is_open() const; -	void open(const std::string& _Filename,ios_base::openmode _Mode = ios_base::out,int _Prot = (int)ios_base::_Openprot);	/* Flawfinder: ignore */ - +	/** +	 *  @brief  Opens an external file. +	 *  @param  Filename  The name of the file. +	 *  @param  Node  The open mode flags. +	 * +	 *  Calls @c llstdio_filebuf::open(s,mode|in).  If that function +	 *  fails, @c failbit is set in the stream's error state. +	*/ +	void open(const std::string& _Filename, +			ios_base::openmode _Mode = ios_base::in) +	{ open(_Filename.c_str(), _Mode); } +	void open(const char* _Filename, +			ios_base::openmode _Mode = ios_base::in); + +	/** +	 *  @brief  Close the file. +	 * +	 *  Calls @c llstdio_filebuf::close().  If that function +	 *  fails, @c failbit is set in the stream's error state. +	*/  	void close();  private: -	_Myfb *_Filebuffer;	// the file buffer -	bool _ShouldClose; -}; - - - -#else -//Use standard file streams on non windows platforms -//#define	llifstream	std::ifstream -//#define	llofstream	std::ofstream - -class LL_COMMON_API llifstream	:	public	std::ifstream -{ -public: -	llifstream() : std::ifstream() -	{ -	} - -	explicit llifstream(const std::string& _Filename, std::_Ios_Openmode _Mode = in) -		: std::ifstream(_Filename.c_str(), _Mode) -	{ -	} -	void open(const std::string& _Filename, std::_Ios_Openmode _Mode = in)	/* Flawfinder: ignore */ -	{ -		std::ifstream::open(_Filename.c_str(), _Mode); -	} +	llstdio_filebuf _M_filebuf;  }; -class LL_COMMON_API llofstream	:	public	std::ofstream +/** + *  @brief  Controlling output for files. + * + *  This class supports writing to named files, using the inherited + *  functions from std::basic_ostream.  To control the associated + *  sequence, an instance of std::basic_filebuf (or a platform-specific derivative) + *  which allows construction using a pre-exisintg file stream buffer.  + *  We refer to this std::basic_filebuf (or derivative) as @c sb. +*/ +class LL_COMMON_API llofstream	:	public	std::ostream  {  public: -	llofstream() : std::ofstream() -	{ -	} +	// Constructors: +	/** +	 *  @brief  Default constructor. +	 * +	 *  Initializes @c sb using its default constructor, and passes +	 *  @c &sb to the base class initializer.  Does not open any files +	 *  (you haven't given it a filename to open). +	*/ +	llofstream(); + +	/** +	 *  @brief  Create an output file stream. +	 *  @param  Filename  String specifying the filename. +	 *  @param  Mode  Open file in specified mode (see std::ios_base). +	 * +	 *  @c ios_base::out|ios_base::trunc is automatically included in +	 *  @a mode. +	*/ +	explicit llofstream(const std::string& _Filename, +			ios_base::openmode _Mode = ios_base::out|ios_base::trunc); +	explicit llofstream(const char* _Filename, +			ios_base::openmode _Mode = ios_base::out|ios_base::trunc); + +	/** +	 *  @brief  Create a stream using an open c file stream. +	 *  @param  File  An open @c FILE*. +        @param  Mode  Same meaning as in a standard filebuf. +        @param  Size  Optimal or preferred size of internal buffer, in chars. +                      Defaults to system's @c BUFSIZ. +	*/ +	explicit llofstream(_Filet *_File, +			ios_base::openmode _Mode = ios_base::out, +			//size_t _Size = static_cast<size_t>(BUFSIZ)); +			size_t _Size = static_cast<size_t>(1)); + +	/** +	 *  @brief  Create a stream using an open file descriptor. +	 *  @param  fd    An open file descriptor. +        @param  Mode  Same meaning as in a standard filebuf. +        @param  Size  Optimal or preferred size of internal buffer, in chars. +                      Defaults to system's @c BUFSIZ. +	*/ +#if !LL_WINDOWS +	explicit llofstream(int __fd, +			ios_base::openmode _Mode = ios_base::out, +			//size_t _Size = static_cast<size_t>(BUFSIZ)); +			size_t _Size = static_cast<size_t>(1)); +#endif -	explicit llofstream(const std::string& _Filename, std::_Ios_Openmode _Mode = out) -		: std::ofstream(_Filename.c_str(), _Mode) -	{ -	} +	/** +	 *  @brief  The destructor does nothing. +	 * +	 *  The file is closed by the filebuf object, not the formatting +	 *  stream. +	*/ +	virtual ~llofstream() {} + +	// Members: +	/** +	 *  @brief  Accessing the underlying buffer. +	 *  @return  The current basic_filebuf buffer. +	 * +	 *  This hides both signatures of std::basic_ios::rdbuf(). +	*/ +	llstdio_filebuf* rdbuf() const +	{ return const_cast<llstdio_filebuf*>(&_M_filebuf); } + +	/** +	 *  @brief  Wrapper to test for an open file. +	 *  @return  @c rdbuf()->is_open() +	*/ +	bool is_open() const; -	void open(const std::string& _Filename, std::_Ios_Openmode _Mode = out)	/* Flawfinder: ignore */ -	{ -		std::ofstream::open(_Filename.c_str(), _Mode); -	} +	/** +	 *  @brief  Opens an external file. +	 *  @param  Filename  The name of the file. +	 *  @param  Node  The open mode flags. +	 * +	 *  Calls @c llstdio_filebuf::open(s,mode|out).  If that function +	 *  fails, @c failbit is set in the stream's error state. +	*/ +	void open(const std::string& _Filename, +			ios_base::openmode _Mode = ios_base::out|ios_base::trunc) +	{ open(_Filename.c_str(), _Mode); } +	void open(const char* _Filename, +			ios_base::openmode _Mode = ios_base::out|ios_base::trunc); + +	/** +	 *  @brief  Close the file. +	 * +	 *  Calls @c llstdio_filebuf::close().  If that function +	 *  fails, @c failbit is set in the stream's error state. +	*/ +	void close(); +private: +	llstdio_filebuf _M_filebuf;  }; -#endif  /**   * @breif filesize helpers. diff --git a/indra/llinventory/llinventory.cpp b/indra/llinventory/llinventory.cpp index fbf23bc3f0..2dbc331036 100644 --- a/indra/llinventory/llinventory.cpp +++ b/indra/llinventory/llinventory.cpp @@ -824,7 +824,7 @@ BOOL LLInventoryItem::importLegacyStream(std::istream& input_stream)  		}  		else if(0 == strcmp("permissions", keyword))  		{ -			success = mPermissions.importLegacyStream(input_stream); +			success = mPermissions.importStream(input_stream);  		}  		else if(0 == strcmp("sale_info", keyword))  		{ @@ -834,7 +834,7 @@ BOOL LLInventoryItem::importLegacyStream(std::istream& input_stream)  			// should pick up the vast majority of the tasks.  			BOOL has_perm_mask = FALSE;  			U32 perm_mask = 0; -			success = mSaleInfo.importLegacyStream(input_stream, has_perm_mask, perm_mask); +			success = mSaleInfo.importStream(input_stream, has_perm_mask, perm_mask);  			if(has_perm_mask)  			{  				if(perm_mask == PERM_NONE) @@ -950,7 +950,7 @@ BOOL LLInventoryItem::exportLegacyStream(std::ostream& output_stream, BOOL inclu  	output_stream << "\t\titem_id\t" << uuid_str << "\n";  	mParentUUID.toString(uuid_str);  	output_stream << "\t\tparent_id\t" << uuid_str << "\n"; -	mPermissions.exportLegacyStream(output_stream); +	mPermissions.exportStream(output_stream);  	// Check for permissions to see the asset id, and if so write it  	// out as an asset id. Otherwise, apply our cheesy encryption. @@ -984,7 +984,7 @@ BOOL LLInventoryItem::exportLegacyStream(std::ostream& output_stream, BOOL inclu  	std::string buffer;  	buffer = llformat( "\t\tflags\t%08x\n", mFlags);  	output_stream << buffer; -	mSaleInfo.exportLegacyStream(output_stream); +	mSaleInfo.exportStream(output_stream);  	output_stream << "\t\tname\t" << mName.c_str() << "|\n";  	output_stream << "\t\tdesc\t" << mDescription.c_str() << "|\n";  	output_stream << "\t\tcreation_date\t" << mCreationDate << "\n"; diff --git a/indra/llinventory/llpermissions.cpp b/indra/llinventory/llpermissions.cpp index 7e013de11a..34354e3e8c 100644 --- a/indra/llinventory/llpermissions.cpp +++ b/indra/llinventory/llpermissions.cpp @@ -572,143 +572,17 @@ void LLPermissions::unpackMessage(LLMessageSystem* msg, const char* block, S32 b  BOOL LLPermissions::importFile(LLFILE* fp)  { -	init(LLUUID::null, LLUUID::null, LLUUID::null, LLUUID::null); -	const S32 BUFSIZE = 16384; - -	// *NOTE: Changing the buffer size will require changing the scanf -	// calls below. -	char buffer[BUFSIZE];	/* Flawfinder: ignore */ -	char keyword[256];	/* Flawfinder: ignore */ -	char valuestr[256];	/* Flawfinder: ignore */ -	char uuid_str[256];	/* Flawfinder: ignore */ -	U32 mask; - -	keyword[0]  = '\0'; -	valuestr[0] = '\0'; - -	while (!feof(fp)) -	{ -		if (fgets(buffer, BUFSIZE, fp) == NULL) -		{ -			buffer[0] = '\0'; -		} -		 -		sscanf( /* Flawfinder: ignore */ -			buffer, -			" %255s %255s", -			keyword, valuestr); -		if (!strcmp("{", keyword)) -		{ -			continue; -		} -		if (!strcmp("}",keyword)) -		{ -			break; -		} -		else if (!strcmp("creator_mask", keyword)) -		{ -			// legacy support for "creator" masks -			sscanf(valuestr, "%x", &mask); -			mMaskBase = mask; -			fixFairUse(); -		} -		else if (!strcmp("base_mask", keyword)) -		{ -			sscanf(valuestr, "%x", &mask); -			mMaskBase = mask; -			//fixFairUse(); -		} -		else if (!strcmp("owner_mask", keyword)) -		{ -			sscanf(valuestr, "%x", &mask); -			mMaskOwner = mask; -		} -		else if (!strcmp("group_mask", keyword)) -		{ -			sscanf(valuestr, "%x", &mask); -			mMaskGroup = mask; -		} -		else if (!strcmp("everyone_mask", keyword)) -		{ -			sscanf(valuestr, "%x", &mask); -			mMaskEveryone = mask; -		} -		else if (!strcmp("next_owner_mask", keyword)) -		{ -			sscanf(valuestr, "%x", &mask); -			mMaskNextOwner = mask; -		} -		else if (!strcmp("creator_id", keyword)) -		{ -			sscanf(valuestr, "%255s", uuid_str); /* Flawfinder: ignore */ -			mCreator.set(uuid_str); -		} -		else if (!strcmp("owner_id", keyword)) -		{ -			sscanf(valuestr, "%255s", uuid_str); /* Flawfinder: ignore */ -			mOwner.set(uuid_str); -		} -		else if (!strcmp("last_owner_id", keyword)) -		{ -			sscanf(valuestr, "%255s", uuid_str); /* Flawfinder: ignore */ -			mLastOwner.set(uuid_str); -		} -		else if (!strcmp("group_id", keyword)) -		{ -			sscanf(valuestr, "%255s", uuid_str); /* Flawfinder: ignore */ -			mGroup.set(uuid_str); -		} -		else if (!strcmp("group_owned", keyword)) -		{ -			sscanf(valuestr, "%d", &mask); -			if(mask) mIsGroupOwned = true; -			else mIsGroupOwned = false; -		} -		else -		{ -			llinfos << "unknown keyword " << keyword << " in permissions import" << llendl; -		} -	} -	fix(); -	return TRUE; +	llifstream ifs(fp); +	return importStream(ifs);  } -  BOOL LLPermissions::exportFile(LLFILE* fp) const  { -	std::string uuid_str; - -	fprintf(fp, "\tpermissions 0\n"); -	fprintf(fp, "\t{\n"); - -	fprintf(fp, "\t\tbase_mask\t%08x\n",		mMaskBase); -	fprintf(fp, "\t\towner_mask\t%08x\n",		mMaskOwner); -	fprintf(fp, "\t\tgroup_mask\t%08x\n",		mMaskGroup); -	fprintf(fp, "\t\teveryone_mask\t%08x\n",	mMaskEveryone); -	fprintf(fp, "\t\tnext_owner_mask\t%08x\n",	mMaskNextOwner); - -	mCreator.toString(uuid_str); -	fprintf(fp, "\t\tcreator_id\t%s\n",			uuid_str.c_str()); - -	mOwner.toString(uuid_str); -	fprintf(fp, "\t\towner_id\t%s\n",			uuid_str.c_str()); - -	mLastOwner.toString(uuid_str); -	fprintf(fp, "\t\tlast_owner_id\t%s\n",		uuid_str.c_str()); - -	mGroup.toString(uuid_str); -	fprintf(fp, "\t\tgroup_id\t%s\n",			uuid_str.c_str()); - -	if(mIsGroupOwned) -	{ -		fprintf(fp, "\t\tgroup_owned\t1\n"); -	} -	fprintf(fp,"\t}\n"); -	return TRUE; +	llofstream ofs(fp); +	return exportStream(ofs);  } - -BOOL LLPermissions::importLegacyStream(std::istream& input_stream) +BOOL LLPermissions::importStream(std::istream& input_stream)  {  	init(LLUUID::null, LLUUID::null, LLUUID::null, LLUUID::null);  	const S32 BUFSIZE = 16384; @@ -727,6 +601,18 @@ BOOL LLPermissions::importLegacyStream(std::istream& input_stream)  	while (input_stream.good())  	{  		input_stream.getline(buffer, BUFSIZE); +		if (input_stream.eof()) +		{ +			llwarns << "Bad permissions: early end of input stream" +					<< llendl; +			return FALSE; +		} +		if (input_stream.fail()) +		{ +			llwarns << "Bad permissions: failed to read from input stream" +					<< llendl; +			return FALSE; +		}  		sscanf( /* Flawfinder: ignore */  			buffer,  			" %255s %255s", @@ -800,7 +686,8 @@ BOOL LLPermissions::importLegacyStream(std::istream& input_stream)  		}  		else  		{ -			llinfos << "unknown keyword " << keyword << " in permissions import" << llendl; +			llwarns << "unknown keyword " << keyword  +					<< " in permissions import" << llendl;  		}  	}  	fix(); @@ -808,36 +695,26 @@ BOOL LLPermissions::importLegacyStream(std::istream& input_stream)  } -BOOL LLPermissions::exportLegacyStream(std::ostream& output_stream) const +BOOL LLPermissions::exportStream(std::ostream& output_stream) const  { -	std::string uuid_str; - +	if (!output_stream.good()) return FALSE;  	output_stream <<  "\tpermissions 0\n";  	output_stream <<  "\t{\n"; -	std::string buffer; -	buffer = llformat( "\t\tbase_mask\t%08x\n",		mMaskBase); -	output_stream << buffer; -	buffer = llformat( "\t\towner_mask\t%08x\n",		mMaskOwner); -	output_stream << buffer; -	buffer = llformat( "\t\tgroup_mask\t%08x\n",		mMaskGroup); -	output_stream << buffer; -	buffer = llformat( "\t\teveryone_mask\t%08x\n",	mMaskEveryone); -	output_stream << buffer; -	buffer = llformat( "\t\tnext_owner_mask\t%08x\n",	mMaskNextOwner); -	output_stream << buffer; - -	mCreator.toString(uuid_str); -	output_stream <<  "\t\tcreator_id\t" << uuid_str << "\n"; - -	mOwner.toString(uuid_str); -	output_stream <<  "\t\towner_id\t" << uuid_str << "\n"; - -	mLastOwner.toString(uuid_str); -	output_stream <<  "\t\tlast_owner_id\t" << uuid_str << "\n"; - -	mGroup.toString(uuid_str); -	output_stream <<  "\t\tgroup_id\t" << uuid_str << "\n"; +	char prev_fill = output_stream.fill('0'); +	output_stream << std::hex; +	output_stream << "\t\tbase_mask\t" << std::setw(8) << mMaskBase << "\n"; +	output_stream << "\t\towner_mask\t" << std::setw(8) << mMaskOwner << "\n"; +	output_stream << "\t\tgroup_mask\t" << std::setw(8) << mMaskGroup << "\n"; +	output_stream << "\t\teveryone_mask\t" << std::setw(8) << mMaskEveryone << "\n"; +	output_stream << "\t\tnext_owner_mask\t" << std::setw(8) << mMaskNextOwner << "\n"; +	output_stream << std::dec; +	output_stream.fill(prev_fill); + +	output_stream <<  "\t\tcreator_id\t" << mCreator << "\n"; +	output_stream <<  "\t\towner_id\t" << mOwner << "\n"; +	output_stream <<  "\t\tlast_owner_id\t" << mLastOwner << "\n"; +	output_stream <<  "\t\tgroup_id\t" << mGroup << "\n";  	if(mIsGroupOwned)  	{ diff --git a/indra/llinventory/llpermissions.h b/indra/llinventory/llpermissions.h index 3ecc922370..7d3a68d353 100644 --- a/indra/llinventory/llpermissions.h +++ b/indra/llinventory/llpermissions.h @@ -316,8 +316,8 @@ public:  	BOOL	importFile(LLFILE* fp);  	BOOL	exportFile(LLFILE* fp) const; -	BOOL	importLegacyStream(std::istream& input_stream); -	BOOL	exportLegacyStream(std::ostream& output_stream) const; +	BOOL	importStream(std::istream& input_stream); +	BOOL	exportStream(std::ostream& output_stream) const;  	bool operator==(const LLPermissions &rhs) const;  	bool operator!=(const LLPermissions &rhs) const; diff --git a/indra/llinventory/llsaleinfo.cpp b/indra/llinventory/llsaleinfo.cpp index dd408a8efe..a829667933 100644 --- a/indra/llinventory/llsaleinfo.cpp +++ b/indra/llinventory/llsaleinfo.cpp @@ -81,15 +81,13 @@ U32 LLSaleInfo::getCRC32() const  BOOL LLSaleInfo::exportFile(LLFILE* fp) const  { -	fprintf(fp, "\tsale_info\t0\n\t{\n"); -	fprintf(fp, "\t\tsale_type\t%s\n", lookup(mSaleType)); -	fprintf(fp, "\t\tsale_price\t%d\n", mSalePrice); -	fprintf(fp,"\t}\n"); -	return TRUE; +	llofstream ofs(fp); +	return exportStream(ofs);  } -BOOL LLSaleInfo::exportLegacyStream(std::ostream& output_stream) const +BOOL LLSaleInfo::exportStream(std::ostream& output_stream) const  { +	if (!output_stream.good()) return FALSE;  	output_stream << "\tsale_info\t0\n\t{\n";  	output_stream << "\t\tsale_type\t" << lookup(mSaleType) << "\n";  	output_stream << "\t\tsale_price\t" << mSalePrice << "\n"; @@ -134,80 +132,39 @@ bool LLSaleInfo::fromLLSD(const LLSD& sd, BOOL& has_perm_mask, U32& perm_mask)  BOOL LLSaleInfo::importFile(LLFILE* fp, BOOL& has_perm_mask, U32& perm_mask)  { -	has_perm_mask = FALSE; - -	// *NOTE: Changing the buffer size will require changing the scanf -	// calls below. -	char buffer[MAX_STRING];	/* Flawfinder: ignore */ -	char keyword[MAX_STRING];	/* Flawfinder: ignore */ -	char valuestr[MAX_STRING];	/* Flawfinder: ignore */ -	BOOL success = TRUE; - -	keyword[0] = '\0'; -	valuestr[0] = '\0'; -	while(success && (!feof(fp))) -	{ -		if (fgets(buffer, MAX_STRING, fp) == NULL) -		{ -			buffer[0] = '\0'; -		} - -		sscanf(	/* Flawfinder: ignore */ -			buffer, -			" %254s %254s", -			keyword, valuestr); -		if(!keyword[0]) -		{ -			continue; -		} -		if(0 == strcmp("{",keyword)) -		{ -			continue; -		} -		if(0 == strcmp("}", keyword)) -		{ -			break; -		} -		else if(0 == strcmp("sale_type", keyword)) -		{ -			mSaleType = lookup(valuestr); -		} -		else if(0 == strcmp("sale_price", keyword)) -		{ -			sscanf(valuestr, "%d", &mSalePrice); -			mSalePrice = llclamp(mSalePrice, 0, S32_MAX); -		} -		else if (!strcmp("perm_mask", keyword)) -		{ -			//llinfos << "found deprecated keyword perm_mask" << llendl; -			has_perm_mask = TRUE; -			sscanf(valuestr, "%x", &perm_mask); -		} -		else -		{ -			llwarns << "unknown keyword '" << keyword -					<< "' in sale info import" << llendl; -		} -	} -	return success; +	llifstream ifs(fp); +	return importStream(ifs, has_perm_mask, perm_mask);  } -BOOL LLSaleInfo::importLegacyStream(std::istream& input_stream, BOOL& has_perm_mask, U32& perm_mask) +BOOL LLSaleInfo::importStream(std::istream& input_stream, BOOL& has_perm_mask, U32& perm_mask)  {  	has_perm_mask = FALSE; +	const S32 BUFSIZE = 16384; +  	// *NOTE: Changing the buffer size will require changing the scanf  	// calls below. -	char buffer[MAX_STRING];	/* Flawfinder: ignore */ -	char keyword[MAX_STRING];	/* Flawfinder: ignore */ -	char valuestr[MAX_STRING];	/* Flawfinder: ignore */ -	BOOL success = TRUE; +	char buffer[BUFSIZE];	/* Flawfinder: ignore */ +	char keyword[255];	/* Flawfinder: ignore */ +	char valuestr[255];	/* Flawfinder: ignore */  	keyword[0] = '\0';  	valuestr[0] = '\0'; -	while(success && input_stream.good()) +	while(input_stream.good())  	{  		input_stream.getline(buffer, MAX_STRING); +		if (input_stream.eof()) +		{ +			llwarns << "Bad sale info: early end of input stream" +					<< llendl; +			return FALSE; +		} +		if (input_stream.fail()) +		{ +			llwarns << "Bad sale info: failed to read from input stream" +					<< llendl; +			return FALSE; +		}  		sscanf(	/* Flawfinder: ignore */  			buffer,  			" %254s %254s", @@ -245,7 +202,7 @@ BOOL LLSaleInfo::importLegacyStream(std::istream& input_stream, BOOL& has_perm_m  					<< "' in sale info import" << llendl;  		}  	} -	return success; +	return TRUE;  }  void LLSaleInfo::setSalePrice(S32 price) diff --git a/indra/llinventory/llsaleinfo.h b/indra/llinventory/llsaleinfo.h index 4e98ccf6ff..f7f3f9269c 100644 --- a/indra/llinventory/llsaleinfo.h +++ b/indra/llinventory/llsaleinfo.h @@ -89,11 +89,11 @@ public:  	BOOL exportFile(LLFILE* fp) const;  	BOOL importFile(LLFILE* fp, BOOL& has_perm_mask, U32& perm_mask); -	BOOL exportLegacyStream(std::ostream& output_stream) const; +	BOOL exportStream(std::ostream& output_stream) const;  	LLSD asLLSD() const;  	operator LLSD() const { return asLLSD(); }  	bool fromLLSD(const LLSD& sd, BOOL& has_perm_mask, U32& perm_mask); -	BOOL importLegacyStream(std::istream& input_stream, BOOL& has_perm_mask, U32& perm_mask); +	BOOL importStream(std::istream& input_stream, BOOL& has_perm_mask, U32& perm_mask);  	LLSD packMessage() const;  	void unpackMessage(LLSD sales); diff --git a/indra/newview/llagent.h b/indra/newview/llagent.h index f784262e90..ae5efb2287 100644 --- a/indra/newview/llagent.h +++ b/indra/newview/llagent.h @@ -34,6 +34,7 @@  #include "llcharacter.h"  #include "llcoordframe.h"			// for mFrameAgent  #include "llavatarappearancedefines.h" +#include "llpermissionsflags.h"  #include <boost/function.hpp>  #include <boost/shared_ptr.hpp> diff --git a/indra/newview/lllocalbitmaps.h b/indra/newview/lllocalbitmaps.h index ca12fe2045..580b6dfa7e 100644 --- a/indra/newview/lllocalbitmaps.h +++ b/indra/newview/lllocalbitmaps.h @@ -28,9 +28,11 @@  #ifndef LL_LOCALBITMAPS_H  #define LL_LOCALBITMAPS_H +#include "llavatarappearancedefines.h"  #include "lleventtimer.h" +#include "llimage.h" +#include "llpointer.h"  #include "llwearabletype.h" -#include "llavatarappearancedefines.h"  class LLScrollListCtrl;  class LLViewerObject; diff --git a/indra/newview/lltoolmorph.cpp b/indra/newview/lltoolmorph.cpp index 0d5daf129f..148e5a015b 100644 --- a/indra/newview/lltoolmorph.cpp +++ b/indra/newview/lltoolmorph.cpp @@ -34,6 +34,7 @@  #include "llaudioengine.h"  #include "llviewercontrol.h"  #include "llfontgl.h" +#include "llwearable.h"  #include "sound_ids.h"  #include "v3math.h"  #include "v3color.h" diff --git a/indra/newview/llviewertexlayer.h b/indra/newview/llviewertexlayer.h index 95c339a5b0..9df9474eff 100644 --- a/indra/newview/llviewertexlayer.h +++ b/indra/newview/llviewertexlayer.h @@ -28,6 +28,7 @@  #define LL_VIEWER_TEXLAYER_H  #include "lldynamictexture.h" +#include "llextendedstatus.h"  #include "lltexlayer.h"  class LLVOAvatarSelf; diff --git a/indra/newview/llviewerwearable.cpp b/indra/newview/llviewerwearable.cpp index e9fa92e8be..162c20837a 100644 --- a/indra/newview/llviewerwearable.cpp +++ b/indra/newview/llviewerwearable.cpp @@ -90,13 +90,13 @@ LLViewerWearable::~LLViewerWearable()  }  // virtual -LLWearable::EImportResult LLViewerWearable::importFile( LLFILE* file, LLAvatarAppearance* avatarp ) +LLWearable::EImportResult LLViewerWearable::importStream( std::istream& input_stream, LLAvatarAppearance* avatarp )  {  	// suppress texlayerset updates while wearables are being imported. Layersets will be updated  	// when the wearables are "worn", not loaded. Note state will be restored when this object is destroyed.  	LLOverrideBakedTextureUpdate stop_bakes(false); -	LLWearable::EImportResult result = LLWearable::importFile(file, avatarp); +	LLWearable::EImportResult result = LLWearable::importStream(input_stream, avatarp);  	if (LLWearable::FAILURE == result) return result;  	if (LLWearable::BAD_HEADER == result)  	{ @@ -129,9 +129,6 @@ LLWearable::EImportResult LLViewerWearable::importFile( LLFILE* file, LLAvatarAp  		}  	} -	// copy all saved param values to working params -	revertValues(); -  	return result;  } @@ -296,8 +293,8 @@ void LLViewerWearable::setTexturesToDefaults()  } -//static -const LLUUID LLViewerWearable::getDefaultTextureImageID(ETextureIndex index) +// virtual +LLUUID LLViewerWearable::getDefaultTextureImageID(ETextureIndex index) const  {  	const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = LLAvatarAppearanceDictionary::getInstance()->getTexture(index);  	const std::string &default_image_name = texture_dict->mDefaultImageName; @@ -475,103 +472,9 @@ void LLViewerWearable::setItemID(const LLUUID& item_id)  	mItemID = item_id;  } - -LLLocalTextureObject* LLViewerWearable::getLocalTextureObject(S32 index) -{ -	te_map_t::iterator iter = mTEMap.find(index); -	if( iter != mTEMap.end() ) -	{ -		LLLocalTextureObject* lto = iter->second; -		return lto; -	} -	return NULL; -} - -const LLLocalTextureObject* LLViewerWearable::getLocalTextureObject(S32 index) const -{ -	te_map_t::const_iterator iter = mTEMap.find(index); -	if( iter != mTEMap.end() ) -	{ -		const LLLocalTextureObject* lto = iter->second; -		return lto; -	} -	return NULL; -} - -std::vector<LLLocalTextureObject*> LLViewerWearable::getLocalTextureListSeq() -{ -	std::vector<LLLocalTextureObject*> result; - -	for(te_map_t::const_iterator iter = mTEMap.begin(); -		iter != mTEMap.end(); iter++) -	{ -		LLLocalTextureObject* lto = iter->second; -		result.push_back(lto); -	} - -	return result; -} - -void LLViewerWearable::setLocalTextureObject(S32 index, LLLocalTextureObject <o) -{ -	if( mTEMap.find(index) != mTEMap.end() ) -	{ -		mTEMap.erase(index); -	} -	mTEMap[index] = new LLLocalTextureObject(lto); -} - -void LLViewerWearable::setVisualParams() -{ -	for (visual_param_index_map_t::const_iterator iter = mVisualParamIndexMap.begin(); iter != mVisualParamIndexMap.end(); iter++) -	{ -		S32 id = iter->first; -		LLVisualParam *wearable_param = iter->second; -		F32 value = wearable_param->getWeight(); -		gAgentAvatarp->setVisualParamWeight(id, value, FALSE); -	} -} -  void LLViewerWearable::revertValues()  { -	//update saved settings so wearable is no longer dirty -	// non-driver params first -	for (param_map_t::const_iterator iter = mSavedVisualParamMap.begin(); iter != mSavedVisualParamMap.end(); iter++) -	{ -		S32 id = iter->first; -		F32 value = iter->second; -		LLVisualParam *param = getVisualParam(id); -		if(param &&  !dynamic_cast<LLDriverParam*>(param) ) -		{ -			setVisualParamWeight(id, value, TRUE); -		} -	} - -	//then driver params -	for (param_map_t::const_iterator iter = mSavedVisualParamMap.begin(); iter != mSavedVisualParamMap.end(); iter++) -	{ -		S32 id = iter->first; -		F32 value = iter->second; -		LLVisualParam *param = getVisualParam(id); -		if(param &&  dynamic_cast<LLDriverParam*>(param) ) -		{ -			setVisualParamWeight(id, value, TRUE); -		} -	} - -	// make sure that saved values are sane -	for (param_map_t::const_iterator iter = mSavedVisualParamMap.begin(); iter != mSavedVisualParamMap.end(); iter++) -	{ -		S32 id = iter->first; -		LLVisualParam *param = getVisualParam(id); -		if( param ) -		{ -			mSavedVisualParamMap[id] = param->getWeight(); -		} -	} - -	syncImages(mSavedTEMap, mTEMap); - +	LLWearable::revertValues();  	LLSidepanelAppearance *panel = dynamic_cast<LLSidepanelAppearance*>(LLFloaterSidePanelContainer::getPanel("appearance"));  	if( panel ) @@ -582,19 +485,7 @@ void LLViewerWearable::revertValues()  void LLViewerWearable::saveValues()  { -	//update saved settings so wearable is no longer dirty -	mSavedVisualParamMap.clear(); -	for (visual_param_index_map_t::const_iterator iter = mVisualParamIndexMap.begin(); iter != mVisualParamIndexMap.end(); ++iter) -	{ -		S32 id = iter->first; -		LLVisualParam *wearable_param = iter->second; -		F32 value = wearable_param->getWeight(); -		mSavedVisualParamMap[id] = value; -	} - -	// Deep copy of mTEMap (copies only those tes that are current, filling in defaults where needed) -	syncImages(mTEMap, mSavedTEMap); - +	LLWearable::saveValues();  	LLSidepanelAppearance *panel = dynamic_cast<LLSidepanelAppearance*>(LLFloaterSidePanelContainer::getPanel("appearance"));  	if( panel ) @@ -603,69 +494,6 @@ void LLViewerWearable::saveValues()  	}  } -void LLViewerWearable::syncImages(te_map_t &src, te_map_t &dst) -{ -	// Deep copy of src (copies only those tes that are current, filling in defaults where needed) -	for( S32 te = 0; te < TEX_NUM_INDICES; te++ ) -	{ -		if (LLAvatarAppearanceDictionary::getTEWearableType((ETextureIndex) te) == mType) -		{ -			te_map_t::const_iterator iter = src.find(te); -			LLUUID image_id; -			LLViewerFetchedTexture *image = NULL; -			LLLocalTextureObject *lto = NULL; -			if(iter != src.end()) -			{ -				// there's a Local Texture Object in the source image map. Use this to populate the values to store in the destination image map. -				lto = iter->second; -				image = dynamic_cast<LLViewerFetchedTexture*> (lto->getImage()); -				image_id = lto->getID(); -			} -			else -			{ -				// there is no Local Texture Object in the source image map. Get defaults values for populating the destination image map. -				image_id = getDefaultTextureImageID((ETextureIndex) te); -				image = LLViewerTextureManager::getFetchedTexture( image_id ); -			} - -			if( dst.find(te) != dst.end() ) -			{ -				// there's already an entry in the destination map for the texture. Just update its values. -				dst[te]->setImage(image); -				dst[te]->setID(image_id); -			} -			else -			{ -				// no entry found in the destination map, we need to create a new Local Texture Object -				dst[te] = new LLLocalTextureObject(image, image_id); -			} - -			if( lto ) -			{ -				// If we pulled values from a Local Texture Object in the source map, make sure the proper flags are set in the new (or updated) entry in the destination map. -				dst[te]->setBakedReady(lto->getBakedReady()); -				dst[te]->setDiscard(lto->getDiscard()); -			} -		} -	} -} - -void LLViewerWearable::destroyTextures() -{ -	for( te_map_t::iterator iter = mTEMap.begin(); iter != mTEMap.end(); ++iter ) -	{ -		LLLocalTextureObject *lto = iter->second; -		delete lto; -	} -	mTEMap.clear(); -	for( te_map_t::iterator iter = mSavedTEMap.begin(); iter != mSavedTEMap.end(); ++iter ) -	{ -		LLLocalTextureObject *lto = iter->second; -		delete lto; -	} -	mSavedTEMap.clear(); -} -  // virtual  void LLViewerWearable::setUpdated() const  {  diff --git a/indra/newview/llviewerwearable.h b/indra/newview/llviewerwearable.h index d8412b1c65..65566f23a5 100644 --- a/indra/newview/llviewerwearable.h +++ b/indra/newview/llviewerwearable.h @@ -64,12 +64,12 @@ public:  	void				removeFromAvatar( BOOL upload_bake )	{ LLViewerWearable::removeFromAvatar( mType, upload_bake ); }  	static void			removeFromAvatar( LLWearableType::EType type, BOOL upload_bake );  -	/*virtual*/ EImportResult	importFile(LLFILE* file, LLAvatarAppearance* avatarp); +	/*virtual*/ EImportResult	importStream( std::istream& input_stream, LLAvatarAppearance* avatarp );  	void				setParamsToDefaults();  	void				setTexturesToDefaults(); -	static const LLUUID			getDefaultTextureImageID(LLAvatarAppearanceDefines::ETextureIndex index); +	/*virtual*/ LLUUID	getDefaultTextureImageID(LLAvatarAppearanceDefines::ETextureIndex index) const;  	void				saveNewAsset() const; @@ -79,14 +79,8 @@ public:  	friend std::ostream& operator<<(std::ostream &s, const LLViewerWearable &w); -	/*virtual*/ LLLocalTextureObject* getLocalTextureObject(S32 index); -	const LLLocalTextureObject* getLocalTextureObject(S32 index) const; -	std::vector<LLLocalTextureObject*> getLocalTextureListSeq(); -	void				setLocalTextureObject(S32 index, LLLocalTextureObject <o); -	void				setVisualParams(); - -	void				revertValues(); -	void				saveValues(); +	/*virtual*/ void	revertValues(); +	/*virtual*/ void	saveValues();  	// Something happened that requires the wearable's label to be updated (e.g. worn/unworn).  	/*virtual*/void		setUpdated() const; @@ -99,8 +93,6 @@ public:  	/*virtual*/void		addToBakedTextureHash(LLMD5& hash) const;  protected: -	void				syncImages(te_map_t &src, te_map_t &dst); -	void				destroyTextures();	  	LLAssetID			mAssetID;  	LLTransactionID		mTransactionID; diff --git a/indra/newview/llwearablelist.cpp b/indra/newview/llwearablelist.cpp index 50beaaec3f..3dfacd70f3 100644 --- a/indra/newview/llwearablelist.cpp +++ b/indra/newview/llwearablelist.cpp @@ -112,15 +112,16 @@ void LLWearableList::processGetAssetReply( const char* filename, const LLAssetID  	else if (status >= 0)  	{  		// read the file -		LLFILE* fp = LLFile::fopen(std::string(filename), "rb");		/*Flawfinder: ignore*/ -		if( !fp ) +		llifstream ifs(filename, llifstream::binary); +		if( !ifs.is_open() )  		{  			LL_WARNS("Wearable") << "Bad Wearable Asset: unable to open file: '" << filename << "'" << LL_ENDL;  		}  		else  		{  			wearable = new LLViewerWearable(uuid); -			LLWearable::EImportResult result = wearable->importFile( fp, avatarp ); +			LLWearable::EImportResult result = wearable->importStream( +												ifs, avatarp );  			if (LLWearable::SUCCESS != result)  			{  				if (wearable->getType() == LLWearableType::WT_COUNT) @@ -131,7 +132,6 @@ void LLWearableList::processGetAssetReply( const char* filename, const LLAssetID  				wearable = NULL;  			} -			fclose( fp );  			if(filename)  			{  				LLFile::remove(std::string(filename)); diff --git a/indra/test/llpermissions_tut.cpp b/indra/test/llpermissions_tut.cpp index bf6766424c..dff8bca53f 100644 --- a/indra/test/llpermissions_tut.cpp +++ b/indra/test/llpermissions_tut.cpp @@ -407,7 +407,7 @@ namespace tut  		LLFILE* fp = LLFile::fopen("linden_file.dat","w+");  		if(!fp)  		{ -			llerrs << "file coudnt be opened\n" << llendl; +			llerrs << "file couldn't be opened\n" << llendl;  			return;  		}  		LLPermissions perm,perm1; @@ -425,15 +425,15 @@ namespace tut  		perm.initMasks(base, ownerp, everyone, groupp, next); -		perm.exportFile(fp); +		ensure("Permissions export failed", perm.exportFile(fp));  		fclose(fp);	  		fp = LLFile::fopen("linden_file.dat","r+");  		if(!fp)  		{ -			llerrs << "file coudnt be opened\n" << llendl; +			llerrs << "file couldn't be opened\n" << llendl;  			return;  		} -		perm1.importFile(fp); +		ensure("Permissions import failed", perm1.importFile(fp));  		fclose(fp);  		ensure_equals("exportFile()/importFile():failed to export and import the data ", perm1, perm);	  } @@ -457,11 +457,11 @@ namespace tut  		perm.initMasks(base, ownerp, everyone, groupp, next);  		std::ostringstream ostream; -		perm.exportLegacyStream(ostream); +		perm.exportStream(ostream);  		std::istringstream istream(ostream.str()); -		perm1.importLegacyStream(istream); +		perm1.importStream(istream); -		ensure_equals("exportLegacyStream()/importLegacyStream():failed to export and import the data ", perm1, perm); +		ensure_equals("exportStream()/importStream():failed to export and import the data ", perm1, perm);  	}  	template<> template<> diff --git a/indra/test/llsaleinfo_tut.cpp b/indra/test/llsaleinfo_tut.cpp index 09fca2abba..d546803947 100644 --- a/indra/test/llsaleinfo_tut.cpp +++ b/indra/test/llsaleinfo_tut.cpp @@ -146,16 +146,17 @@ namespace tut  		LLSaleInfo llsaleinfo(LLSaleInfo::FS_ORIGINAL, sale_price);  		std::ostringstream ostream; -		llsaleinfo.exportLegacyStream(ostream); +		llsaleinfo.exportStream(ostream);  		std::istringstream istream(ostream.str());  		LLSaleInfo llsaleinfo1;  		U32 perm_mask = 0;  		BOOL has_perm_mask = FALSE; -		llsaleinfo1.importLegacyStream(istream, has_perm_mask, perm_mask); +		llsaleinfo1.importStream(istream, has_perm_mask, perm_mask); -		ensure("importLegacyStream() fn failed ", llsaleinfo.getSalePrice() == llsaleinfo1.getSalePrice() && -										       llsaleinfo.getSaleType() == llsaleinfo1.getSaleType());		 +		ensure("importStream() fn failed ", +			llsaleinfo.getSalePrice() == llsaleinfo1.getSalePrice() && +			llsaleinfo.getSaleType() == llsaleinfo1.getSaleType());  	}  	template<> template<> | 
