From 949a9ab5dc567788b45b1af78d5330d046ce1472 Mon Sep 17 00:00:00 2001 From: Drake Arconis Date: Sun, 17 Jan 2016 23:33:21 -0500 Subject: [PATCH] Largely rework llfile* --- indra/llappearance/llwearable.cpp | 23 +- indra/llappearance/llwearable.h | 4 +- indra/llcommon/llfile.cpp | 659 ++-------------------------- indra/llcommon/llfile.h | 281 +----------- indra/llinventory/llinventory.cpp | 8 +- indra/llinventory/llpermissions.cpp | 206 ++++++--- indra/llinventory/llpermissions.h | 10 +- indra/llinventory/llsaleinfo.cpp | 99 +++-- indra/llinventory/llsaleinfo.h | 4 +- indra/newview/llviewerwearable.cpp | 18 +- indra/newview/llviewerwearable.h | 3 +- 11 files changed, 303 insertions(+), 1012 deletions(-) diff --git a/indra/llappearance/llwearable.cpp b/indra/llappearance/llwearable.cpp index 45962d898..0dbd6f3de 100644 --- a/indra/llappearance/llwearable.cpp +++ b/indra/llappearance/llwearable.cpp @@ -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; } diff --git a/indra/llappearance/llwearable.h b/indra/llappearance/llwearable.h index 3ffcc7516..d9527b9e9 100644 --- a/indra/llappearance/llwearable.h +++ b/indra/llappearance/llwearable.h @@ -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 ); diff --git a/indra/llcommon/llfile.cpp b/indra/llcommon/llfile.cpp index 686a516b9..7660baa90 100644 --- a/indra/llcommon/llfile.cpp +++ b/indra/llcommon/llfile.cpp @@ -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(__ibuf), __ilen); - __elen = fwrite(reinterpret_cast(__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(__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(__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(this->eback()), - // __buflen); - __ilen = fread(reinterpret_cast(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 - (_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(__s), __n); - __len = fread(reinterpret_cast(__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(this->pbase()); - //__ret = _M_file.xsputn_2(__buf, __buffill, - // reinterpret_cast(__s), __n); - if (__buffill) - { - __ret = fwrite(__buf, 1, __buffill, _M_file.file()); - } - if (__ret == __buffill) - { - __ret += fwrite(reinterpret_cast(__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 ********************************/ diff --git a/indra/llcommon/llfile.h b/indra/llcommon/llfile.h index cc990f6ab..eacbacca1 100644 --- a/indra/llcommon/llfile.h +++ b/indra/llcommon/llfile.h @@ -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 -#include #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(BUFSIZ)) : - size_t __size = static_cast(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(BUFSIZ)) : - size_t __size = static_cast(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(BUFSIZ)); - size_t _Size = static_cast(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(BUFSIZ)); - size_t _Size = static_cast(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(&_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(BUFSIZ)); - size_t _Size = static_cast(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(BUFSIZ)); - size_t _Size = static_cast(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(&_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. diff --git a/indra/llinventory/llinventory.cpp b/indra/llinventory/llinventory.cpp index 4a21ea334..6bce8f62e 100644 --- a/indra/llinventory/llinventory.cpp +++ b/indra/llinventory/llinventory.cpp @@ -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"; diff --git a/indra/llinventory/llpermissions.cpp b/indra/llinventory/llpermissions.cpp index b0deafdfe..2316c635d 100644 --- a/indra/llinventory/llpermissions.cpp +++ b/indra/llinventory/llpermissions.cpp @@ -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::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::instance(); -} - ///---------------------------------------------------------------------------- /// Class LLAggregatePermissions ///---------------------------------------------------------------------------- @@ -1021,7 +1129,7 @@ void mask_to_string(U32 mask, char* str) else { *str = ' '; - } + } str++; if (mask & PERM_EXPORT) diff --git a/indra/llinventory/llpermissions.h b/indra/llinventory/llpermissions.h index d3a65a5a6..a69f6033d 100644 --- a/indra/llinventory/llpermissions.h +++ b/indra/llinventory/llpermissions.h @@ -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; - virtual const LLMetaClass& getMetaClass() const; }; // Inlines diff --git a/indra/llinventory/llsaleinfo.cpp b/indra/llinventory/llsaleinfo.cpp index 2c5d163e3..021c1d9d3 100644 --- a/indra/llinventory/llsaleinfo.cpp +++ b/indra/llinventory/llsaleinfo.cpp @@ -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) diff --git a/indra/llinventory/llsaleinfo.h b/indra/llinventory/llsaleinfo.h index 8a01653a6..262aeb3dd 100644 --- a/indra/llinventory/llsaleinfo.h +++ b/indra/llinventory/llsaleinfo.h @@ -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); diff --git a/indra/newview/llviewerwearable.cpp b/indra/newview/llviewerwearable.cpp index 1f8add5c2..71bf61541 100644 --- a/indra/newview/llviewerwearable.cpp +++ b/indra/newview/llviewerwearable.cpp @@ -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; diff --git a/indra/newview/llviewerwearable.h b/indra/newview/llviewerwearable.h index 3f5d8ec17..245753865 100644 --- a/indra/newview/llviewerwearable.h +++ b/indra/newview/llviewerwearable.h @@ -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();