summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--indra/llappearance/llavatarappearance.h1
-rw-r--r--indra/llappearance/llavatarappearancedefines.h3
-rw-r--r--indra/llappearance/lllocaltextureobject.h1
-rw-r--r--indra/llappearance/lltexlayer.h1
-rw-r--r--indra/llappearance/lltexturemanagerbridge.h1
-rwxr-xr-xindra/llappearance/llwearable.cpp443
-rw-r--r--indra/llappearance/llwearable.h23
-rw-r--r--indra/llappearance/llwearabledata.h1
-rw-r--r--indra/llcommon/lldictionary.h2
-rw-r--r--indra/llcommon/llfile.cpp705
-rw-r--r--indra/llcommon/llfile.h423
-rw-r--r--indra/llinventory/llinventory.cpp8
-rw-r--r--indra/llinventory/llpermissions.cpp193
-rw-r--r--indra/llinventory/llpermissions.h4
-rw-r--r--indra/llinventory/llsaleinfo.cpp95
-rw-r--r--indra/llinventory/llsaleinfo.h4
-rw-r--r--indra/newview/llagent.h1
-rw-r--r--indra/newview/lllocalbitmaps.h4
-rw-r--r--indra/newview/lltoolmorph.cpp1
-rw-r--r--indra/newview/llviewertexlayer.h1
-rw-r--r--indra/newview/llviewerwearable.cpp184
-rw-r--r--indra/newview/llviewerwearable.h16
-rw-r--r--indra/newview/llwearablelist.cpp8
-rw-r--r--indra/test/llpermissions_tut.cpp14
-rw-r--r--indra/test/llsaleinfo_tut.cpp9
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", &param_id, &param_weight );
- if( fields_read != 2 )
+ if ( 2 != sscanf( buffer, "%d %f\n", &param_id, &param_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 &lto)
+{
+ 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 &lto);
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 &lto)
-{
- 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 &lto);
- 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<>