Largely rework llfile*

This commit is contained in:
Drake Arconis
2016-01-17 23:33:21 -05:00
parent e545281387
commit 949a9ab5dc
11 changed files with 303 additions and 1012 deletions

View File

@@ -86,10 +86,10 @@ LLAssetType::EType LLWearable::getAssetType() const
return LLWearableType::getAssetType(mType);
}
BOOL LLWearable::exportFile(LLFILE* fp) const
BOOL LLWearable::exportFile(const std::string& filename) const
{
llofstream ofs(fp);
return exportStream(ofs);
llofstream ofs(filename.c_str(), std::ios_base::out | std::ios_base::trunc | std::ios_base::binary);
return ofs.is_open() && exportStream(ofs);
}
// virtual
@@ -105,13 +105,13 @@ BOOL LLWearable::exportStream( std::ostream& output_stream ) const
output_stream << mDescription << "\n";
// permissions
if( !mPermissions.exportStream( output_stream ) )
if( !mPermissions.exportLegacyStream( output_stream ) )
{
return FALSE;
}
// sale info
if( !mSaleInfo.exportStream( output_stream ) )
if( !mSaleInfo.exportLegacyStream( output_stream ) )
{
return FALSE;
}
@@ -193,7 +193,7 @@ void LLWearable::createLayers(S32 te, LLAvatarAppearance *avatarp)
if (layer_set)
{
layer_set->cloneTemplates(mTEMap[te], (ETextureIndex)te, this);
layer_set->cloneTemplates(mTEMap[te], (ETextureIndex)te, this);
}
else
{
@@ -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);
return importStream(ifs, avatarp);
llifstream ifs(filename.c_str(), std::ios_base::in | std::ios_base::binary);
return (! ifs.is_open())? FAILURE : importStream(ifs, avatarp);
}
// virtual
@@ -287,7 +288,7 @@ LLWearable::EImportResult LLWearable::importStream( std::istream& input_stream,
LL_WARNS() << "Bad Wearable asset: missing valid permissions" << LL_ENDL;
return LLWearable::FAILURE;
}
if( !mPermissions.importStream( input_stream ) )
if( !mPermissions.importLegacyStream( input_stream ) )
{
return LLWearable::FAILURE;
}
@@ -312,7 +313,7 @@ LLWearable::EImportResult LLWearable::importStream( std::istream& input_stream,
// up the vast majority of the tasks.
BOOL has_perm_mask = FALSE;
U32 perm_mask = 0;
if( !mSaleInfo.importStream(input_stream, has_perm_mask, perm_mask) )
if( !mSaleInfo.importLegacyStream(input_stream, has_perm_mask, perm_mask) )
{
return LLWearable::FAILURE;
}

View File

@@ -82,8 +82,8 @@ public:
SUCCESS,
BAD_HEADER
};
BOOL exportFile(LLFILE* file) const;
EImportResult importFile(LLFILE* file, LLAvatarAppearance* avatarp );
BOOL exportFile(const std::string& filename) const;
EImportResult importFile(const std::string& filename, LLAvatarAppearance* avatarp );
virtual BOOL exportStream( std::ostream& output_stream ) const;
virtual EImportResult importStream( std::istream& input_stream, LLAvatarAppearance* avatarp );

View File

@@ -416,679 +416,76 @@ LLFILE * LLFile::_Fiopen(const std::string& filename,
#endif /* LL_WINDOWS */
/************** 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
//}
// *TODO: Seek the underlying c stream for better cross-platform compatibility?
#if !LL_WINDOWS
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)
{
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;
}
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);
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)
{
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"));
}
return __ret;
}
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;
}
std::streamsize llstdio_filebuf::xsputn(char_type const* __s, std::streamsize __n)
{
// 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)
{
// 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);
}
else
__ret = __streambuf_type::xsputn(__s, __n);
return __ret;
}
int llstdio_filebuf::sync()
{
return (_M_file.sync() == 0 ? 0 : -1);
}
#endif
#if LL_WINDOWS
/************** input file stream ********************************/
llifstream::llifstream() : _M_filebuf(),
#if LL_WINDOWS
std::istream(&_M_filebuf) {}
#else
std::istream()
llifstream::llifstream() : std::ifstream()
{
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)
llifstream::llifstream(const std::string& _Filename, ios_base::openmode _Mode) :
std::ifstream(utf8str_to_utf16str(_Filename),
_Mode | ios_base::in)
{
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
llifstream::llifstream(const char* _Filename, ios_base::openmode _Mode) :
std::ifstream(utf8str_to_utf16str(_Filename).c_str(),
_Mode | ios_base::in)
// 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()
void llifstream::open(const std::string& _Filename, ios_base::openmode _Mode)
{
this->init(&_M_filebuf);
}
#endif
bool llifstream::is_open() const
{ // test if C stream has been opened
return _M_filebuf.is_open();
std::ifstream::open(utf8str_to_utf16str(_Filename),
_Mode | ios_base::in);
}
void llifstream::open(const char* _Filename, ios_base::openmode _Mode)
{ // open a C stream with specified mode
if (_M_filebuf.open(_Filename, _Mode | ios_base::in) == 0)
#if LL_WINDOWS
{
_Myios::setstate(ios_base::failbit);
}
else
{
_Myios::clear();
}
#else
{
this->setstate(ios_base::failbit);
}
else
{
this->clear();
}
#endif
}
void llifstream::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
}
{
std::ifstream::open(utf8str_to_utf16str(_Filename).c_str(),
_Mode | ios_base::in);
}
/************** output file stream ********************************/
llofstream::llofstream() : _M_filebuf(),
#if LL_WINDOWS
std::ostream(&_M_filebuf) {}
#else
std::ostream()
llofstream::llofstream() : std::ofstream()
{
this->init(&_M_filebuf);
}
#endif
// explicit
llofstream::llofstream(const std::string& _Filename,
ios_base::openmode _Mode) : _M_filebuf(),
#if LL_WINDOWS
std::ostream(&_M_filebuf)
llofstream::llofstream(const std::string& _Filename, ios_base::openmode _Mode) :
std::ofstream(utf8str_to_utf16str(_Filename),
_Mode | ios_base::out)
{
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)
llofstream::llofstream(const char* _Filename, ios_base::openmode _Mode) :
std::ofstream(utf8str_to_utf16str(_Filename).c_str(),
_Mode | ios_base::out)
{
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()
void llofstream::open(const std::string& _Filename, ios_base::openmode _Mode)
{
this->init(&_M_filebuf);
}
#endif
#if !LL_WINDOWS
// explicit
llofstream::llofstream(int __fd,
ios_base::openmode _Mode, size_t _Size) :
_M_filebuf(__fd, _Mode, _Size),
std::ostream()
{
this->init(&_M_filebuf);
}
#endif
bool llofstream::is_open() const
{ // test if C stream has been opened
return _M_filebuf.is_open();
std::ofstream::open(utf8str_to_utf16str(_Filename),
_Mode | ios_base::out);
}
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
{
_Myios::clear();
}
#else
{
this->setstate(ios_base::failbit);
}
else
{
this->clear();
}
#endif
{
std::ofstream::open(utf8str_to_utf16str(_Filename).c_str(),
_Mode | ios_base::out);
}
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
}
}
#endif // LL_WINDOWS
/************** helper functions ********************************/

View File

@@ -38,15 +38,13 @@
* Attempts to mostly mirror the POSIX style IO functions.
*/
typedef FILE LLFILE;
typedef FILE LLFILE;
#if LL_WINDOWS
// windows version of stat function and stat data structure are called _stat
typedef struct _stat llstat;
#else
typedef struct stat llstat;
#include <ext/stdio_filebuf.h>
#include <bits/postypes.h>
#endif
#ifndef S_ISREG
@@ -93,135 +91,20 @@ public:
static std::string strerr();
};
/**
* @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;
//Singu note: Wrap around std::filebuf to override the open procedure.
// The client encodes filepaths in UTF-8, however Windows uses UTF-16 encoding natively.
// Need to convert paths to UTF-16 before calling std::filebuf::open.
struct _Myfb : public std::filebuf
{
_Myfb() : std::filebuf() {}
_Myfb(_Filet* file) : std::filebuf(file) {}
_Myt *open(const char *filename, std::ios_base::openmode mode, int prot = (int)std::ios_base::_Openprot)
{
return std::filebuf::open(utf8str_to_utf16str(filename).c_str(),mode,prot);
}
};
#if !defined(LL_WINDOWS)
typedef std::ifstream llifstream;
typedef std::ofstream llofstream;
#else
typedef __gnu_cxx::stdio_filebuf< char > _Myfb;
typedef std::__c_file _Filet;
#endif /* LL_WINDOWS */
}
class LL_COMMON_API llstdio_filebuf : public _Myfb
{
public:
/**
* 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
/**
* @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
// *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 const*, std::streamsize);
#endif
};
/**
* @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
* functions from std::ifstream. The only added value is that our constructor
* Does The Right Thing when passed a non-ASCII pathname. Sadly, that isn't
* true of Microsoft's std::ifstream.
*/
class LL_COMMON_API llifstream : public std::ifstream
{
// input stream associated with a C stream
public:
@@ -247,56 +130,6 @@ public:
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;
/**
* @brief Opens an external file.
* @param Filename The name of the file.
@@ -306,34 +139,21 @@ public:
* 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); }
ios_base::openmode _Mode = ios_base::in);
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:
llstdio_filebuf _M_filebuf;
};
/**
* @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
* This class supports writing to named files, using the inherited functions
* from std::ofstream. The only added value is that our constructor Does The
* Right Thing when passed a non-ASCII pathname. Sadly, that isn't true of
* Microsoft's std::ofstream.
*/
class LL_COMMON_API llofstream : public std::ofstream
{
public:
// Constructors:
@@ -351,64 +171,13 @@ public:
* @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.
* @c ios_base::out 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
/**
* @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;
/**
* @brief Opens an external file.
* @param Filename The name of the file.
@@ -418,23 +187,11 @@ public:
* 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); }
ios_base::openmode _Mode = ios_base::out | ios_base::trunc);
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.

View File

@@ -831,7 +831,7 @@ BOOL LLInventoryItem::importLegacyStream(std::istream& input_stream)
}
else if(0 == strcmp("permissions", keyword))
{
success = mPermissions.importStream(input_stream);
success = mPermissions.importLegacyStream(input_stream);
}
else if(0 == strcmp("sale_info", keyword))
{
@@ -841,7 +841,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.importStream(input_stream, has_perm_mask, perm_mask);
success = mSaleInfo.importLegacyStream(input_stream, has_perm_mask, perm_mask);
if(has_perm_mask)
{
if(perm_mask == PERM_NONE)
@@ -957,7 +957,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.exportStream(output_stream);
mPermissions.exportLegacyStream(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.
@@ -991,7 +991,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.exportStream(output_stream);
mSaleInfo.exportLegacyStream(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";

View File

@@ -31,7 +31,6 @@
// library includes
#include "message.h"
#include "metapropertyt.h"
#include "llsd.h"
///----------------------------------------------------------------------------
@@ -572,17 +571,143 @@ void LLPermissions::unpackMessage(LLMessageSystem* msg, const char* block, S32 b
BOOL LLPermissions::importFile(LLFILE* fp)
{
llifstream ifs(fp);
return importStream(ifs);
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
{
LL_INFOS() << "unknown keyword " << keyword << " in permissions import" << LL_ENDL;
}
}
fix();
return TRUE;
}
BOOL LLPermissions::exportFile(LLFILE* fp) const
{
llofstream ofs(fp);
return exportStream(ofs);
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;
}
BOOL LLPermissions::importStream(std::istream& input_stream)
BOOL LLPermissions::importLegacyStream(std::istream& input_stream)
{
init(LLUUID::null, LLUUID::null, LLUUID::null, LLUUID::null);
const S32 BUFSIZE = 16384;
@@ -601,18 +726,6 @@ BOOL LLPermissions::importStream(std::istream& input_stream)
while (input_stream.good())
{
input_stream.getline(buffer, BUFSIZE);
if (input_stream.eof())
{
LL_WARNS() << "Bad permissions: early end of input stream"
<< LL_ENDL;
return FALSE;
}
if (input_stream.fail())
{
LL_WARNS() << "Bad permissions: failed to read from input stream"
<< LL_ENDL;
return FALSE;
}
sscanf( /* Flawfinder: ignore */
buffer,
" %255s %255s",
@@ -695,26 +808,36 @@ BOOL LLPermissions::importStream(std::istream& input_stream)
}
BOOL LLPermissions::exportStream(std::ostream& output_stream) const
BOOL LLPermissions::exportLegacyStream(std::ostream& output_stream) const
{
if (!output_stream.good()) return FALSE;
std::string uuid_str;
output_stream << "\tpermissions 0\n";
output_stream << "\t{\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);
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;
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";
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";
if(mIsGroupOwned)
{
@@ -772,21 +895,6 @@ std::ostream& operator<<(std::ostream &s, const LLPermissions &perm)
return s;
}
template <>
void LLMetaClassT<LLPermissions>::reflectProperties(LLMetaClass& meta_class)
{
reflectProperty(meta_class, "mCreator", &LLPermissions::mCreator);
reflectProperty(meta_class, "mOwner", &LLPermissions::mOwner);
reflectProperty(meta_class, "mGroup", &LLPermissions::mGroup);
reflectProperty(meta_class, "mIsGroupOwned", &LLPermissions::mIsGroupOwned);
}
// virtual
const LLMetaClass& LLPermissions::getMetaClass() const
{
return LLMetaClassT<LLPermissions>::instance();
}
///----------------------------------------------------------------------------
/// Class LLAggregatePermissions
///----------------------------------------------------------------------------
@@ -1021,7 +1129,7 @@ void mask_to_string(U32 mask, char* str)
else
{
*str = ' ';
}
}
str++;
if (mask & PERM_EXPORT)

View File

@@ -31,7 +31,6 @@
#include "llsd.h"
#include "lluuid.h"
#include "llxmlnode.h"
#include "reflective.h"
#include "llinventorytype.h"
// prototypes
@@ -89,7 +88,7 @@ enum ExportPolicy {
// logical consistency.
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
class LLPermissions : public LLReflective
class LLPermissions
{
private:
LLUUID mCreator; // null if object created by system
@@ -329,17 +328,14 @@ public:
BOOL importFile(LLFILE* fp);
BOOL exportFile(LLFILE* fp) const;
BOOL importStream(std::istream& input_stream);
BOOL exportStream(std::ostream& output_stream) const;
BOOL importLegacyStream(std::istream& input_stream);
BOOL exportLegacyStream(std::ostream& output_stream) const;
bool operator==(const LLPermissions &rhs) const;
bool operator!=(const LLPermissions &rhs) const;
friend std::ostream& operator<<(std::ostream &s, const LLPermissions &perm);
// Reflection.
friend class LLMetaClassT<LLPermissions>;
virtual const LLMetaClass& getMetaClass() const;
};
// Inlines

View File

@@ -87,13 +87,15 @@ U32 LLSaleInfo::getCRC32() const
BOOL LLSaleInfo::exportFile(LLFILE* fp) const
{
llofstream ofs(fp);
return exportStream(ofs);
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;
}
BOOL LLSaleInfo::exportStream(std::ostream& output_stream) const
BOOL LLSaleInfo::exportLegacyStream(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";
@@ -137,40 +139,25 @@ bool LLSaleInfo::fromLLSD(const LLSD& sd, BOOL& has_perm_mask, U32& perm_mask)
// because I can't find any non-test code references to it. 2009-05-04 JC
BOOL LLSaleInfo::importFile(LLFILE* fp, BOOL& has_perm_mask, U32& perm_mask)
{
llifstream ifs(fp);
return importStream(ifs, has_perm_mask, 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[BUFSIZE]; /* Flawfinder: ignore */
char keyword[255]; /* Flawfinder: ignore */
char valuestr[255]; /* Flawfinder: ignore */
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(input_stream.good())
while(success && (!feof(fp)))
{
input_stream.getline(buffer, MAX_STRING);
if (input_stream.eof())
if (fgets(buffer, MAX_STRING, fp) == NULL)
{
LL_WARNS() << "Bad sale info: early end of input stream"
<< LL_ENDL;
return FALSE;
}
if (input_stream.fail())
{
LL_WARNS() << "Bad sale info: failed to read from input stream"
<< LL_ENDL;
return FALSE;
buffer[0] = '\0';
}
sscanf( /* Flawfinder: ignore */
buffer,
" %254s %254s",
@@ -208,7 +195,63 @@ BOOL LLSaleInfo::importStream(std::istream& input_stream, BOOL& has_perm_mask, U
<< "' in sale info import" << LL_ENDL;
}
}
return TRUE;
return success;
}
BOOL LLSaleInfo::importLegacyStream(std::istream& input_stream, 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 && input_stream.good())
{
input_stream.getline(buffer, MAX_STRING);
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))
{
//LL_INFOS() << "found deprecated keyword perm_mask" << LL_ENDL;
has_perm_mask = TRUE;
sscanf(valuestr, "%x", &perm_mask);
}
else
{
LL_WARNS() << "unknown keyword '" << keyword
<< "' in sale info import" << LL_ENDL;
}
}
return success;
}
void LLSaleInfo::setSalePrice(S32 price)

View File

@@ -95,11 +95,11 @@ public:
BOOL exportFile(LLFILE* fp) const;
BOOL importFile(LLFILE* fp, BOOL& has_perm_mask, U32& perm_mask);
BOOL exportStream(std::ostream& output_stream) const;
BOOL exportLegacyStream(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 importStream(std::istream& input_stream, BOOL& has_perm_mask, U32& perm_mask);
BOOL importLegacyStream(std::istream& input_stream, BOOL& has_perm_mask, U32& perm_mask);
LLSD packMessage() const;
void unpackMessage(const LLSD& sales);

View File

@@ -42,7 +42,6 @@
#include "llinventoryfunctions.h"
#include "lllocaltextureobject.h"
#include "llpaneleditwearable.h"
#include "aixmllindengenepool.h"
using namespace LLAvatarAppearanceDefines;
@@ -136,7 +135,7 @@ LLWearable::EImportResult LLViewerWearable::importStream( std::istream& input_st
return result;
}
#if 0
AIArchetype LLViewerWearable::getArchetype(void) const
{
AIArchetype archetype(this);
@@ -150,7 +149,7 @@ AIArchetype LLViewerWearable::getArchetype(void) const
}
return archetype;
}
#endif
// Avatar parameter and texture definitions can change over time.
// This function returns true if parameters or textures have been added or removed
// since this wearable was created.
@@ -600,18 +599,7 @@ void LLViewerWearable::saveNewAsset() const
//LL_INFOS() << *this << LL_ENDL;
const std::string filename = asset_id_to_filename(mAssetID);
LLFILE* fp = LLFile::fopen(filename, "wb"); /* Flawfinder: ignore */
BOOL successful_save = FALSE;
if(fp && exportFile(fp))
{
successful_save = TRUE;
}
if(fp)
{
fclose(fp);
fp = NULL;
}
if(!successful_save)
if(! exportFile(filename))
{
std::string buffer = llformat("Unable to save '%s' to wearable file.", mName.c_str());
LL_WARNS() << buffer << LL_ENDL;

View File

@@ -29,7 +29,6 @@
#include "llwearable.h"
#include "llavatarappearancedefines.h"
#include "aixmllindengenepool.h"
class LLVOAvatar;
class LLAPRFile;
@@ -69,7 +68,9 @@ public:
/*virtual*/ EImportResult importStream( std::istream& input_stream, LLAvatarAppearance* avatarp );
// Singu extension.
#if 0
AIArchetype getArchetype(void) const;
#endif
void setParamsToDefaults();
void setTexturesToDefaults();