Skip to content
Snippets Groups Projects
Commit ae6440ee authored by Nat Goodspeed's avatar Nat Goodspeed
Browse files

MAINT-4744: Eliminate viewer dependency on (old) GNU libstdc++.

To be more accurate, this changeset doesn't actually eliminate the dependency:
it eliminates the use cases for the llifstream / llofstream feature that
requires it.
Currently you can construct an llifstream or llofstream from an open LLFILE*
file handle (or, except on Windows, an int file descriptor). But rather than
containing a streambuf implementation based on FILE*, llfile.h relies on the
fact that the Windows std::filebuf happens to support that as a nonstandard
extension; also on a nonstandard GNU extension __gnu_cxx::stdio_filebuf<char>.
To move from GNU libstdc++ to clang's libc++ (the direction on Mac), we could
code a streambuf that supports FILE*. But before doing that, it's worth asking
whether anyone actually uses this questionable feature.
In fact there were only two methods: LLWearable::exportFile() and importFile()
-- and only one call to either, in LLViewerWearable::saveNewAsset(). The code
in saveNewAsset() opened the LLFILE* immediately before calling exportFile(),
meaning we could reasonably push the open operation down into exportFile().
That logic was complex anyway due to the need for the caller to close the
LLFILE* regardless of the success of the exportFile().
Change LLWearable::exportFile() and importFile() to accept a std::string
filename rather than an open LLFILE*. Change LLViewerWearable::saveNewAsset()
to simply call exportFile(filename) rather than horsing around with an LLFILE*
handle. (This improves the code in another way too: it encapsulates the need
to open the relevant file in binary mode. Previously, each caller had to
remember to do that.)
To prevent inadvertent reintroduction of ll[io]fstream(LLFILE*) code, add
llstream_LLFILE preprocessor macro (default 0) to control access to the
relevant constructors. Also suppress rdbuf() override, the only method whose
signature references llstdio_filebuf.
parent 198046e2
No related branches found
No related tags found
No related merge requests found
...@@ -86,10 +86,10 @@ LLAssetType::EType LLWearable::getAssetType() const ...@@ -86,10 +86,10 @@ LLAssetType::EType LLWearable::getAssetType() const
return LLWearableType::getAssetType(mType); return LLWearableType::getAssetType(mType);
} }
BOOL LLWearable::exportFile(LLFILE* fp) const BOOL LLWearable::exportFile(const std::string& filename) const
{ {
llofstream ofs(fp); llofstream ofs(filename, std::ios_base::out | std::ios_base::trunc | std::ios_base::binary);
return exportStream(ofs); return ofs.is_open() && exportStream(ofs);
} }
// virtual // virtual
...@@ -201,10 +201,11 @@ void LLWearable::createLayers(S32 te, LLAvatarAppearance *avatarp) ...@@ -201,10 +201,11 @@ void LLWearable::createLayers(S32 te, LLAvatarAppearance *avatarp)
} }
} }
LLWearable::EImportResult LLWearable::importFile(LLFILE* fp, LLAvatarAppearance* avatarp ) LLWearable::EImportResult LLWearable::importFile(const std::string& filename,
LLAvatarAppearance* avatarp )
{ {
llifstream ifs(fp); llifstream ifs(filename, std::ios_base::in | std::ios_base::binary);
return importStream(ifs, avatarp); return (! ifs.is_open())? FAILURE : importStream(ifs, avatarp);
} }
// virtual // virtual
......
...@@ -81,8 +81,8 @@ class LLWearable ...@@ -81,8 +81,8 @@ class LLWearable
SUCCESS, SUCCESS,
BAD_HEADER BAD_HEADER
}; };
BOOL exportFile(LLFILE* file) const; BOOL exportFile(const std::string& filename) const;
EImportResult importFile(LLFILE* file, LLAvatarAppearance* avatarp ); EImportResult importFile(const std::string& filename, LLAvatarAppearance* avatarp );
virtual BOOL exportStream( std::ostream& output_stream ) const; virtual BOOL exportStream( std::ostream& output_stream ) const;
virtual EImportResult importStream( std::istream& input_stream, LLAvatarAppearance* avatarp ); virtual EImportResult importStream( std::istream& input_stream, LLAvatarAppearance* avatarp );
......
...@@ -919,6 +919,7 @@ llifstream::llifstream(const char* _Filename, ...@@ -919,6 +919,7 @@ llifstream::llifstream(const char* _Filename,
#endif #endif
#if llstream_LLFILE
// explicit // explicit
llifstream::llifstream(_Filet *_File, llifstream::llifstream(_Filet *_File,
ios_base::openmode _Mode, size_t _Size) : ios_base::openmode _Mode, size_t _Size) :
...@@ -942,6 +943,7 @@ llifstream::llifstream(int __fd, ...@@ -942,6 +943,7 @@ llifstream::llifstream(int __fd,
this->init(&_M_filebuf); this->init(&_M_filebuf);
} }
#endif #endif
#endif // llstream_LLFILE
bool llifstream::is_open() const bool llifstream::is_open() const
{ // test if C stream has been opened { // test if C stream has been opened
...@@ -1039,6 +1041,7 @@ llofstream::llofstream(const char* _Filename, ...@@ -1039,6 +1041,7 @@ llofstream::llofstream(const char* _Filename,
} }
#endif #endif
#if llstream_LLFILE
// explicit // explicit
llofstream::llofstream(_Filet *_File, llofstream::llofstream(_Filet *_File,
ios_base::openmode _Mode, size_t _Size) : ios_base::openmode _Mode, size_t _Size) :
...@@ -1062,6 +1065,7 @@ llofstream::llofstream(int __fd, ...@@ -1062,6 +1065,7 @@ llofstream::llofstream(int __fd,
this->init(&_M_filebuf); this->init(&_M_filebuf);
} }
#endif #endif
#endif // llstream_LLFILE
bool llofstream::is_open() const bool llofstream::is_open() const
{ // test if C stream has been opened { // test if C stream has been opened
......
...@@ -86,6 +86,12 @@ class LL_COMMON_API LLFile ...@@ -86,6 +86,12 @@ class LL_COMMON_API LLFile
static const char * tmpdir(); static const char * tmpdir();
}; };
// Remove ll[io]fstream support for [LL]FILE*, preparing to remove dependency
// on GNU's standard library.
#if ! defined(llstream_LLFILE)
#define llstream_LLFILE 0
#endif
/** /**
* @brief Provides a layer of compatibility for C/POSIX. * @brief Provides a layer of compatibility for C/POSIX.
* *
...@@ -228,6 +234,7 @@ class LL_COMMON_API llifstream : public std::istream ...@@ -228,6 +234,7 @@ class LL_COMMON_API llifstream : public std::istream
explicit llifstream(const char* _Filename, explicit llifstream(const char* _Filename,
ios_base::openmode _Mode = ios_base::in); ios_base::openmode _Mode = ios_base::in);
#if llstream_LLFILE
/** /**
* @brief Create a stream using an open c file stream. * @brief Create a stream using an open c file stream.
* @param File An open @c FILE*. * @param File An open @c FILE*.
...@@ -253,6 +260,7 @@ class LL_COMMON_API llifstream : public std::istream ...@@ -253,6 +260,7 @@ class LL_COMMON_API llifstream : public std::istream
//size_t _Size = static_cast<size_t>(BUFSIZ)); //size_t _Size = static_cast<size_t>(BUFSIZ));
size_t _Size = static_cast<size_t>(1)); size_t _Size = static_cast<size_t>(1));
#endif #endif
#endif // llstream_LLFILE
/** /**
* @brief The destructor does nothing. * @brief The destructor does nothing.
...@@ -263,6 +271,7 @@ class LL_COMMON_API llifstream : public std::istream ...@@ -263,6 +271,7 @@ class LL_COMMON_API llifstream : public std::istream
virtual ~llifstream() {} virtual ~llifstream() {}
// Members: // Members:
#if llstream_LLFILE
/** /**
* @brief Accessing the underlying buffer. * @brief Accessing the underlying buffer.
* @return The current basic_filebuf buffer. * @return The current basic_filebuf buffer.
...@@ -271,6 +280,7 @@ class LL_COMMON_API llifstream : public std::istream ...@@ -271,6 +280,7 @@ class LL_COMMON_API llifstream : public std::istream
*/ */
llstdio_filebuf* rdbuf() const llstdio_filebuf* rdbuf() const
{ return const_cast<llstdio_filebuf*>(&_M_filebuf); } { return const_cast<llstdio_filebuf*>(&_M_filebuf); }
#endif // llstream_LLFILE
/** /**
* @brief Wrapper to test for an open file. * @brief Wrapper to test for an open file.
...@@ -340,6 +350,7 @@ class LL_COMMON_API llofstream : public std::ostream ...@@ -340,6 +350,7 @@ class LL_COMMON_API llofstream : public std::ostream
explicit llofstream(const char* _Filename, explicit llofstream(const char* _Filename,
ios_base::openmode _Mode = ios_base::out|ios_base::trunc); ios_base::openmode _Mode = ios_base::out|ios_base::trunc);
#if llstream_LLFILE
/** /**
* @brief Create a stream using an open c file stream. * @brief Create a stream using an open c file stream.
* @param File An open @c FILE*. * @param File An open @c FILE*.
...@@ -365,6 +376,7 @@ class LL_COMMON_API llofstream : public std::ostream ...@@ -365,6 +376,7 @@ class LL_COMMON_API llofstream : public std::ostream
//size_t _Size = static_cast<size_t>(BUFSIZ)); //size_t _Size = static_cast<size_t>(BUFSIZ));
size_t _Size = static_cast<size_t>(1)); size_t _Size = static_cast<size_t>(1));
#endif #endif
#endif // llstream_LLFILE
/** /**
* @brief The destructor does nothing. * @brief The destructor does nothing.
...@@ -375,6 +387,7 @@ class LL_COMMON_API llofstream : public std::ostream ...@@ -375,6 +387,7 @@ class LL_COMMON_API llofstream : public std::ostream
virtual ~llofstream() {} virtual ~llofstream() {}
// Members: // Members:
#if llstream_LLFILE
/** /**
* @brief Accessing the underlying buffer. * @brief Accessing the underlying buffer.
* @return The current basic_filebuf buffer. * @return The current basic_filebuf buffer.
...@@ -383,6 +396,7 @@ class LL_COMMON_API llofstream : public std::ostream ...@@ -383,6 +396,7 @@ class LL_COMMON_API llofstream : public std::ostream
*/ */
llstdio_filebuf* rdbuf() const llstdio_filebuf* rdbuf() const
{ return const_cast<llstdio_filebuf*>(&_M_filebuf); } { return const_cast<llstdio_filebuf*>(&_M_filebuf); }
#endif // llstream_LLFILE
/** /**
* @brief Wrapper to test for an open file. * @brief Wrapper to test for an open file.
......
...@@ -509,18 +509,7 @@ void LLViewerWearable::saveNewAsset() const ...@@ -509,18 +509,7 @@ void LLViewerWearable::saveNewAsset() const
//LL_INFOS() << *this << LL_ENDL; //LL_INFOS() << *this << LL_ENDL;
const std::string filename = asset_id_to_filename(mAssetID); const std::string filename = asset_id_to_filename(mAssetID);
LLFILE* fp = LLFile::fopen(filename, "wb"); /* Flawfinder: ignore */ if(! exportFile(filename))
BOOL successful_save = FALSE;
if(fp && exportFile(fp))
{
successful_save = TRUE;
}
if(fp)
{
fclose(fp);
fp = NULL;
}
if(!successful_save)
{ {
std::string buffer = llformat("Unable to save '%s' to wearable file.", mName.c_str()); std::string buffer = llformat("Unable to save '%s' to wearable file.", mName.c_str());
LL_WARNS() << buffer << LL_ENDL; LL_WARNS() << buffer << LL_ENDL;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment