From 2fa1c42aadbe2a29e1bcced9a487c0e5abf0602b Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Thu, 29 Mar 2012 23:48:29 -0700 Subject: CHUI-51 WIP notifications routig code cleanup phase 2, removal of extraneous signaling in favor of llnotificationchannels made notificationchannels work better with overrides and lifetime managed by creator --- indra/llcommon/llinstancetracker.h | 5 ++++- indra/llcommon/llrefcount.h | 19 +++++++++++++++++++ indra/llcommon/llthread.h | 17 +++++++++++++++++ 3 files changed, 40 insertions(+), 1 deletion(-) (limited to 'indra/llcommon') diff --git a/indra/llcommon/llinstancetracker.h b/indra/llcommon/llinstancetracker.h index 34d841a4e0..11f582372e 100644 --- a/indra/llcommon/llinstancetracker.h +++ b/indra/llcommon/llinstancetracker.h @@ -43,7 +43,7 @@ * semantics: one instance per process, rather than one instance per module as * sometimes happens with data simply declared static. */ -class LL_COMMON_API LLInstanceTrackerBase : public boost::noncopyable +class LL_COMMON_API LLInstanceTrackerBase { protected: /// Get a process-unique void* pointer slot for the specified type_info @@ -209,6 +209,9 @@ protected: virtual const KEY& getKey() const { return mInstanceKey; } private: + LLInstanceTracker( const LLInstanceTracker& ); + const LLInstanceTracker& operator=( const LLInstanceTracker& ); + void add_(KEY key) { mInstanceKey = key; diff --git a/indra/llcommon/llrefcount.h b/indra/llcommon/llrefcount.h index 8eb5d53f3f..32ae15435a 100644 --- a/indra/llcommon/llrefcount.h +++ b/indra/llcommon/llrefcount.h @@ -27,6 +27,7 @@ #define LLREFCOUNT_H #include +#include #define LL_REF_COUNT_DEBUG 0 #if LL_REF_COUNT_DEBUG @@ -86,4 +87,22 @@ private: #endif }; +/** + * intrusive pointer support + * this allows you to use boost::intrusive_ptr with any LLRefCount-derived type + */ +namespace boost +{ + inline void intrusive_ptr_add_ref(LLRefCount* p) + { + p->ref(); + } + + inline void intrusive_ptr_release(LLRefCount* p) + { + p->unref(); + } +}; + + #endif diff --git a/indra/llcommon/llthread.h b/indra/llcommon/llthread.h index b52e70ab2e..cf39696b4f 100644 --- a/indra/llcommon/llthread.h +++ b/indra/llcommon/llthread.h @@ -30,6 +30,7 @@ #include "llapp.h" #include "llapr.h" #include "apr_thread_cond.h" +#include "boost/intrusive_ptr.hpp" class LLThread; class LLMutex; @@ -266,6 +267,22 @@ private: S32 mRef; }; +/** + * intrusive pointer support for LLThreadSafeRefCount + * this allows you to use boost::intrusive_ptr with any LLThreadSafeRefCount-derived type + */ +namespace boost +{ + inline void intrusive_ptr_add_ref(LLThreadSafeRefCount* p) + { + p->ref(); + } + + inline void intrusive_ptr_release(LLThreadSafeRefCount* p) + { + p->unref(); + } +}; //============================================================================ // Simple responder for self destructing callbacks -- cgit v1.2.3 From 9b92235291382deac15b860efa281f625d2173dd Mon Sep 17 00:00:00 2001 From: Seth ProductEngine Date: Fri, 8 Jun 2012 01:08:58 +0300 Subject: CHUI-120 WIP Added conversations participants drag and drop from avatar lists to IM floaters. - Added new drag and drop type DAD_PERSON and source SOURCE_PEOPLE to avoid highliting the toolbars when using SOURCE_VIEWER. - Disabled calling card drop support as it is considered obsolete. --- indra/llcommon/llassettype.cpp | 1 + indra/llcommon/llassettype.h | 3 +++ indra/llcommon/stdenums.h | 3 ++- 3 files changed, 6 insertions(+), 1 deletion(-) (limited to 'indra/llcommon') diff --git a/indra/llcommon/llassettype.cpp b/indra/llcommon/llassettype.cpp index 5e566d6c7c..5ae2df3994 100644 --- a/indra/llcommon/llassettype.cpp +++ b/indra/llcommon/llassettype.cpp @@ -95,6 +95,7 @@ LLAssetDictionary::LLAssetDictionary() addEntry(LLAssetType::AT_LINK_FOLDER, new AssetEntry("FOLDER_LINK", "link_f", "sym folder link", false, false, true)); addEntry(LLAssetType::AT_MESH, new AssetEntry("MESH", "mesh", "mesh", false, false, false)); addEntry(LLAssetType::AT_WIDGET, new AssetEntry("WIDGET", "widget", "widget", false, false, false)); + addEntry(LLAssetType::AT_PERSON, new AssetEntry("PERSON", "person", "person", false, false, false)); addEntry(LLAssetType::AT_NONE, new AssetEntry("NONE", "-1", NULL, FALSE, FALSE, FALSE)); }; diff --git a/indra/llcommon/llassettype.h b/indra/llcommon/llassettype.h index d538accbf7..69b01731e5 100644 --- a/indra/llcommon/llassettype.h +++ b/indra/llcommon/llassettype.h @@ -112,6 +112,9 @@ public: AT_WIDGET = 40, // UI Widget: this is *not* an inventory asset type, only a viewer side asset (e.g. button, other ui items...) + AT_PERSON = 45, + // A user uuid which is not an inventory asset type, used in viewer only for adding a person to a chat via drag and drop. + AT_MESH = 49, // Mesh data in our proprietary SLM format diff --git a/indra/llcommon/stdenums.h b/indra/llcommon/stdenums.h index 40b3364b36..efcbe76795 100644 --- a/indra/llcommon/stdenums.h +++ b/indra/llcommon/stdenums.h @@ -51,7 +51,8 @@ enum EDragAndDropType DAD_LINK = 14, DAD_MESH = 15, DAD_WIDGET = 16, - DAD_COUNT = 17, // number of types in this enum + DAD_PERSON = 17, + DAD_COUNT = 18, // number of types in this enum }; // Reasons for drags to be denied. -- cgit v1.2.3 From e4a0dda457039b1a04c74024d9fbcf02e071b13d Mon Sep 17 00:00:00 2001 From: "Brad Payne (Vir Linden)" Date: Thu, 28 Jun 2012 14:24:04 -0400 Subject: SH-3228 WIP - always respond to processAppearance for self, convert baked textures to checkerboards --- indra/llcommon/imageids.cpp | 3 +++ indra/llcommon/imageids.h | 1 + 2 files changed, 4 insertions(+) mode change 100644 => 100755 indra/llcommon/imageids.cpp mode change 100644 => 100755 indra/llcommon/imageids.h (limited to 'indra/llcommon') diff --git a/indra/llcommon/imageids.cpp b/indra/llcommon/imageids.cpp old mode 100644 new mode 100755 index fe11465221..7d647e5c36 --- a/indra/llcommon/imageids.cpp +++ b/indra/llcommon/imageids.cpp @@ -68,3 +68,6 @@ const LLUUID TERRAIN_MOUNTAIN_DETAIL ("303cd381-8560-7579-23f1-f0a880799740"); / const LLUUID TERRAIN_ROCK_DETAIL ("53a2f406-4895-1d13-d541-d2e3b86bc19c"); // VIEWER const LLUUID DEFAULT_WATER_NORMAL ("822ded49-9a6c-f61c-cb89-6df54f42cdf4"); // VIEWER + +const LLUUID IMG_CHECKERBOARD_RGBA ("2585a0f3-4163-6dd1-0f34-ad48cb909e25"); // dataserver + diff --git a/indra/llcommon/imageids.h b/indra/llcommon/imageids.h old mode 100644 new mode 100755 index e0c2683fdc..18c8ecb074 --- a/indra/llcommon/imageids.h +++ b/indra/llcommon/imageids.h @@ -66,4 +66,5 @@ LL_COMMON_API extern const LLUUID TERRAIN_ROCK_DETAIL; LL_COMMON_API extern const LLUUID DEFAULT_WATER_NORMAL; +LL_COMMON_API extern const LLUUID IMG_CHECKERBOARD_RGBA; #endif -- cgit v1.2.3 From 118e3b33bd417331397f89770d46b1b3eeeffc8e Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Fri, 3 Aug 2012 17:43:48 -0700 Subject: CHUI-270 FIX Progress spinner not visible in merchant outbox --- indra/llcommon/llinitparam.cpp | 7 ++----- indra/llcommon/llinitparam.h | 10 +++++++--- 2 files changed, 9 insertions(+), 8 deletions(-) (limited to 'indra/llcommon') diff --git a/indra/llcommon/llinitparam.cpp b/indra/llcommon/llinitparam.cpp index 451b638a3f..89c831d296 100644 --- a/indra/llcommon/llinitparam.cpp +++ b/indra/llcommon/llinitparam.cpp @@ -335,15 +335,12 @@ namespace LLInitParam { const std::string& top_name = name_stack_range.first->first; - ParamDescriptor::deserialize_func_t deserialize_func = NULL; - Param* paramp = NULL; - BlockDescriptor::param_map_t::iterator found_it = block_data.mNamedParams.find(top_name); if (found_it != block_data.mNamedParams.end()) { // find pointer to member parameter from offset table - paramp = getParamFromHandle(found_it->second->mParamHandle); - deserialize_func = found_it->second->mDeserializeFunc; + Param* paramp = getParamFromHandle(found_it->second->mParamHandle); + ParamDescriptor::deserialize_func_t deserialize_func = found_it->second->mDeserializeFunc; Parser::name_stack_range_t new_name_stack(name_stack_range.first, name_stack_range.second); ++new_name_stack.first; diff --git a/indra/llcommon/llinitparam.h b/indra/llcommon/llinitparam.h index 2f767c234e..14ba8e0b43 100644 --- a/indra/llcommon/llinitparam.h +++ b/indra/llcommon/llinitparam.h @@ -2194,7 +2194,7 @@ namespace LLInitParam resetToDefault(); } return mValue.deserializeBlock(p, name_stack_range, new_name); - } + } void serializeBlock(Parser& p, Parser::name_stack_t& name_stack, const self_t* diff_block = NULL) const { @@ -2211,12 +2211,16 @@ namespace LLInitParam bool mergeBlockParam(bool source_provided, bool dst_provided, BlockDescriptor& block_data, const self_t& source, bool overwrite) { - if (overwrite) + if ((overwrite && source_provided) // new values coming in on top or... + || (!overwrite && !dst_provided)) // values being pushed under with nothing already there { + // clear away what is there and take the new stuff as a whole resetToDefault(); return mValue.mergeBlock(block_data, source.getValue(), overwrite); } - return false; + + + return mValue.mergeBlock(block_data, source.getValue(), overwrite); } bool validateBlock(bool emit_errors = true) const -- cgit v1.2.3 From a1a1410d25c3e4ff87e33344b416b7a827cdb1c2 Mon Sep 17 00:00:00 2001 From: William Todd Stinson Date: Mon, 27 Aug 2012 18:16:47 -0700 Subject: Skipping the realloc alignment test on Linux as the ll_aligned_malloc_16() function is not implemented to ensure alignment on Linux. --- indra/llcommon/llmemory.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'indra/llcommon') diff --git a/indra/llcommon/llmemory.h b/indra/llcommon/llmemory.h index 9dd776ff57..08e2a2caa6 100644 --- a/indra/llcommon/llmemory.h +++ b/indra/llcommon/llmemory.h @@ -65,6 +65,8 @@ inline void* ll_aligned_realloc_16(void* ptr, size_t size) // returned hunk MUST #elif defined(LL_DARWIN) return realloc(ptr,size); // default osx malloc is 16 byte aligned. #else + // The realloc alignment test is skipped on Linux because the ll_aligned_realloc_16() + // function is not implemented to ensure alignment (see alignment_test.cpp) return realloc(ptr,size); // FIXME not guaranteed to be aligned. #endif } -- cgit v1.2.3 From 5dc8738076d158aa74a93f7f3630a17d9102fdc4 Mon Sep 17 00:00:00 2001 From: Gilbert Gonzales Date: Mon, 10 Sep 2012 07:40:13 -0700 Subject: CHUI-283: Basic Implementation, just have hard coded avatar icon appearing and profile/info buttons visible. profile/info buttons do not have proper positioning or mouseclick events. --- indra/llcommon/llfoldertype.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) mode change 100644 => 100755 indra/llcommon/llfoldertype.h (limited to 'indra/llcommon') diff --git a/indra/llcommon/llfoldertype.h b/indra/llcommon/llfoldertype.h old mode 100644 new mode 100755 index a0c847914f..6b5ae572a9 --- a/indra/llcommon/llfoldertype.h +++ b/indra/llcommon/llfoldertype.h @@ -89,7 +89,9 @@ public: FT_COUNT, - FT_NONE = -1 + FT_NONE = -1, + + FT_PROFILE = 58 }; static EType lookup(const std::string& type_name); -- cgit v1.2.3 From c6863d18d7c981756c57bbcd52baa06af00d1551 Mon Sep 17 00:00:00 2001 From: Gilbert Gonzales Date: Thu, 13 Sep 2012 19:10:28 -0700 Subject: CHUI-283: Now upon the information icon and speaker icon do not overlap the username text. Instead the username text will be truncated with an ellipse to prevent the overlap. Also did a code cleanup. --- indra/llcommon/llfoldertype.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/llcommon') diff --git a/indra/llcommon/llfoldertype.h b/indra/llcommon/llfoldertype.h index 6b5ae572a9..609b550900 100755 --- a/indra/llcommon/llfoldertype.h +++ b/indra/llcommon/llfoldertype.h @@ -91,7 +91,7 @@ public: FT_NONE = -1, - FT_PROFILE = 58 + FT_PROFILEXXXGGG = 58 }; static EType lookup(const std::string& type_name); -- cgit v1.2.3 From 8808325ced4d380d937c9be1cc81e20a5ebb5f62 Mon Sep 17 00:00:00 2001 From: Don Kjer Date: Fri, 14 Sep 2012 11:27:04 +0000 Subject: Removed appearance utility from viewer source. Added appearance utility autobuild package. --- indra/llcommon/llversionserver.h | 2 +- indra/llcommon/llversionviewer.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'indra/llcommon') diff --git a/indra/llcommon/llversionserver.h b/indra/llcommon/llversionserver.h index b19ba3bf74..ef68a0eaf5 100644 --- a/indra/llcommon/llversionserver.h +++ b/indra/llcommon/llversionserver.h @@ -30,7 +30,7 @@ const S32 LL_VERSION_MAJOR = 2; const S32 LL_VERSION_MINOR = 1; const S32 LL_VERSION_PATCH = 0; -const S32 LL_VERSION_BUILD = 13828; +const S32 LL_VERSION_BUILD = 264760; const char * const LL_CHANNEL = "Second Life Server"; diff --git a/indra/llcommon/llversionviewer.h b/indra/llcommon/llversionviewer.h index bcc661a920..295fed3c4b 100644 --- a/indra/llcommon/llversionviewer.h +++ b/indra/llcommon/llversionviewer.h @@ -30,7 +30,7 @@ const S32 LL_VERSION_MAJOR = 3; const S32 LL_VERSION_MINOR = 4; const S32 LL_VERSION_PATCH = 1; -const S32 LL_VERSION_BUILD = 0; +const S32 LL_VERSION_BUILD = 264760; const char * const LL_CHANNEL = "Second Life Developer"; -- cgit v1.2.3 From 3c8407f32cf947ee1631ed66bba7a676e8b3b670 Mon Sep 17 00:00:00 2001 From: Gilbert Gonzales Date: Tue, 18 Sep 2012 12:15:51 -0700 Subject: CHUI-283: Now the avatar icon loads in the user's avatar image.Also the avatar image is of proper size. The participant of the conversation is offset correctly as well. --- indra/llcommon/llfoldertype.h | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'indra/llcommon') diff --git a/indra/llcommon/llfoldertype.h b/indra/llcommon/llfoldertype.h index 609b550900..a0c847914f 100755 --- a/indra/llcommon/llfoldertype.h +++ b/indra/llcommon/llfoldertype.h @@ -89,9 +89,7 @@ public: FT_COUNT, - FT_NONE = -1, - - FT_PROFILEXXXGGG = 58 + FT_NONE = -1 }; static EType lookup(const std::string& type_name); -- cgit v1.2.3 From 7153d1db11c00245a379fa9601f092020152ea73 Mon Sep 17 00:00:00 2001 From: Don Kjer Date: Thu, 20 Sep 2012 04:29:17 +0000 Subject: Partial rewrite of llifstream and llofstream (Windows implementation pending). Moved more functionality from llviewerwearable to llwearable --- indra/llcommon/lldictionary.h | 2 + indra/llcommon/llfile.cpp | 705 +++++++++++++++++++++++++++++++++++++----- indra/llcommon/llfile.h | 423 ++++++++++++++++++------- 3 files changed, 945 insertions(+), 185 deletions(-) (limited to 'indra/llcommon') diff --git a/indra/llcommon/lldictionary.h b/indra/llcommon/lldictionary.h index bc3bc3e74a..c752859a36 100644 --- a/indra/llcommon/lldictionary.h +++ b/indra/llcommon/lldictionary.h @@ -30,6 +30,8 @@ #include #include +#include "llerror.h" + struct LL_COMMON_API LLDictionaryEntry { LLDictionaryEntry(const std::string &name); diff --git a/indra/llcommon/llfile.cpp b/indra/llcommon/llfile.cpp index c51d042a3d..38b0dfdaf1 100644 --- a/indra/llcommon/llfile.cpp +++ b/indra/llcommon/llfile.cpp @@ -56,6 +56,8 @@ std::string strerr(int errn) return buffer; } +typedef std::basic_ios > _Myios; + #else // On Posix we want to call strerror_r(), but alarmingly, there are two // different variants. The one that returns int always populates the passed @@ -324,9 +326,10 @@ const char *LLFile::tmpdir() /***************** Modified file stream created to overcome the incorrect behaviour of posix fopen in windows *******************/ -#if USE_LLFILESTREAMS +#if LL_WINDOWS -LLFILE * LLFile::_Fiopen(const std::string& filename, std::ios::openmode mode,int) // protection currently unused +LLFILE * LLFile::_Fiopen(const std::string& filename, + std::ios::openmode mode,int) // protection currently unused { // open a file static const char *mods[] = { // fopen mode strings corresponding to valid[i] @@ -385,117 +388,677 @@ LLFILE * LLFile::_Fiopen(const std::string& filename, std::ios::openmode mode,in return (0); } -/************** input file stream ********************************/ +#endif /* LL_WINDOWS */ -void llifstream::close() -{ // close the C stream - if (_Filebuffer && _Filebuffer->close() == 0) +/************** llstdio file buffer ********************************/ + + +//llstdio_filebuf* llstdio_filebuf::open(const char *_Filename, +// ios_base::openmode _Mode) +//{ +//#if LL_WINDOWS +// _Filet *_File; +// if (is_open() || (_File = LLFILE::_Fiopen(_Filename, _Mode)) == 0) +// return (0); // open failed +// +// _Init(_File, _Openfl); +// _Initcvt(&_USE(_Mysb::getloc(), _Cvt)); +// return (this); // open succeeded +//#else +// std::filebuf* _file = std::filebuf::open(_Filename, _Mode); +// if (NULL == _file) return NULL; +// return this; +//#endif +//} + +llstdio_filebuf::int_type llstdio_filebuf::overflow(llstdio_filebuf::int_type __c) +{ + int_type __ret = traits_type::eof(); + const bool __testeof = traits_type::eq_int_type(__c, __ret); + const bool __testout = _M_mode & ios_base::out; + if (__testout && !_M_reading) { - _Myios::setstate(ios_base::failbit); /*Flawfinder: ignore*/ + if (this->pbase() < this->pptr()) + { + // If appropriate, append the overflow char. + if (!__testeof) + { + *this->pptr() = traits_type::to_char_type(__c); + this->pbump(1); + } + + // Convert pending sequence to external representation, + // and output. + if (_convert_to_external(this->pbase(), + this->pptr() - this->pbase())) + { + _M_set_buffer(0); + __ret = traits_type::not_eof(__c); + } + } + else if (_M_buf_size > 1) + { + // Overflow in 'uncommitted' mode: set _M_writing, set + // the buffer to the initial 'write' mode, and put __c + // into the buffer. + _M_set_buffer(0); + _M_writing = true; + if (!__testeof) + { + *this->pptr() = traits_type::to_char_type(__c); + this->pbump(1); + } + __ret = traits_type::not_eof(__c); + } + else + { + // Unbuffered. + char_type __conv = traits_type::to_char_type(__c); + if (__testeof || _convert_to_external(&__conv, 1)) + { + _M_writing = true; + __ret = traits_type::not_eof(__c); + } + } } + return __ret; } -void llifstream::open(const std::string& _Filename, /* Flawfinder: ignore */ - ios_base::openmode _Mode, - int _Prot) -{ // open a C stream with specified mode +bool llstdio_filebuf::_convert_to_external(char_type* __ibuf, + std::streamsize __ilen) +{ + // Sizes of external and pending output. + streamsize __elen; + streamsize __plen; + if (__check_facet(_M_codecvt).always_noconv()) + { + //__elen = _M_file.xsputn(reinterpret_cast(__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); - LLFILE* filep = LLFile::_Fiopen(_Filename,_Mode | ios_base::in, _Prot); - if(filep == NULL) + if (__r == codecvt_base::ok || __r == codecvt_base::partial) + __blen = __bend - __buf; + else if (__r == codecvt_base::noconv) + { + // Same as the always_noconv case above. + __buf = reinterpret_cast(__ibuf); + __blen = __ilen; + } + else + __throw_ios_failure(__N("llstdio_filebuf::_convert_to_external " + "conversion error")); + + //__elen = _M_file.xsputn(__buf, __blen); + __elen = fwrite(__buf, 1, __blen, _M_file.file()); + __plen = __blen; + + // Try once more for partial conversions. + if (__r == codecvt_base::partial && __elen == __plen) + { + const char_type* __iresume = __iend; + streamsize __rlen = this->pptr() - __iend; + __r = _M_codecvt->out(_M_state_cur, __iresume, + __iresume + __rlen, __iend, __buf, + __buf + __blen, __bend); + if (__r != codecvt_base::error) + { + __rlen = __bend - __buf; + //__elen = _M_file.xsputn(__buf, __rlen); + __elen = fwrite(__buf, 1, __rlen, _M_file.file()); + __plen = __rlen; + } + else + { + __throw_ios_failure(__N("llstdio_filebuf::_convert_to_external " + "conversion error")); + } + } + } + return __elen == __plen; +} + +llstdio_filebuf::int_type llstdio_filebuf::underflow() +{ + int_type __ret = traits_type::eof(); + const bool __testin = _M_mode & ios_base::in; + if (__testin) { - _Myios::setstate(ios_base::failbit); /*Flawfinder: ignore*/ - return; + if (_M_writing) + { + if (overflow() == traits_type::eof()) + return __ret; + //_M_set_buffer(-1); + //_M_writing = false; + } + // Check for pback madness, and if so switch back to the + // normal buffers and jet outta here before expensive + // fileops happen... + _M_destroy_pback(); + + if (this->gptr() < this->egptr()) + return traits_type::to_int_type(*this->gptr()); + + // Get and convert input sequence. + const size_t __buflen = _M_buf_size > 1 ? _M_buf_size - 1 : 1; + + // Will be set to true if ::fread() returns 0 indicating EOF. + bool __got_eof = false; + // Number of internal characters produced. + streamsize __ilen = 0; + codecvt_base::result __r = codecvt_base::ok; + if (__check_facet(_M_codecvt).always_noconv()) + { + //__ilen = _M_file.xsgetn(reinterpret_cast(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")); } - llassert(_Filebuffer == NULL); - _Filebuffer = new _Myfb(filep); - _ShouldClose = true; - _Myios::init(_Filebuffer); + return __ret; } -bool llifstream::is_open() const -{ // test if C stream has been opened - if(_Filebuffer) - return (_Filebuffer->is_open()); - return false; +std::streamsize llstdio_filebuf::xsgetn(char_type* __s, std::streamsize __n) +{ + // Clear out pback buffer before going on to the real deal... + streamsize __ret = 0; + if (_M_pback_init) + { + if (__n > 0 && this->gptr() == this->eback()) + { + *__s++ = *this->gptr(); + this->gbump(1); + __ret = 1; + --__n; + } + _M_destroy_pback(); + } + + // Optimization in the always_noconv() case, to be generalized in the + // future: when __n > __buflen we read directly instead of using the + // buffer repeatedly. + const bool __testin = _M_mode & ios_base::in; + const streamsize __buflen = _M_buf_size > 1 ? _M_buf_size - 1 : 1; + + if (__n > __buflen && __check_facet(_M_codecvt).always_noconv() + && __testin && !_M_writing) + { + // First, copy the chars already present in the buffer. + const streamsize __avail = this->egptr() - this->gptr(); + if (__avail != 0) + { + if (__avail == 1) + *__s = *this->gptr(); + else + traits_type::copy(__s, this->gptr(), __avail); + __s += __avail; + this->gbump(__avail); + __ret += __avail; + __n -= __avail; + } + + // Need to loop in case of short reads (relatively common + // with pipes). + streamsize __len; + for (;;) + { + //__len = _M_file.xsgetn(reinterpret_cast(__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; } -llifstream::~llifstream() + +std::streamsize llstdio_filebuf::xsputn(char_type* __s, std::streamsize __n) { - if (_ShouldClose) + // Optimization in the always_noconv() case, to be generalized in the + // future: when __n is sufficiently large we write directly instead of + // using the buffer. + streamsize __ret = 0; + const bool __testout = _M_mode & ios_base::out; + if (__check_facet(_M_codecvt).always_noconv() + && __testout && !_M_reading) { - close(); + // Measurement would reveal the best choice. + const streamsize __chunk = 1ul << 10; + streamsize __bufavail = this->epptr() - this->pptr(); + + // Don't mistake 'uncommitted' mode buffered with unbuffered. + if (!_M_writing && _M_buf_size > 1) + __bufavail = _M_buf_size - 1; + + const streamsize __limit = std::min(__chunk, __bufavail); + if (__n >= __limit) + { + const streamsize __buffill = this->pptr() - this->pbase(); + const char* __buf = reinterpret_cast(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); } - delete _Filebuffer; + else + __ret = __streambuf_type::xsputn(__s, __n); + return __ret; } -llifstream::llifstream(const std::string& _Filename, - ios_base::openmode _Mode, - int _Prot) - : std::basic_istream< char , std::char_traits< char > >(NULL,true),_Filebuffer(NULL),_ShouldClose(false) +int llstdio_filebuf::sync() +{ + return (_M_file.sync() == 0 ? 0 : -1); +} -{ // construct with named file and specified mode - open(_Filename, _Mode | ios_base::in, _Prot); /* Flawfinder: ignore */ +/************** input file stream ********************************/ + + +llifstream::llifstream() : _M_filebuf(), +#if LL_WINDOWS + std::istream(&_M_filebuf) {} +#else + std::istream() +{ + this->init(&_M_filebuf); +} +#endif + +// explicit +llifstream::llifstream(const std::string& _Filename, + ios_base::openmode _Mode) : _M_filebuf(), +#if LL_WINDOWS + std::istream(&_M_filebuf) +{ + if (_M_filebuf.open(_Filename.c_str(), _Mode | ios_base::in) == 0) + { + _Myios::setstate(ios_base::failbit); + } +} +#else + std::istream() +{ + this->init(&_M_filebuf); + this->open(_Filename.c_str(), _Mode | ios_base::in); } +#endif +// explicit +llifstream::llifstream(const char* _Filename, + ios_base::openmode _Mode) : _M_filebuf(), +#if LL_WINDOWS + std::istream(&_M_filebuf) +{ + if (_M_filebuf.open(_Filename, _Mode | ios_base::in) == 0) + { + _Myios::setstate(ios_base::failbit); + } +} +#else + std::istream() +{ + this->init(&_M_filebuf); + this->open(_Filename, _Mode | ios_base::in); +} +#endif -/************** output file stream ********************************/ -bool llofstream::is_open() const +// explicit +llifstream::llifstream(_Filet *_File, + ios_base::openmode _Mode, size_t _Size) : + _M_filebuf(_File, _Mode, _Size), +#if LL_WINDOWS + std::istream(&_M_filebuf) {} +#else + std::istream() +{ + this->init(&_M_filebuf); +} +#endif + +#if LL_WINDOWS +// explicit +llifstream::llifstream(int __fd, + ios_base::openmode _Mode, size_t _Size) : + _M_filebuf(__fd, _Mode, _Size), + std::istream() +{ + this->init(&_M_filebuf); +} +#endif + +bool llifstream::is_open() const { // test if C stream has been opened - if(_Filebuffer) - return (_Filebuffer->is_open()); - return false; + return _M_filebuf.is_open(); } -void llofstream::open(const std::string& _Filename, /* Flawfinder: ignore */ - ios_base::openmode _Mode, - int _Prot) +void llifstream::open(const char* _Filename, ios_base::openmode _Mode) { // open a C stream with specified mode - - LLFILE* filep = LLFile::_Fiopen(_Filename,_Mode | ios_base::out, _Prot); - if(filep == NULL) + if (_M_filebuf.open(_Filename, _Mode | ios_base::in) == 0) +#if LL_WINDOWS { - _Myios::setstate(ios_base::failbit); /*Flawfinder: ignore*/ - return; + _Myios::setstate(ios_base::failbit); } - llassert(_Filebuffer==NULL); - _Filebuffer = new _Myfb(filep); - _ShouldClose = true; - _Myios::init(_Filebuffer); + else + { + _Myios::clear(); + } +#else + { + this->setstate(ios_base::failbit); + } + else + { + this->clear(); + } +#endif } -void llofstream::close() +void llifstream::close() { // close the C stream - if(is_open()) + if (_M_filebuf.close() == 0) { - if (_Filebuffer->close() == 0) - { - _Myios::setstate(ios_base::failbit); /*Flawfinder: ignore*/ - } - delete _Filebuffer; - _Filebuffer = NULL; - _ShouldClose = false; +#if LL_WINDOWS + _Myios::setstate(ios_base::failbit); +#else + this->setstate(ios_base::failbit); +#endif } } + +/************** output file stream ********************************/ + + +llofstream::llofstream() : _M_filebuf(), +#if LL_WINDOWS + std::ostream(&_M_filebuf) {} +#else + std::ostream() +{ + this->init(&_M_filebuf); +} +#endif + +// explicit llofstream::llofstream(const std::string& _Filename, - std::ios_base::openmode _Mode, - int _Prot) - : std::basic_ostream >(NULL,true),_Filebuffer(NULL),_ShouldClose(false) -{ // construct with named file and specified mode - open(_Filename, _Mode , _Prot); /* Flawfinder: ignore */ + ios_base::openmode _Mode) : _M_filebuf(), +#if LL_WINDOWS + std::ostream(&_M_filebuf) +{ + if (_M_filebuf.open(_Filename.c_str(), _Mode | ios_base::out) == 0) + { + _Myios::setstate(ios_base::failbit); + } +} +#else + std::ostream() +{ + this->init(&_M_filebuf); + this->open(_Filename.c_str(), _Mode | ios_base::out); +} +#endif + +// explicit +llofstream::llofstream(const char* _Filename, + ios_base::openmode _Mode) : _M_filebuf(), +#if LL_WINDOWS + std::ostream(&_M_filebuf) +{ + if (_M_filebuf.open(_Filename, _Mode | ios_base::out) == 0) + { + _Myios::setstate(ios_base::failbit); + } +} +#else + std::ostream() +{ + this->init(&_M_filebuf); + this->open(_Filename, _Mode | ios_base::out); +} +#endif + +// explicit +llofstream::llofstream(_Filet *_File, + ios_base::openmode _Mode, size_t _Size) : + _M_filebuf(_File, _Mode, _Size), +#if LL_WINDOWS + std::ostream(&_M_filebuf) {} +#else + std::ostream() +{ + this->init(&_M_filebuf); } +#endif -llofstream::~llofstream() +#if LL_WINDOWS +// explicit +llofstream::llofstream(int __fd, + ios_base::openmode _Mode, size_t _Size) : + _M_filebuf(__fd, _Mode, _Size), + std::ostream() { - // destroy the object - if (_ShouldClose) + this->init(&_M_filebuf); +} +#endif + +bool llofstream::is_open() const +{ // test if C stream has been opened + return _M_filebuf.is_open(); +} + +void llofstream::open(const char* _Filename, ios_base::openmode _Mode) +{ // open a C stream with specified mode + if (_M_filebuf.open(_Filename, _Mode | ios_base::out) == 0) +#if LL_WINDOWS + { + _Myios::setstate(ios_base::failbit); + } + else { - close(); + _Myios::clear(); } - delete _Filebuffer; +#else + { + this->setstate(ios_base::failbit); + } + else + { + this->clear(); + } +#endif } -#endif // #if USE_LLFILESTREAMS +void llofstream::close() +{ // close the C stream + if (_M_filebuf.close() == 0) + { +#if LL_WINDOWS + _Myios::setstate(ios_base::failbit); +#else + this->setstate(ios_base::failbit); +#endif + } +} /************** helper functions ********************************/ diff --git a/indra/llcommon/llfile.h b/indra/llcommon/llfile.h index dd7d36513a..7049ab1396 100644 --- a/indra/llcommon/llfile.h +++ b/indra/llcommon/llfile.h @@ -35,16 +35,10 @@ * Attempts to mostly mirror the POSIX style IO functions. */ -typedef FILE LLFILE; +typedef FILE LLFILE; #include - -#ifdef LL_WINDOWS -#define USE_LLFILESTREAMS 1 -#else -#define USE_LLFILESTREAMS 0 -#endif - +#include #include #if LL_WINDOWS @@ -52,6 +46,7 @@ typedef FILE LLFILE; typedef struct _stat llstat; #else typedef struct stat llstat; +#include #endif #ifndef S_ISREG @@ -83,142 +78,342 @@ public: static int stat(const std::string& filename,llstat* file_status); static bool isdir(const std::string& filename); static bool isfile(const std::string& filename); - static LLFILE * _Fiopen(const std::string& filename, std::ios::openmode mode,int); // protection currently unused + static LLFILE * _Fiopen(const std::string& filename, + std::ios::openmode mode); static const char * tmpdir(); }; +/** + * @brief Provides a layer of compatibility for C/POSIX. + * + * This is taken from both the GNU __gnu_cxx::stdio_filebuf extension and + * VC's basic_filebuf implementation. + * This file buffer provides extensions for working with standard C FILE*'s + * and POSIX file descriptors for platforms that support this. +*/ +namespace +{ +#if LL_WINDOWS +typedef std::filebuf _Myfb; +#else +typedef __gnu_cxx::stdio_filebuf< char > _Myfb; +typedef std::__c_file _Filet; +#endif /* LL_WINDOWS */ +} -#if USE_LLFILESTREAMS - -class LL_COMMON_API llifstream : public std::basic_istream < char , std::char_traits < char > > +class LL_COMMON_API llstdio_filebuf : public _Myfb { - // input stream associated with a C stream public: - typedef std::basic_ifstream > _Myt; - typedef std::basic_filebuf > _Myfb; - typedef std::basic_ios > _Myios; - - llifstream() - : std::basic_istream >(NULL,true),_Filebuffer(NULL),_ShouldClose(false) - { // construct unopened - } + /** + * deferred initialization / destruction + */ + llstdio_filebuf() : _Myfb() {} + virtual ~llstdio_filebuf() {} + + /** + * @param f An open @c FILE*. + * @param mode Same meaning as in a standard filebuf. + * @param size Optimal or preferred size of internal buffer, in chars. + * Defaults to system's @c BUFSIZ. + * + * This constructor associates a file stream buffer with an open + * C @c FILE*. The @c FILE* will not be automatically closed when the + * stdio_filebuf is closed/destroyed. + */ + llstdio_filebuf(_Filet* __f, std::ios_base::openmode __mode, + //size_t __size = static_cast(BUFSIZ)) : + size_t __size = static_cast(1)) : +#if LL_WINDOWS + _Myfb(__f) {} +#else + _Myfb(__f, __mode, __size) {} +#endif - explicit llifstream(const std::string& _Filename, - ios_base::openmode _Mode = ios_base::in, - int _Prot = (int)ios_base::_Openprot); - - explicit llifstream(_Filet *_File) - : std::basic_istream >(NULL,true), - _Filebuffer(new _Myfb(_File)), - _ShouldClose(false) - { // construct with specified C stream - } - virtual ~llifstream(); - - _Myfb *rdbuf() const - { // return pointer to file buffer - return _Filebuffer; - } - bool is_open() const; - void open(const std::string& _Filename, /* Flawfinder: ignore */ - ios_base::openmode _Mode = ios_base::in, - int _Prot = (int)ios_base::_Openprot); - void close(); + /** + * @brief Opens an external file. + * @param s The name of the file. + * @param mode The open mode flags. + * @return @c this on success, NULL on failure + * + * If a file is already open, this function immediately fails. + * Otherwise it tries to open the file named @a s using the flags + * given in @a mode. + */ + //llstdio_filebuf* open(const char *_Filename, + // std::ios_base::openmode _Mode); + + /** + * @param fd An open file descriptor. + * @param mode Same meaning as in a standard filebuf. + * @param size Optimal or preferred size of internal buffer, in chars. + * + * This constructor associates a file stream buffer with an open + * POSIX file descriptor. The file descriptor will be automatically + * closed when the stdio_filebuf is closed/destroyed. + */ +#if !LL_WINDOWS + llstdio_filebuf(int __fd, std::ios_base::openmode __mode, + //size_t __size = static_cast(BUFSIZ)) : + size_t __size = static_cast(1)) : + _Myfb(__fd, __mode, __size) {} +#endif -private: - _Myfb* _Filebuffer; // the file buffer - bool _ShouldClose; +// *TODO: Seek the underlying c stream for better cross-platform compatibility? +#if !LL_WINDOWS +protected: + /** underflow() and uflow() functions are called to get the next + * character from the real input source when the buffer is empty. + * Buffered input uses underflow() + */ + /*virtual*/ int_type underflow(); + + /* Convert internal byte sequence to external, char-based + * sequence via codecvt. + */ + bool _convert_to_external(char_type*, std::streamsize); + + /** The overflow() function is called to transfer characters to the + * real output destination when the buffer is full. A call to + * overflow(c) outputs the contents of the buffer plus the + * character c. + * Consume some sequence of the characters in the pending sequence. + */ + /*virtual*/ int_type overflow(int_type __c = traits_type::eof()); + + /** sync() flushes the underlying @c FILE* stream. + */ + /*virtual*/ int sync(); + + std::streamsize xsgetn(char_type*, std::streamsize); + std::streamsize xsputn(char_type*, std::streamsize); +#endif }; -class LL_COMMON_API llofstream : public std::basic_ostream< char , std::char_traits < char > > +/** + * @brief Controlling input for files. + * + * This class supports reading from named files, using the inherited + * functions from std::basic_istream. To control the associated + * sequence, an instance of std::basic_filebuf (or a platform-specific derivative) + * which allows construction using a pre-exisintg file stream buffer. + * We refer to this std::basic_filebuf (or derivative) as @c sb. +*/ +class LL_COMMON_API llifstream : public std::istream { + // input stream associated with a C stream public: - typedef std::basic_ostream< char , std::char_traits < char > > _Myt; - typedef std::basic_filebuf< char , std::char_traits < char > > _Myfb; - typedef std::basic_ios > _Myios; - - llofstream() - : std::basic_ostream >(NULL,true),_Filebuffer(NULL),_ShouldClose(false) - { // construct unopened - } - - explicit llofstream(const std::string& _Filename, - std::ios_base::openmode _Mode = ios_base::out, - int _Prot = (int)std::ios_base::_Openprot); - - - explicit llofstream(_Filet *_File) - : std::basic_ostream >(NULL,true), - _Filebuffer(new _Myfb(_File)),//_File) - _ShouldClose(false) - { // construct with specified C stream - } - - virtual ~llofstream(); - - _Myfb *rdbuf() const - { // return pointer to file buffer - return _Filebuffer; - } + // Constructors: + /** + * @brief Default constructor. + * + * Initializes @c sb using its default constructor, and passes + * @c &sb to the base class initializer. Does not open any files + * (you haven't given it a filename to open). + */ + llifstream(); + + /** + * @brief Create an input file stream. + * @param Filename String specifying the filename. + * @param Mode Open file in specified mode (see std::ios_base). + * + * @c ios_base::in is automatically included in @a mode. + */ + explicit llifstream(const std::string& _Filename, + ios_base::openmode _Mode = ios_base::in); + explicit llifstream(const char* _Filename, + ios_base::openmode _Mode = ios_base::in); + + /** + * @brief Create a stream using an open c file stream. + * @param File An open @c FILE*. + @param Mode Same meaning as in a standard filebuf. + @param Size Optimal or preferred size of internal buffer, in chars. + Defaults to system's @c BUFSIZ. + */ + explicit llifstream(_Filet *_File, + ios_base::openmode _Mode = ios_base::in, + //size_t _Size = static_cast(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; - void open(const std::string& _Filename,ios_base::openmode _Mode = ios_base::out,int _Prot = (int)ios_base::_Openprot); /* Flawfinder: ignore */ - + /** + * @brief Opens an external file. + * @param Filename The name of the file. + * @param Node The open mode flags. + * + * Calls @c llstdio_filebuf::open(s,mode|in). If that function + * fails, @c failbit is set in the stream's error state. + */ + void open(const std::string& _Filename, + ios_base::openmode _Mode = ios_base::in) + { open(_Filename.c_str(), _Mode); } + void open(const char* _Filename, + ios_base::openmode _Mode = ios_base::in); + + /** + * @brief Close the file. + * + * Calls @c llstdio_filebuf::close(). If that function + * fails, @c failbit is set in the stream's error state. + */ void close(); private: - _Myfb *_Filebuffer; // the file buffer - bool _ShouldClose; -}; - - - -#else -//Use standard file streams on non windows platforms -//#define llifstream std::ifstream -//#define llofstream std::ofstream - -class LL_COMMON_API llifstream : public std::ifstream -{ -public: - llifstream() : std::ifstream() - { - } - - explicit llifstream(const std::string& _Filename, std::_Ios_Openmode _Mode = in) - : std::ifstream(_Filename.c_str(), _Mode) - { - } - void open(const std::string& _Filename, std::_Ios_Openmode _Mode = in) /* Flawfinder: ignore */ - { - std::ifstream::open(_Filename.c_str(), _Mode); - } + llstdio_filebuf _M_filebuf; }; -class LL_COMMON_API llofstream : public std::ofstream +/** + * @brief Controlling output for files. + * + * This class supports writing to named files, using the inherited + * functions from std::basic_ostream. To control the associated + * sequence, an instance of std::basic_filebuf (or a platform-specific derivative) + * which allows construction using a pre-exisintg file stream buffer. + * We refer to this std::basic_filebuf (or derivative) as @c sb. +*/ +class LL_COMMON_API llofstream : public std::ostream { public: - llofstream() : std::ofstream() - { - } + // Constructors: + /** + * @brief Default constructor. + * + * Initializes @c sb using its default constructor, and passes + * @c &sb to the base class initializer. Does not open any files + * (you haven't given it a filename to open). + */ + llofstream(); + + /** + * @brief Create an output file stream. + * @param Filename String specifying the filename. + * @param Mode Open file in specified mode (see std::ios_base). + * + * @c ios_base::out|ios_base::trunc is automatically included in + * @a mode. + */ + explicit llofstream(const std::string& _Filename, + ios_base::openmode _Mode = ios_base::out|ios_base::trunc); + explicit llofstream(const char* _Filename, + ios_base::openmode _Mode = ios_base::out|ios_base::trunc); + + /** + * @brief Create a stream using an open c file stream. + * @param File An open @c FILE*. + @param Mode Same meaning as in a standard filebuf. + @param Size Optimal or preferred size of internal buffer, in chars. + Defaults to system's @c BUFSIZ. + */ + explicit llofstream(_Filet *_File, + ios_base::openmode _Mode = ios_base::out, + //size_t _Size = static_cast(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 - explicit llofstream(const std::string& _Filename, std::_Ios_Openmode _Mode = out) - : std::ofstream(_Filename.c_str(), _Mode) - { - } + /** + * @brief The destructor does nothing. + * + * The file is closed by the filebuf object, not the formatting + * stream. + */ + virtual ~llofstream() {} + + // Members: + /** + * @brief Accessing the underlying buffer. + * @return The current basic_filebuf buffer. + * + * This hides both signatures of std::basic_ios::rdbuf(). + */ + llstdio_filebuf* rdbuf() const + { return const_cast(&_M_filebuf); } + + /** + * @brief Wrapper to test for an open file. + * @return @c rdbuf()->is_open() + */ + bool is_open() const; - void open(const std::string& _Filename, std::_Ios_Openmode _Mode = out) /* Flawfinder: ignore */ - { - std::ofstream::open(_Filename.c_str(), _Mode); - } + /** + * @brief Opens an external file. + * @param Filename The name of the file. + * @param Node The open mode flags. + * + * Calls @c llstdio_filebuf::open(s,mode|out). If that function + * fails, @c failbit is set in the stream's error state. + */ + void open(const std::string& _Filename, + ios_base::openmode _Mode = ios_base::out|ios_base::trunc) + { open(_Filename.c_str(), _Mode); } + void open(const char* _Filename, + ios_base::openmode _Mode = ios_base::out|ios_base::trunc); + + /** + * @brief Close the file. + * + * Calls @c llstdio_filebuf::close(). If that function + * fails, @c failbit is set in the stream's error state. + */ + void close(); +private: + llstdio_filebuf _M_filebuf; }; -#endif /** * @breif filesize helpers. -- cgit v1.2.3 From 7d62343f4444e05d30092e6219bfea564a8e8e17 Mon Sep 17 00:00:00 2001 From: Don Kjer Date: Thu, 20 Sep 2012 04:56:09 +0000 Subject: Skipping experimental filebuffering code on windows for now --- indra/llcommon/llfile.cpp | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'indra/llcommon') diff --git a/indra/llcommon/llfile.cpp b/indra/llcommon/llfile.cpp index 38b0dfdaf1..deab7a87fc 100644 --- a/indra/llcommon/llfile.cpp +++ b/indra/llcommon/llfile.cpp @@ -411,6 +411,9 @@ LLFILE * LLFile::_Fiopen(const std::string& filename, //#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(); @@ -829,6 +832,7 @@ int llstdio_filebuf::sync() { return (_M_file.sync() == 0 ? 0 : -1); } +#endif /************** input file stream ********************************/ -- cgit v1.2.3 From 0fc7c2aac14eaf1f2dbe9e64c02e1b68ae3e70ec Mon Sep 17 00:00:00 2001 From: Don Kjer Date: Thu, 20 Sep 2012 06:32:43 +0000 Subject: Fix for windows compile issue --- indra/llcommon/llfile.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/llcommon') diff --git a/indra/llcommon/llfile.h b/indra/llcommon/llfile.h index 7049ab1396..9d70db96ea 100644 --- a/indra/llcommon/llfile.h +++ b/indra/llcommon/llfile.h @@ -38,7 +38,6 @@ typedef FILE LLFILE; #include -#include #include #if LL_WINDOWS @@ -47,6 +46,7 @@ typedef struct _stat llstat; #else typedef struct stat llstat; #include +#include #endif #ifndef S_ISREG -- cgit v1.2.3 From e9e459c89cdfc57f32ffc7c421e01f43348f3b6c Mon Sep 17 00:00:00 2001 From: Don Kjer Date: Thu, 20 Sep 2012 17:13:16 +0000 Subject: Restoring llrenderheadless changes so we can fix them --- indra/llcommon/llfile.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/llcommon') diff --git a/indra/llcommon/llfile.h b/indra/llcommon/llfile.h index 9d70db96ea..7049ab1396 100644 --- a/indra/llcommon/llfile.h +++ b/indra/llcommon/llfile.h @@ -38,6 +38,7 @@ typedef FILE LLFILE; #include +#include #include #if LL_WINDOWS @@ -46,7 +47,6 @@ typedef struct _stat llstat; #else typedef struct stat llstat; #include -#include #endif #ifndef S_ISREG -- cgit v1.2.3 From 3d5e24d135bd5d2636f075f9ef12ffba2129c61f Mon Sep 17 00:00:00 2001 From: William Todd Stinson Date: Fri, 21 Sep 2012 17:32:28 -0700 Subject: Adding the CXX to each CMake project definition. --- indra/llcommon/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/llcommon') diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt index dd7b8c6eb8..b29cd5bb53 100644 --- a/indra/llcommon/CMakeLists.txt +++ b/indra/llcommon/CMakeLists.txt @@ -1,7 +1,7 @@ # -*- cmake -*- -project(llcommon) +project(llcommon CXX) include(00-Common) include(LLCommon) -- cgit v1.2.3 From ecf72da021d16168688a833e776e8a76e80ee4d6 Mon Sep 17 00:00:00 2001 From: "developer@Developer-PC" Date: Fri, 21 Sep 2012 22:21:42 -0700 Subject: More windows build fixes --- indra/llcommon/llfile.cpp | 6 +++--- indra/llcommon/llfile.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'indra/llcommon') diff --git a/indra/llcommon/llfile.cpp b/indra/llcommon/llfile.cpp index deab7a87fc..bc615ed39e 100644 --- a/indra/llcommon/llfile.cpp +++ b/indra/llcommon/llfile.cpp @@ -329,7 +329,7 @@ const char *LLFile::tmpdir() #if LL_WINDOWS LLFILE * LLFile::_Fiopen(const std::string& filename, - std::ios::openmode mode,int) // protection currently unused + std::ios::openmode mode) { // open a file static const char *mods[] = { // fopen mode strings corresponding to valid[i] @@ -899,7 +899,7 @@ llifstream::llifstream(_Filet *_File, } #endif -#if LL_WINDOWS +#if !LL_WINDOWS // explicit llifstream::llifstream(int __fd, ios_base::openmode _Mode, size_t _Size) : @@ -1014,7 +1014,7 @@ llofstream::llofstream(_Filet *_File, } #endif -#if LL_WINDOWS +#if !LL_WINDOWS // explicit llofstream::llofstream(int __fd, ios_base::openmode _Mode, size_t _Size) : diff --git a/indra/llcommon/llfile.h b/indra/llcommon/llfile.h index 7049ab1396..9d70db96ea 100644 --- a/indra/llcommon/llfile.h +++ b/indra/llcommon/llfile.h @@ -38,7 +38,6 @@ typedef FILE LLFILE; #include -#include #include #if LL_WINDOWS @@ -47,6 +46,7 @@ typedef struct _stat llstat; #else typedef struct stat llstat; #include +#include #endif #ifndef S_ISREG -- cgit v1.2.3 From 0ca59987843cfcaedb12592b9466567ef421c4e8 Mon Sep 17 00:00:00 2001 From: William Todd Stinson Date: Wed, 3 Oct 2012 17:53:28 -0700 Subject: Backed out changeset: eb957fafe167 --- indra/llcommon/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/llcommon') diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt index b29cd5bb53..dd7b8c6eb8 100644 --- a/indra/llcommon/CMakeLists.txt +++ b/indra/llcommon/CMakeLists.txt @@ -1,7 +1,7 @@ # -*- cmake -*- -project(llcommon CXX) +project(llcommon) include(00-Common) include(LLCommon) -- cgit v1.2.3 From c06c35609c6683731eaea283468f6b32af18fea2 Mon Sep 17 00:00:00 2001 From: Don Kjer Date: Thu, 11 Oct 2012 00:09:04 +0000 Subject: Updating linux build to gcc4.6 --- indra/llcommon/llsdserialize.cpp | 5 ++++- indra/llcommon/tests/bitpack_test.cpp | 15 +++++++-------- indra/llcommon/tests/llinstancetracker_test.cpp | 3 +-- indra/llcommon/tests/reflection_test.cpp | 2 +- 4 files changed, 13 insertions(+), 12 deletions(-) (limited to 'indra/llcommon') diff --git a/indra/llcommon/llsdserialize.cpp b/indra/llcommon/llsdserialize.cpp index 7f4f670ed0..ad4fce6f35 100644 --- a/indra/llcommon/llsdserialize.cpp +++ b/indra/llcommon/llsdserialize.cpp @@ -1451,9 +1451,12 @@ S32 LLSDBinaryFormatter::format(const LLSD& data, std::ostream& ostr, U32 option } case LLSD::TypeUUID: + { ostr.put('u'); - ostr.write((const char*)(&(data.asUUID().mData)), UUID_BYTES); + LLUUID temp = data.asUUID(); + ostr.write((const char*)(&(temp.mData)), UUID_BYTES); break; + } case LLSD::TypeString: ostr.put('s'); diff --git a/indra/llcommon/tests/bitpack_test.cpp b/indra/llcommon/tests/bitpack_test.cpp index 05289881d0..afc0c18cd0 100644 --- a/indra/llcommon/tests/bitpack_test.cpp +++ b/indra/llcommon/tests/bitpack_test.cpp @@ -71,7 +71,6 @@ namespace tut U8 packbuffer[255]; U8 unpackbuffer[255]; int pack_bufsize = 0; - int unpack_bufsize = 0; LLBitPack bitpack(packbuffer, 255); @@ -81,19 +80,19 @@ namespace tut pack_bufsize = bitpack.flushBitPack(); LLBitPack bitunpack(packbuffer, pack_bufsize*8); - unpack_bufsize = bitunpack.bitUnpack(&unpackbuffer[0], 8); + bitunpack.bitUnpack(&unpackbuffer[0], 8); ensure("bitPack: individual unpack: 0", unpackbuffer[0] == (U8) str[0]); - unpack_bufsize = bitunpack.bitUnpack(&unpackbuffer[0], 8); + bitunpack.bitUnpack(&unpackbuffer[0], 8); ensure("bitPack: individual unpack: 1", unpackbuffer[0] == (U8) str[1]); - unpack_bufsize = bitunpack.bitUnpack(&unpackbuffer[0], 8); + bitunpack.bitUnpack(&unpackbuffer[0], 8); ensure("bitPack: individual unpack: 2", unpackbuffer[0] == (U8) str[2]); - unpack_bufsize = bitunpack.bitUnpack(&unpackbuffer[0], 8); + bitunpack.bitUnpack(&unpackbuffer[0], 8); ensure("bitPack: individual unpack: 3", unpackbuffer[0] == (U8) str[3]); - unpack_bufsize = bitunpack.bitUnpack(&unpackbuffer[0], 8); + bitunpack.bitUnpack(&unpackbuffer[0], 8); ensure("bitPack: individual unpack: 4", unpackbuffer[0] == (U8) str[4]); - unpack_bufsize = bitunpack.bitUnpack(&unpackbuffer[0], 8); + bitunpack.bitUnpack(&unpackbuffer[0], 8); ensure("bitPack: individual unpack: 5", unpackbuffer[0] == (U8) str[5]); - unpack_bufsize = bitunpack.bitUnpack(unpackbuffer, 8*4); // Life + bitunpack.bitUnpack(unpackbuffer, 8*4); // Life ensure_memory_matches("bitPack: 4 bytes unpack:", unpackbuffer, 4, str+6, 4); } diff --git a/indra/llcommon/tests/llinstancetracker_test.cpp b/indra/llcommon/tests/llinstancetracker_test.cpp index 454695ff9f..e769c3e22c 100644 --- a/indra/llcommon/tests/llinstancetracker_test.cpp +++ b/indra/llcommon/tests/llinstancetracker_test.cpp @@ -267,7 +267,6 @@ namespace tut { existing.insert(&*uki); } - Unkeyed* puk = NULL; try { // We don't expect the assignment to take place because we expect @@ -280,7 +279,7 @@ namespace tut // realize we're testing the C++ implementation more than // Unkeyed's implementation, but this seems an important point to // nail down. - puk = new Unkeyed("throw"); + new Unkeyed("throw"); } catch (const Badness&) { diff --git a/indra/llcommon/tests/reflection_test.cpp b/indra/llcommon/tests/reflection_test.cpp index 59491cd1fe..8980ebb1f1 100644 --- a/indra/llcommon/tests/reflection_test.cpp +++ b/indra/llcommon/tests/reflection_test.cpp @@ -207,7 +207,7 @@ namespace tut const LLReflective* reflective = property->get(aggregated_data); // Wrong reflective type, should throw exception. // useless op to get rid of compiler warning. - reflective = NULL; + reflective = reflective; } catch(...) { -- cgit v1.2.3 From 1004eff4a29371719f98eae378f6ecd7dc6be225 Mon Sep 17 00:00:00 2001 From: Logan Dethrow Date: Wed, 5 Dec 2012 17:29:52 -0500 Subject: Linux Viewer build fixes. * Removed no longer used unpack_bufsize from bitpack_test.cpp * Added llviewertexture_stub.cpp to the newview tests directory to fix llworldmap_test.cpp and llworldmipmap_test.cpp linker errors. --- indra/llcommon/tests/bitpack_test.cpp | 1 - 1 file changed, 1 deletion(-) (limited to 'indra/llcommon') diff --git a/indra/llcommon/tests/bitpack_test.cpp b/indra/llcommon/tests/bitpack_test.cpp index 49cae16400..afc0c18cd0 100644 --- a/indra/llcommon/tests/bitpack_test.cpp +++ b/indra/llcommon/tests/bitpack_test.cpp @@ -94,7 +94,6 @@ namespace tut ensure("bitPack: individual unpack: 5", unpackbuffer[0] == (U8) str[5]); bitunpack.bitUnpack(unpackbuffer, 8*4); // Life ensure_memory_matches("bitPack: 4 bytes unpack:", unpackbuffer, 4, str+6, 4); - ensure("keep compiler quiet", unpack_bufsize == unpack_bufsize); } // U32 packing -- cgit v1.2.3 From 3a49beed0e96a797a6d663bcae5e932437ca3661 Mon Sep 17 00:00:00 2001 From: Merov Linden Date: Wed, 5 Dec 2012 20:25:46 -0800 Subject: CHUI-580 : WIP : Change the display name cache system, deprecating the old protocol and using the cap (People API) whenever available. Still has occurence of Resident as last name to clean up. --- indra/llcommon/llavatarname.cpp | 69 +++++++++++++++++++++++++++++++++++++++-- indra/llcommon/llavatarname.h | 57 ++++++++++++++++++++++++---------- 2 files changed, 108 insertions(+), 18 deletions(-) (limited to 'indra/llcommon') diff --git a/indra/llcommon/llavatarname.cpp b/indra/llcommon/llavatarname.cpp index 3206843bf4..b49e6a7aac 100644 --- a/indra/llcommon/llavatarname.cpp +++ b/indra/llcommon/llavatarname.cpp @@ -30,6 +30,7 @@ #include "llavatarname.h" #include "lldate.h" +#include "llframetimer.h" #include "llsd.h" // Store these in pre-built std::strings to avoid memory allocations in @@ -42,6 +43,8 @@ static const std::string IS_DISPLAY_NAME_DEFAULT("is_display_name_default"); static const std::string DISPLAY_NAME_EXPIRES("display_name_expires"); static const std::string DISPLAY_NAME_NEXT_UPDATE("display_name_next_update"); +bool LLAvatarName::sUseDisplayNames = true; + LLAvatarName::LLAvatarName() : mUsername(), mDisplayName(), @@ -61,6 +64,17 @@ bool LLAvatarName::operator<(const LLAvatarName& rhs) const return mUsername < rhs.mUsername; } +//static +void LLAvatarName::setUseDisplayNames(bool use) +{ + sUseDisplayNames = use; +} +//static +bool LLAvatarName::useDisplayNames() +{ + return sUseDisplayNames; +} + LLSD LLAvatarName::asLLSD() const { LLSD sd; @@ -85,6 +99,33 @@ void LLAvatarName::fromLLSD(const LLSD& sd) mExpires = expires.secondsSinceEpoch(); LLDate next_update = sd[DISPLAY_NAME_NEXT_UPDATE]; mNextUpdate = next_update.secondsSinceEpoch(); + + // Some avatars don't have explicit display names set. Force a legible display name here. + if (mDisplayName.empty()) + { + mDisplayName = mUsername; + } +} + +void LLAvatarName::fromString(const std::string& full_name, F64 expires) +{ + mDisplayName = full_name; + std::string::size_type index = full_name.find(' '); + if (index != std::string::npos) + { + mLegacyFirstName = full_name.substr(0, index); + mLegacyLastName = full_name.substr(index+1); + mUsername = mLegacyFirstName + " " + mLegacyLastName; + } + else + { + mLegacyFirstName = full_name; + mLegacyLastName = ""; + mUsername = full_name; + } + mIsDisplayNameDefault = true; + mIsTemporaryName = true; + mExpires = LLFrameTimer::getTotalSeconds() + expires; } std::string LLAvatarName::getCompleteName() const @@ -104,9 +145,22 @@ std::string LLAvatarName::getCompleteName() const return name; } -std::string LLAvatarName::getLegacyName() const +std::string LLAvatarName::getDisplayName() const +{ + if (sUseDisplayNames) + { + return mDisplayName; + } + else + { + return getUserName(); + } +} + +std::string LLAvatarName::getUserName() const { - if (mLegacyFirstName.empty() && mLegacyLastName.empty()) // display names disabled? + // If we cannot create a user name from the legacy strings, use the display name + if (mLegacyFirstName.empty() && mLegacyLastName.empty()) { return mDisplayName; } @@ -118,3 +172,14 @@ std::string LLAvatarName::getLegacyName() const name += mLegacyLastName; return name; } + +void LLAvatarName::dump() const +{ + llinfos << "Merov debug : display = " << mDisplayName << ", user = " << mUsername << ", complete = " << getCompleteName() << ", legacy = " << getUserName() << " first = " << mLegacyFirstName << " last = " << mLegacyLastName << llendl; + LL_DEBUGS("AvNameCache") << "LLAvatarName: " + << "user '" << mUsername << "' " + << "display '" << mDisplayName << "' " + << "expires in " << mExpires - LLFrameTimer::getTotalSeconds() << " seconds" + << LL_ENDL; +} + diff --git a/indra/llcommon/llavatarname.h b/indra/llcommon/llavatarname.h index ba258d6d52..cf9eb27b03 100644 --- a/indra/llcommon/llavatarname.h +++ b/indra/llcommon/llavatarname.h @@ -43,19 +43,50 @@ public: void fromLLSD(const LLSD& sd); + // Used only in legacy mode when the display name capability is not provided server side + void fromString(const std::string& full_name, F64 expires = 0.0f); + + static void setUseDisplayNames(bool use); + static bool useDisplayNames(); + + // Name is valid if not temporary and not yet expired + bool isValidName(F64 max_unrefreshed = 0.0f) const { return !mIsTemporaryName && (mExpires >= max_unrefreshed); } + + // + bool isDisplayNameDefault() const { return mIsDisplayNameDefault; } + // For normal names, returns "James Linden (james.linden)" // When display names are disabled returns just "James Linden" std::string getCompleteName() const; - - // Returns "James Linden" or "bobsmith123 Resident" for backwards - // compatibility with systems like voice and muting - // *TODO: Eliminate this in favor of username only - std::string getLegacyName() const; - + + // "José Sanchez" or "James Linden", UTF-8 encoded Unicode + // Takes the display name preference into account. This is truly the name that should + // be used for all UI where an avatar name has to be used unless we truly want something else (rare) + std::string getDisplayName() const; + + // Returns "James Linden" or "bobsmith123 Resident" + // Used where we explicitely prefer or need a non UTF-8 legacy (ASCII) name + // Also used for backwards compatibility with systems like voice and muting + std::string getUserName() const; + + // Debug print of the object + void dump() const; + + // Names can change, so need to keep track of when name was + // last checked. + // Unix time-from-epoch seconds for efficiency + F64 mExpires; + + // You can only change your name every N hours, so record + // when the next update is allowed + // Unix time-from-epoch seconds + F64 mNextUpdate; + +private: // "bobsmith123" or "james.linden", US-ASCII only std::string mUsername; - // "Jose' Sanchez" or "James Linden", UTF-8 encoded Unicode + // "José Sanchez" or "James Linden", UTF-8 encoded Unicode // Contains data whether or not user has explicitly set // a display name; may duplicate their username. std::string mDisplayName; @@ -81,15 +112,9 @@ public: // shown in UI, but are not serialized. bool mIsTemporaryName; - // Names can change, so need to keep track of when name was - // last checked. - // Unix time-from-epoch seconds for efficiency - F64 mExpires; - - // You can only change your name every N hours, so record - // when the next update is allowed - // Unix time-from-epoch seconds - F64 mNextUpdate; + // Global flag indicating if display name should be used or not + // This will affect the output of the high level "get" methods + static bool sUseDisplayNames; }; #endif -- cgit v1.2.3 From bb322a1cccd3fab28951ad4e11b5edcfc4e48140 Mon Sep 17 00:00:00 2001 From: Merov Linden Date: Fri, 7 Dec 2012 00:10:50 -0800 Subject: CHUI-580 : Fixed : Clean up the use of display name. Allow the use of the legacy protocol in settings.xml --- indra/llcommon/llavatarname.cpp | 75 +++++++++++++++++++++++++++++++---------- indra/llcommon/llavatarname.h | 13 ++++--- 2 files changed, 66 insertions(+), 22 deletions(-) (limited to 'indra/llcommon') diff --git a/indra/llcommon/llavatarname.cpp b/indra/llcommon/llavatarname.cpp index b49e6a7aac..95ecce509b 100644 --- a/indra/llcommon/llavatarname.cpp +++ b/indra/llcommon/llavatarname.cpp @@ -45,6 +45,12 @@ static const std::string DISPLAY_NAME_NEXT_UPDATE("display_name_next_update"); bool LLAvatarName::sUseDisplayNames = true; +// Minimum time-to-live (in seconds) for a name entry. +// Avatar name should always guarantee to expire reasonably soon by default +// so if the failure to get a valid expiration time was due to something temporary +// we will eventually request and get the right data. +const F64 MIN_ENTRY_LIFETIME = 60.0; + LLAvatarName::LLAvatarName() : mUsername(), mDisplayName(), @@ -107,40 +113,67 @@ void LLAvatarName::fromLLSD(const LLSD& sd) } } -void LLAvatarName::fromString(const std::string& full_name, F64 expires) +// Transform a string (typically provided by the legacy service) into a decent +// avatar name instance. +void LLAvatarName::fromString(const std::string& full_name) { mDisplayName = full_name; std::string::size_type index = full_name.find(' '); if (index != std::string::npos) { + // The name is in 2 parts (first last) mLegacyFirstName = full_name.substr(0, index); mLegacyLastName = full_name.substr(index+1); - mUsername = mLegacyFirstName + " " + mLegacyLastName; + if (mLegacyLastName != "Resident") + { + mUsername = mLegacyFirstName + "." + mLegacyLastName; + mDisplayName = full_name; + LLStringUtil::toLower(mUsername); + } + else + { + // Very old names do have a dummy "Resident" last name + // that we choose to hide from users. + mUsername = mLegacyFirstName; + mDisplayName = mLegacyFirstName; + } } else { mLegacyFirstName = full_name; mLegacyLastName = ""; mUsername = full_name; + mDisplayName = full_name; } mIsDisplayNameDefault = true; mIsTemporaryName = true; + setExpires(MIN_ENTRY_LIFETIME); +} + +void LLAvatarName::setExpires(F64 expires) +{ mExpires = LLFrameTimer::getTotalSeconds() + expires; } std::string LLAvatarName::getCompleteName() const { std::string name; - if (mUsername.empty() || mIsDisplayNameDefault) - // If the display name feature is off - // OR this particular display name is defaulted (i.e. based on user name), - // then display only the easier to read instance of the person's name. + if (sUseDisplayNames) { - name = mDisplayName; + if (mUsername.empty() || mIsDisplayNameDefault) + { + // If this particular display name is defaulted (i.e. based on user name), + // then display only the easier to read instance of the person's name. + name = mDisplayName; + } + else + { + name = mDisplayName + " (" + mUsername + ")"; + } } else { - name = mDisplayName + " (" + mUsername + ")"; + name = getUserName(); } return name; } @@ -159,23 +192,29 @@ std::string LLAvatarName::getDisplayName() const std::string LLAvatarName::getUserName() const { - // If we cannot create a user name from the legacy strings, use the display name - if (mLegacyFirstName.empty() && mLegacyLastName.empty()) + std::string name; + if (mLegacyLastName.empty() || (mLegacyLastName == "Resident")) { - return mDisplayName; + if (mLegacyFirstName.empty()) + { + // If we cannot create a user name from the legacy strings, use the display name + name = mDisplayName; + } + else + { + // The last name might be empty if it defaulted to "Resident" + name = mLegacyFirstName; + } + } + else + { + name = mLegacyFirstName + " " + mLegacyLastName; } - - std::string name; - name.reserve( mLegacyFirstName.size() + 1 + mLegacyLastName.size() ); - name = mLegacyFirstName; - name += " "; - name += mLegacyLastName; return name; } void LLAvatarName::dump() const { - llinfos << "Merov debug : display = " << mDisplayName << ", user = " << mUsername << ", complete = " << getCompleteName() << ", legacy = " << getUserName() << " first = " << mLegacyFirstName << " last = " << mLegacyLastName << llendl; LL_DEBUGS("AvNameCache") << "LLAvatarName: " << "user '" << mUsername << "' " << "display '" << mDisplayName << "' " diff --git a/indra/llcommon/llavatarname.h b/indra/llcommon/llavatarname.h index cf9eb27b03..2f8c534974 100644 --- a/indra/llcommon/llavatarname.h +++ b/indra/llcommon/llavatarname.h @@ -39,20 +39,25 @@ public: bool operator<(const LLAvatarName& rhs) const; + // Conversion to and from LLSD (cache file or server response) LLSD asLLSD() const; - void fromLLSD(const LLSD& sd); // Used only in legacy mode when the display name capability is not provided server side - void fromString(const std::string& full_name, F64 expires = 0.0f); + // or to otherwise create a temporary valid item. + void fromString(const std::string& full_name); + // Set the name object to become invalid in "expires" seconds from now + void setExpires(F64 expires); + + // Set and get the display name flag set by the user in preferences. static void setUseDisplayNames(bool use); static bool useDisplayNames(); - // Name is valid if not temporary and not yet expired + // A name object is valid if not temporary and not yet expired (default is expiration not checked) bool isValidName(F64 max_unrefreshed = 0.0f) const { return !mIsTemporaryName && (mExpires >= max_unrefreshed); } - // + // Return true if the name is made up from legacy or temporary data bool isDisplayNameDefault() const { return mIsDisplayNameDefault; } // For normal names, returns "James Linden (james.linden)" -- cgit v1.2.3 From 08cc82ec483fab8299d52ba979f04df95e525acb Mon Sep 17 00:00:00 2001 From: Merov Linden Date: Thu, 13 Dec 2012 22:45:47 -0800 Subject: CHUI-599 : Fixed : Avatar name provides now a method to get the regular account name. --- indra/llcommon/llavatarname.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'indra/llcommon') diff --git a/indra/llcommon/llavatarname.h b/indra/llcommon/llavatarname.h index 2f8c534974..4827353018 100644 --- a/indra/llcommon/llavatarname.h +++ b/indra/llcommon/llavatarname.h @@ -74,6 +74,9 @@ public: // Also used for backwards compatibility with systems like voice and muting std::string getUserName() const; + // Returns "james.linden" or the legacy name for very old names + std::string getAccountName() const { return mUsername; } + // Debug print of the object void dump() const; -- cgit v1.2.3 From 438ceeb008b7c4eec0fc48894935289ca352fc65 Mon Sep 17 00:00:00 2001 From: Nyx Linden Date: Fri, 25 Jan 2013 17:58:11 -0500 Subject: BUILDFIX: merge cleanup A couple of merge issues that caused the resulting code to not build. --- indra/llcommon/llfasttimer.cpp | 6 ++++++ indra/llcommon/llfasttimer.h | 2 ++ 2 files changed, 8 insertions(+) (limited to 'indra/llcommon') diff --git a/indra/llcommon/llfasttimer.cpp b/indra/llcommon/llfasttimer.cpp index 6970c29092..9b15804e97 100644 --- a/indra/llcommon/llfasttimer.cpp +++ b/indra/llcommon/llfasttimer.cpp @@ -561,6 +561,12 @@ std::vector& LLFastTimer::NamedTimer::getChildren() return mChildren; } +// static +LLFastTimer::NamedTimer& LLFastTimer::NamedTimer::getRootNamedTimer() +{ + return *NamedTimerFactory::instance().getRootTimer(); +} + //static void LLFastTimer::nextFrame() { diff --git a/indra/llcommon/llfasttimer.h b/indra/llcommon/llfasttimer.h index e42e549df5..81c4b78775 100644 --- a/indra/llcommon/llfasttimer.h +++ b/indra/llcommon/llfasttimer.h @@ -91,6 +91,8 @@ public: U32 getHistoricalCount(S32 history_index = 0) const; U32 getHistoricalCalls(S32 history_index = 0) const; + static NamedTimer& getRootNamedTimer(); + void setFrameState(FrameState* state) { mFrameState = state; state->setNamedTimer(this); } FrameState& getFrameState() const; -- cgit v1.2.3 From c7cac7896ee4ccdd71dad432f1314b85987e78cf Mon Sep 17 00:00:00 2001 From: AlexanderP ProductEngine Date: Wed, 13 Feb 2013 20:44:38 +0200 Subject: CHUI-739 Fixed! FUI toolbars not displayed when switching between CHUI and release viewer : parsing declare values of Enums --- indra/llcommon/llinitparam.h | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) (limited to 'indra/llcommon') diff --git a/indra/llcommon/llinitparam.h b/indra/llcommon/llinitparam.h index 75c87c4bdb..695403e3f4 100644 --- a/indra/llcommon/llinitparam.h +++ b/indra/llcommon/llinitparam.h @@ -439,7 +439,7 @@ namespace LLInitParam {} void operator ()(const std::string& name) - { + { *this = name; } @@ -516,14 +516,30 @@ namespace LLInitParam { static bool read(T& param, Parser* parser) { - // read all enums as ints + std::string value_string; + //TypeValues::value_t v; + + // trying to get the declare value + parser_read_func_map_t::iterator string_func = parser->mParserReadFuncs->find(&typeid(std::string)); + if (string_func != parser->mParserReadFuncs->end()) + { + if (string_func->second(*parser, (void*)&value_string)) + { + if (TypeValues::getValueFromName(value_string, param)) + { + return true; + } + } + } + + // read enums as ints if it not declared as string parser_read_func_map_t::iterator found_it = parser->mParserReadFuncs->find(&typeid(S32)); if (found_it != parser->mParserReadFuncs->end()) { - S32 value; - if (found_it->second(*parser, (void*)&value)) + S32 value_S32; + if (found_it->second(*parser, (void*)&value_S32)) { - param = (T)value; + param = (T)value_S32; return true; } } -- cgit v1.2.3 From 638d94eef75799d47f8b913e0909b4079e55c03b Mon Sep 17 00:00:00 2001 From: AlexanderP ProductEngine Date: Thu, 14 Feb 2013 18:51:13 +0200 Subject: CHUI-739 : Clean up : FUI toolbars not displayed when switching between CHUI and release viewer --- indra/llcommon/llinitparam.h | 1 - 1 file changed, 1 deletion(-) (limited to 'indra/llcommon') diff --git a/indra/llcommon/llinitparam.h b/indra/llcommon/llinitparam.h index 695403e3f4..eb4d84d835 100644 --- a/indra/llcommon/llinitparam.h +++ b/indra/llcommon/llinitparam.h @@ -517,7 +517,6 @@ namespace LLInitParam static bool read(T& param, Parser* parser) { std::string value_string; - //TypeValues::value_t v; // trying to get the declare value parser_read_func_map_t::iterator string_func = parser->mParserReadFuncs->find(&typeid(std::string)); -- cgit v1.2.3 From 45849294cefd33c4875b5fe5b3fc8f04745452cf Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Mon, 18 Feb 2013 20:30:22 -0800 Subject: CHUI-739 FIX FUI toolbars not displayed when switching between CHUI and release viewer param blocks no longer write enums as ints --- indra/llcommon/llinitparam.h | 94 +++++++++++++++++--------------------------- 1 file changed, 35 insertions(+), 59 deletions(-) (limited to 'indra/llcommon') diff --git a/indra/llcommon/llinitparam.h b/indra/llcommon/llinitparam.h index 75c87c4bdb..66aac4f549 100644 --- a/indra/llcommon/llinitparam.h +++ b/indra/llcommon/llinitparam.h @@ -485,62 +485,6 @@ namespace LLInitParam typedef std::map parser_write_func_map_t; typedef std::map parser_inspect_func_map_t; - private: - template::value> - struct ReaderWriter - { - static bool read(T& param, Parser* parser) - { - parser_read_func_map_t::iterator found_it = parser->mParserReadFuncs->find(&typeid(T)); - if (found_it != parser->mParserReadFuncs->end()) - { - return found_it->second(*parser, (void*)¶m); - } - return false; - } - - static bool write(const T& param, Parser* parser, name_stack_t& name_stack) - { - parser_write_func_map_t::iterator found_it = parser->mParserWriteFuncs->find(&typeid(T)); - if (found_it != parser->mParserWriteFuncs->end()) - { - return found_it->second(*parser, (const void*)¶m, name_stack); - } - return false; - } - }; - - // read enums as ints - template - struct ReaderWriter - { - static bool read(T& param, Parser* parser) - { - // read all enums as ints - parser_read_func_map_t::iterator found_it = parser->mParserReadFuncs->find(&typeid(S32)); - if (found_it != parser->mParserReadFuncs->end()) - { - S32 value; - if (found_it->second(*parser, (void*)&value)) - { - param = (T)value; - return true; - } - } - return false; - } - - static bool write(const T& param, Parser* parser, name_stack_t& name_stack) - { - parser_write_func_map_t::iterator found_it = parser->mParserWriteFuncs->find(&typeid(S32)); - if (found_it != parser->mParserWriteFuncs->end()) - { - return found_it->second(*parser, (const void*)¶m, name_stack); - } - return false; - } - }; - public: Parser(parser_read_func_map_t& read_map, parser_write_func_map_t& write_map, parser_inspect_func_map_t& inspect_map) @@ -552,14 +496,46 @@ namespace LLInitParam virtual ~Parser(); - template bool readValue(T& param) + template bool readValue(T& param, typename boost::disable_if >::type* dummy = 0) { - return ReaderWriter::read(param, this); + parser_read_func_map_t::iterator found_it = mParserReadFuncs->find(&typeid(T)); + if (found_it != mParserReadFuncs->end()) + { + return found_it->second(*this, (void*)¶m); + } + + return false; } + template bool readValue(T& param, typename boost::enable_if >::type* dummy = 0) + { + parser_read_func_map_t::iterator found_it = mParserReadFuncs->find(&typeid(T)); + if (found_it != mParserReadFuncs->end()) + { + return found_it->second(*this, (void*)¶m); + } + else + { + found_it = mParserReadFuncs->find(&typeid(S32)); + if (found_it != mParserReadFuncs->end()) + { + S32 int_value; + bool parsed = found_it->second(*this, (void*)&int_value); + param = (T)int_value; + return parsed; + } + } + return false; + } + template bool writeValue(const T& param, name_stack_t& name_stack) { - return ReaderWriter::write(param, this, name_stack); + parser_write_func_map_t::iterator found_it = mParserWriteFuncs->find(&typeid(T)); + if (found_it != mParserWriteFuncs->end()) + { + return found_it->second(*this, (const void*)¶m, name_stack); + } + return false; } // dispatch inspection to registered inspection functions, for each parameter in a param block -- cgit v1.2.3 From 9ebe7db402af546211b65faf43d1635f3b92937e Mon Sep 17 00:00:00 2001 From: Oz Linden Date: Mon, 25 Feb 2013 17:29:15 -0500 Subject: increment minor version: 3.5.0 --- indra/llcommon/llversionviewer.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'indra/llcommon') diff --git a/indra/llcommon/llversionviewer.h b/indra/llcommon/llversionviewer.h index 6a5ff314e4..1554e9e665 100644 --- a/indra/llcommon/llversionviewer.h +++ b/indra/llcommon/llversionviewer.h @@ -28,8 +28,8 @@ #define LL_LLVERSIONVIEWER_H const S32 LL_VERSION_MAJOR = 3; -const S32 LL_VERSION_MINOR = 4; -const S32 LL_VERSION_PATCH = 6; +const S32 LL_VERSION_MINOR = 5; +const S32 LL_VERSION_PATCH = 0; const S32 LL_VERSION_BUILD = 0; const char * const LL_CHANNEL = "Second Life Developer"; -- cgit v1.2.3 From f7100331ebc7913d7117501ccac86f93f4ffb0e3 Mon Sep 17 00:00:00 2001 From: Oz Linden Date: Mon, 25 Feb 2013 17:41:36 -0500 Subject: increment version to 3.5.1 --- indra/llcommon/llversionviewer.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/llcommon') diff --git a/indra/llcommon/llversionviewer.h b/indra/llcommon/llversionviewer.h index 1554e9e665..0b0c74b3d3 100644 --- a/indra/llcommon/llversionviewer.h +++ b/indra/llcommon/llversionviewer.h @@ -29,7 +29,7 @@ const S32 LL_VERSION_MAJOR = 3; const S32 LL_VERSION_MINOR = 5; -const S32 LL_VERSION_PATCH = 0; +const S32 LL_VERSION_PATCH = 1; const S32 LL_VERSION_BUILD = 0; const char * const LL_CHANNEL = "Second Life Developer"; -- cgit v1.2.3 From 54cdc322b8f2bd35b289cacf3493622e7cc51194 Mon Sep 17 00:00:00 2001 From: Don Kjer Date: Tue, 5 Mar 2013 22:05:22 -0800 Subject: Fixing issues with not detecting when LLSD XML parsing fails. Changing most http error handlers to understand LLSD error responses. Fleshing out most http error handler message spam. --- indra/llcommon/llmetricperformancetester.cpp | 2 +- indra/llcommon/llsdserialize.h | 16 ++++++++-------- indra/llcommon/llsdserialize_xml.cpp | 18 +++++++++++++----- 3 files changed, 22 insertions(+), 14 deletions(-) (limited to 'indra/llcommon') diff --git a/indra/llcommon/llmetricperformancetester.cpp b/indra/llcommon/llmetricperformancetester.cpp index 41d3eb0bf3..731e58bd20 100644 --- a/indra/llcommon/llmetricperformancetester.cpp +++ b/indra/llcommon/llmetricperformancetester.cpp @@ -100,7 +100,7 @@ LLSD LLMetricPerformanceTesterBasic::analyzeMetricPerformanceLog(std::istream& i LLSD ret; LLSD cur; - while (!is.eof() && LLSDSerialize::fromXML(cur, is)) + while (!is.eof() && LLSDParser::PARSE_FAILURE != LLSDSerialize::fromXML(cur, is)) { for (LLSD::map_iterator iter = cur.beginMap(); iter != cur.endMap(); ++iter) { diff --git a/indra/llcommon/llsdserialize.h b/indra/llcommon/llsdserialize.h index 86e3fc864c..e7a5507385 100644 --- a/indra/llcommon/llsdserialize.h +++ b/indra/llcommon/llsdserialize.h @@ -300,7 +300,7 @@ public: /** * @brief Constructor */ - LLSDXMLParser(); + LLSDXMLParser(bool emit_errors=true); protected: /** @@ -747,25 +747,25 @@ public: return f->format(sd, str, LLSDFormatter::OPTIONS_PRETTY); } - static S32 fromXMLEmbedded(LLSD& sd, std::istream& str) + static S32 fromXMLEmbedded(LLSD& sd, std::istream& str, bool emit_errors=true) { // no need for max_bytes since xml formatting is not // subvertable by bad sizes. - LLPointer p = new LLSDXMLParser; + LLPointer p = new LLSDXMLParser(emit_errors); return p->parse(str, sd, LLSDSerialize::SIZE_UNLIMITED); } // Line oriented parser, 30% faster than fromXML(), but can // only be used when you know you have the complete XML // document available in the stream. - static S32 fromXMLDocument(LLSD& sd, std::istream& str) + static S32 fromXMLDocument(LLSD& sd, std::istream& str, bool emit_errors=true) { - LLPointer p = new LLSDXMLParser(); + LLPointer p = new LLSDXMLParser(emit_errors); return p->parseLines(str, sd); } - static S32 fromXML(LLSD& sd, std::istream& str) + static S32 fromXML(LLSD& sd, std::istream& str, bool emit_errors=true) { - return fromXMLEmbedded(sd, str); -// return fromXMLDocument(sd, str); + return fromXMLEmbedded(sd, str, emit_errors); +// return fromXMLDocument(sd, str, emit_errors); } /* diff --git a/indra/llcommon/llsdserialize_xml.cpp b/indra/llcommon/llsdserialize_xml.cpp index 34b3dbb99a..cef743a7be 100644 --- a/indra/llcommon/llsdserialize_xml.cpp +++ b/indra/llcommon/llsdserialize_xml.cpp @@ -250,7 +250,7 @@ std::string LLSDXMLFormatter::escapeString(const std::string& in) class LLSDXMLParser::Impl { public: - Impl(); + Impl(bool emit_errors); ~Impl(); S32 parse(std::istream& input, LLSD& data); @@ -294,6 +294,7 @@ private: static const XML_Char* findAttribute(const XML_Char* name, const XML_Char** pairs); + bool mEmitErrors; XML_Parser mParser; @@ -315,7 +316,8 @@ private: }; -LLSDXMLParser::Impl::Impl() +LLSDXMLParser::Impl::Impl(bool emit_errors) + : mEmitErrors(emit_errors) { mParser = XML_ParserCreate(NULL); reset(); @@ -402,7 +404,10 @@ S32 LLSDXMLParser::Impl::parse(std::istream& input, LLSD& data) { ((char*) buffer)[count ? count - 1 : 0] = '\0'; } - llinfos << "LLSDXMLParser::Impl::parse: XML_STATUS_ERROR parsing:" << (char*) buffer << llendl; + if (mEmitErrors) + { + llinfos << "LLSDXMLParser::Impl::parse: XML_STATUS_ERROR parsing:" << (char*) buffer << llendl; + } data = LLSD(); return LLSDParser::PARSE_FAILURE; } @@ -480,7 +485,10 @@ S32 LLSDXMLParser::Impl::parseLines(std::istream& input, LLSD& data) if (status == XML_STATUS_ERROR && !mGracefullStop) { - llinfos << "LLSDXMLParser::Impl::parseLines: XML_STATUS_ERROR" << llendl; + if (mEmitErrors) + { + llinfos << "LLSDXMLParser::Impl::parseLines: XML_STATUS_ERROR" << llendl; + } return LLSDParser::PARSE_FAILURE; } @@ -897,7 +905,7 @@ LLSDXMLParser::Impl::Element LLSDXMLParser::Impl::readElement(const XML_Char* na /** * LLSDXMLParser */ -LLSDXMLParser::LLSDXMLParser() : impl(* new Impl) +LLSDXMLParser::LLSDXMLParser(bool emit_errors /* = true */) : impl(* new Impl(emit_errors)) { } -- cgit v1.2.3 From fac6ee27f2d3277494f011271064b0e5e7e02554 Mon Sep 17 00:00:00 2001 From: Oz Linden Date: Fri, 12 Apr 2013 12:42:03 -0400 Subject: increment version to 3.5.2 --- indra/llcommon/llversionviewer.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/llcommon') diff --git a/indra/llcommon/llversionviewer.h b/indra/llcommon/llversionviewer.h index ae5e3ecade..0ea130e86b 100644 --- a/indra/llcommon/llversionviewer.h +++ b/indra/llcommon/llversionviewer.h @@ -29,7 +29,7 @@ const S32 LL_VERSION_MAJOR = 3; const S32 LL_VERSION_MINOR = 5; -const S32 LL_VERSION_PATCH = 1; +const S32 LL_VERSION_PATCH = 2; const S32 LL_VERSION_BUILD = 264760; const char * const LL_CHANNEL = "Second Life Developer"; -- cgit v1.2.3