diff options
Diffstat (limited to 'indra/llcommon')
| -rwxr-xr-x | indra/llcommon/llerror.cpp | 4 | ||||
| -rwxr-xr-x | indra/llcommon/llfile.cpp | 170 | ||||
| -rwxr-xr-x | indra/llcommon/llfile.h | 191 | ||||
| -rwxr-xr-x | indra/llcommon/llliveappconfig.cpp | 2 | ||||
| -rwxr-xr-x | indra/llcommon/llmd5.cpp | 12 | ||||
| -rwxr-xr-x | indra/llcommon/llmemory.cpp | 76 | ||||
| -rwxr-xr-x | indra/llcommon/llmemory.h | 54 | ||||
| -rwxr-xr-x | indra/llcommon/llstacktrace.cpp | 29 | ||||
| -rwxr-xr-x | indra/llcommon/llstacktrace.h | 1 | ||||
| -rwxr-xr-x | indra/llcommon/llstring.cpp | 2 | ||||
| -rw-r--r-- | indra/llcommon/lluriparser.cpp | 47 | ||||
| -rw-r--r-- | indra/llcommon/lluriparser.h | 5 | 
12 files changed, 527 insertions, 66 deletions
| diff --git a/indra/llcommon/llerror.cpp b/indra/llcommon/llerror.cpp index 3cb81b4e47..2100989316 100755 --- a/indra/llcommon/llerror.cpp +++ b/indra/llcommon/llerror.cpp @@ -135,7 +135,7 @@ namespace {  		}  	private: -		std::ofstream mFile; +		llofstream mFile;  	}; @@ -335,7 +335,7 @@ namespace  		LLSD configuration;  		{ -			std::ifstream file(filename().c_str()); +			llifstream file(filename().c_str());  			if (file.is_open())  			{  				LLSDSerialize::fromXML(configuration, file); diff --git a/indra/llcommon/llfile.cpp b/indra/llcommon/llfile.cpp index ab432a923d..295c97eac8 100755 --- a/indra/llcommon/llfile.cpp +++ b/indra/llcommon/llfile.cpp @@ -424,26 +424,6 @@ LLFILE *	LLFile::_Fiopen(const std::string& filename,  /************** 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)  { @@ -865,3 +845,153 @@ int llstdio_filebuf::sync()  }  #endif +#if LL_WINDOWS +/************** input file stream ********************************/ + +llifstream::llifstream() : +    _M_filebuf(), +	std::istream(&_M_filebuf) +{ +} + +// explicit +llifstream::llifstream(const std::string& _Filename,  +                       ios_base::openmode _Mode) : +    _M_filebuf(), +	std::istream(&_M_filebuf) +{ +	llutf16string wideName = utf8str_to_utf16str( _Filename ); +	if (_M_filebuf.open(wideName.c_str(), _Mode | ios_base::in) == 0) +	{ +		_Myios::setstate(ios_base::failbit); +	} +} + +// explicit +llifstream::llifstream(const char* _Filename,  +                       ios_base::openmode _Mode) : +    _M_filebuf(), +	std::istream(&_M_filebuf) +{ +	llutf16string wideName = utf8str_to_utf16str( _Filename ); +	if (_M_filebuf.open(wideName.c_str(), _Mode | ios_base::in) == 0) +	{ +		_Myios::setstate(ios_base::failbit); +	} +} + +bool llifstream::is_open() const +{	// test if C stream has been opened +	return _M_filebuf.is_open(); +} + +void llifstream::open(const char* _Filename, ios_base::openmode _Mode) +{	// open a C stream with specified mode +	llutf16string wideName = utf8str_to_utf16str( _Filename ); +	if (_M_filebuf.open( wideName.c_str(), _Mode | ios_base::in) == 0) +	{ +		_Myios::setstate(ios_base::failbit); +	} +	else +	{ +		_Myios::clear(); +	} +} + +void llifstream::close() +{	// close the C stream +	if (_M_filebuf.close() == 0) +	{ +		_Myios::setstate(ios_base::failbit); +	} +} + + +/************** output file stream ********************************/ + + +llofstream::llofstream() : +    _M_filebuf(), +	std::ostream(&_M_filebuf) +{ +} + +// explicit +llofstream::llofstream(const std::string& _Filename, +                       ios_base::openmode _Mode) : +    _M_filebuf(), +	std::ostream(&_M_filebuf) +{ +	llutf16string wideName = utf8str_to_utf16str( _Filename ); +	if (_M_filebuf.open( wideName.c_str(), _Mode | ios_base::out) == 0) +	{ +		_Myios::setstate(ios_base::failbit); +	} +} + +// explicit +llofstream::llofstream(const char* _Filename, +                       ios_base::openmode _Mode) : +    _M_filebuf(), +	std::ostream(&_M_filebuf) +{ +	llutf16string wideName = utf8str_to_utf16str( _Filename ); +	if (_M_filebuf.open( wideName.c_str(), _Mode | ios_base::out) == 0) +	{ +		_Myios::setstate(ios_base::failbit); +	} +} + +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 +	llutf16string wideName = utf8str_to_utf16str( _Filename ); +	if (_M_filebuf.open( wideName.c_str(), _Mode | ios_base::out) == 0) +	{ +		_Myios::setstate(ios_base::failbit); +	} +	else +	{ +		_Myios::clear(); +	} +} + +void llofstream::close() +{	// close the C stream +	if (_M_filebuf.close() == 0) +	{ +		_Myios::setstate(ios_base::failbit); +	} +} + +/************** helper functions ********************************/ + +std::streamsize llifstream_size(llifstream& ifstr) +{ +	if(!ifstr.is_open()) return 0; +	std::streampos pos_old = ifstr.tellg(); +	ifstr.seekg(0, ios_base::beg); +	std::streampos pos_beg = ifstr.tellg(); +	ifstr.seekg(0, ios_base::end); +	std::streampos pos_end = ifstr.tellg(); +	ifstr.seekg(pos_old, ios_base::beg); +	return pos_end - pos_beg; +} + +std::streamsize llofstream_size(llofstream& ofstr) +{ +	if(!ofstr.is_open()) return 0; +	std::streampos pos_old = ofstr.tellp(); +	ofstr.seekp(0, ios_base::beg); +	std::streampos pos_beg = ofstr.tellp(); +	ofstr.seekp(0, ios_base::end); +	std::streampos pos_end = ofstr.tellp(); +	ofstr.seekp(pos_old, ios_base::beg); +	return pos_end - pos_beg; +} + +#endif  // LL_WINDOWS diff --git a/indra/llcommon/llfile.h b/indra/llcommon/llfile.h index e310d47325..347c9867aa 100755 --- a/indra/llcommon/llfile.h +++ b/indra/llcommon/llfile.h @@ -192,4 +192,195 @@ protected:  #endif  }; +#if LL_WINDOWS +/** + *  @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: +	// 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  The destructor does nothing. +	 * +	 *  The file is closed by the filebuf object, not the formatting +	 *  stream. +     */ +	virtual ~llifstream() {} + +	// Members: +	/** +	 *  @brief  Accessing the underlying buffer. +	 *  @return  The current basic_filebuf buffer. +	 * +	 *  This hides both signatures of std::basic_ios::rdbuf(). +	*/ +	llstdio_filebuf* rdbuf() const +	{ return const_cast<llstdio_filebuf*>(&_M_filebuf); } + +	/** +	 *  @brief  Wrapper to test for an open file. +	 *  @return  @c rdbuf()->is_open() +     */ +	bool is_open() const; + +	/** +	 *  @brief  Opens an external file. +	 *  @param  Filename  The name of the file. +	 *  @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: +	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 +{ +  public: +	// 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  The destructor does nothing. +	 * +	 *  The file is closed by the filebuf object, not the formatting +	 *  stream. +	*/ +	virtual ~llofstream() {} + +	// Members: +	/** +	 *  @brief  Accessing the underlying buffer. +	 *  @return  The current basic_filebuf buffer. +	 * +	 *  This hides both signatures of std::basic_ios::rdbuf(). +	*/ +	llstdio_filebuf* rdbuf() const +	{ return const_cast<llstdio_filebuf*>(&_M_filebuf); } + +	/** +	 *  @brief  Wrapper to test for an open file. +	 *  @return  @c rdbuf()->is_open() +	*/ +	bool is_open() const; + +	/** +	 *  @brief  Opens an external file. +	 *  @param  Filename  The name of the file. +	 *  @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; +}; + + +/** + * @breif filesize helpers. + * + * The file size helpers are not considered particularly efficient, + * and should only be used for config files and the like -- not in a + * loop. + */ +std::streamsize LL_COMMON_API llifstream_size(llifstream& fstr); +std::streamsize LL_COMMON_API llofstream_size(llofstream& fstr); + +#else // ! LL_WINDOWS + +// on non-windows, llifstream and llofstream are just mapped directly to the std:: equivalents +typedef std::ifstream llifstream; +typedef std::ofstream llofstream; + +#endif // LL_WINDOWS or ! LL_WINDOWS +  #endif // not LL_LLFILE_H diff --git a/indra/llcommon/llliveappconfig.cpp b/indra/llcommon/llliveappconfig.cpp index f955194009..a9b1cdf4f6 100755 --- a/indra/llcommon/llliveappconfig.cpp +++ b/indra/llcommon/llliveappconfig.cpp @@ -49,7 +49,7 @@ bool LLLiveAppConfig::loadFile()  {  	LL_INFOS() << "LLLiveAppConfig::loadFile(): reading from "  		<< filename() << LL_ENDL; -    std::ifstream file(filename().c_str()); +    llifstream file(filename().c_str());  	LLSD config;      if (file.is_open())      { diff --git a/indra/llcommon/llmd5.cpp b/indra/llcommon/llmd5.cpp index ed80af36d8..f942a976b7 100755 --- a/indra/llcommon/llmd5.cpp +++ b/indra/llcommon/llmd5.cpp @@ -118,6 +118,12 @@ void LLMD5::update (const uint1 *input, const uint4 input_length) {    buffer_space = 64 - buffer_index;  // how much space is left in buffer +  // now, transform each 64-byte piece of the input, bypassing the buffer +  if (input == NULL || input_length == 0){ +	  std::cerr << "LLMD5::update:  Invalid input!" << std::endl; +	  return; +  } +    // Transform as many times as possible.    if (input_length >= buffer_space) { // ie. we have enough to fill the buffer      // fill the rest of the buffer and transform @@ -127,12 +133,6 @@ void LLMD5::update (const uint1 *input, const uint4 input_length) {  		buffer_space);      transform (buffer); -    // now, transform each 64-byte piece of the input, bypassing the buffer -  if (input == NULL || input_length == 0){ -	std::cerr << "LLMD5::update:  Invalid input!" << std::endl; -	return; -  } -      for (input_index = buffer_space; input_index + 63 < input_length;   	 input_index += 64)        transform (input+input_index); diff --git a/indra/llcommon/llmemory.cpp b/indra/llcommon/llmemory.cpp index e0b2aa87c2..ae11988df8 100755 --- a/indra/llcommon/llmemory.cpp +++ b/indra/llcommon/llmemory.cpp @@ -63,13 +63,18 @@ LLPrivateMemoryPoolManager::mem_allocation_info_t LLPrivateMemoryPoolManager::sM  void ll_assert_aligned_func(uintptr_t ptr,U32 alignment)  { -#ifdef SHOW_ASSERT -	// Redundant, place to set breakpoints. -	if (ptr%alignment!=0) -	{ -		LL_WARNS() << "alignment check failed" << LL_ENDL; -	} -	llassert(ptr%alignment==0); +#if defined(LL_WINDOWS) && defined(LL_DEBUG_BUFFER_OVERRUN) +	//do not check +	return; +#else +	#ifdef SHOW_ASSERT +		// Redundant, place to set breakpoints. +		if (ptr%alignment!=0) +		{ +			LL_WARNS() << "alignment check failed" << LL_ENDL; +		} +		llassert(ptr%alignment==0); +	#endif  #endif  } @@ -2148,3 +2153,60 @@ void LLPrivateMemoryPoolTester::fragmentationtest()  }  #endif  //-------------------------------------------------------------------- + +#if defined(LL_WINDOWS) && defined(LL_DEBUG_BUFFER_OVERRUN) + +#include <map> + +struct mem_info { +	std::map<void*, void*> memory_info; +	LLMutex mutex; + +	static mem_info& get() { +		static mem_info instance; +		return instance; +	} + +private: +	mem_info(){} +}; + +void* ll_aligned_malloc_fallback( size_t size, int align ) +{ +	SYSTEM_INFO sysinfo; +	GetSystemInfo(&sysinfo); +	 +	unsigned int for_alloc = sysinfo.dwPageSize; +	while(for_alloc < size) for_alloc += sysinfo.dwPageSize; +	 +	void *p = VirtualAlloc(NULL, for_alloc+sysinfo.dwPageSize, MEM_COMMIT|MEM_RESERVE, PAGE_READWRITE); +	if(NULL == p) { +		// call debugger +		__asm int 3; +	} +	DWORD old; +	BOOL Res = VirtualProtect((void*)((char*)p + for_alloc), sysinfo.dwPageSize, PAGE_NOACCESS, &old); +	if(FALSE == Res) { +		// call debugger +		__asm int 3; +	} + +	void* ret = (void*)((char*)p + for_alloc-size); +	 +	{ +		LLMutexLock lock(&mem_info::get().mutex); +		mem_info::get().memory_info.insert(std::pair<void*, void*>(ret, p)); +	} +	 + +	return ret; +} + +void ll_aligned_free_fallback( void* ptr ) +{ +	LLMutexLock lock(&mem_info::get().mutex); +	VirtualFree(mem_info::get().memory_info.find(ptr)->second, 0, MEM_RELEASE); +	mem_info::get().memory_info.erase(ptr); +} + +#endif diff --git a/indra/llcommon/llmemory.h b/indra/llcommon/llmemory.h index 7d1d541a4b..c4c9cc0566 100755 --- a/indra/llcommon/llmemory.h +++ b/indra/llcommon/llmemory.h @@ -94,32 +94,44 @@ template <typename T> T* LL_NEXT_ALIGNED_ADDRESS_64(T* address)  #define LL_ALIGN_16(var) LL_ALIGN_PREFIX(16) var LL_ALIGN_POSTFIX(16) - -inline void* ll_aligned_malloc_fallback( size_t size, int align ) -{ -#if defined(LL_WINDOWS) -	return _aligned_malloc(size, align); +//------------------------------------------------------------------------------------------------ +//------------------------------------------------------------------------------------------------ +	// for enable buffer overrun detection predefine LL_DEBUG_BUFFER_OVERRUN in current library +	// change preprocessro code to: #if 1 && defined(LL_WINDOWS) + +#if 0 && defined(LL_WINDOWS) +	void* ll_aligned_malloc_fallback( size_t size, int align ); +	void ll_aligned_free_fallback( void* ptr ); +//------------------------------------------------------------------------------------------------  #else -	void* mem = malloc( size + (align - 1) + sizeof(void*) ); -	char* aligned = ((char*)mem) + sizeof(void*); -	aligned += align - ((uintptr_t)aligned & (align - 1)); - -	((void**)aligned)[-1] = mem; -	return aligned; -#endif -} +	inline void* ll_aligned_malloc_fallback( size_t size, int align ) +	{ +	#if defined(LL_WINDOWS) +		return _aligned_malloc(size, align); +	#else +		void* mem = malloc( size + (align - 1) + sizeof(void*) ); +		char* aligned = ((char*)mem) + sizeof(void*); +		aligned += align - ((uintptr_t)aligned & (align - 1)); + +		((void**)aligned)[-1] = mem; +		return aligned; +	#endif +	} -inline void ll_aligned_free_fallback( void* ptr ) -{ -#if defined(LL_WINDOWS) -	_aligned_free(ptr); -#else -	if (ptr) +	inline void ll_aligned_free_fallback( void* ptr )  	{ -		free( ((void**)ptr)[-1] ); +	#if defined(LL_WINDOWS) +		_aligned_free(ptr); +	#else +		if (ptr) +		{ +			free( ((void**)ptr)[-1] ); +		} +	#endif  	}  #endif -} +//------------------------------------------------------------------------------------------------ +//------------------------------------------------------------------------------------------------  #if !LL_USE_TCMALLOC  inline void* ll_aligned_malloc_16(size_t size) // returned hunk MUST be freed with ll_aligned_free_16(). diff --git a/indra/llcommon/llstacktrace.cpp b/indra/llcommon/llstacktrace.cpp index e0e9056380..bbf0e1e141 100755 --- a/indra/llcommon/llstacktrace.cpp +++ b/indra/llcommon/llstacktrace.cpp @@ -125,6 +125,30 @@ bool ll_get_stack_trace(std::vector<std::string>& lines)  	return false;  } +void ll_get_stack_trace_internal(std::vector<std::string>& lines) +{ +	const S32 MAX_STACK_DEPTH = 100; +	const S32 STRING_NAME_LENGTH = 256; + +	HANDLE process = GetCurrentProcess(); +	SymInitialize( process, NULL, TRUE ); + +	void *stack[MAX_STACK_DEPTH]; + +	unsigned short frames = RtlCaptureStackBackTrace_fn( 0, MAX_STACK_DEPTH, stack, NULL ); +	SYMBOL_INFO *symbol = (SYMBOL_INFO*)calloc(sizeof(SYMBOL_INFO) + STRING_NAME_LENGTH * sizeof(char), 1); +	symbol->MaxNameLen = STRING_NAME_LENGTH-1; +	symbol->SizeOfStruct = sizeof(SYMBOL_INFO); + +	for(unsigned int i = 0; i < frames; i++)  +	{ +		SymFromAddr(process, (DWORD64)(stack[i]), 0, symbol); +		lines.push_back(symbol->Name); +	} + +	free( symbol ); +} +  #else  bool ll_get_stack_trace(std::vector<std::string>& lines) @@ -132,5 +156,10 @@ bool ll_get_stack_trace(std::vector<std::string>& lines)  	return false;  } +void ll_get_stack_trace_internal(std::vector<std::string>& lines) +{ + +} +  #endif diff --git a/indra/llcommon/llstacktrace.h b/indra/llcommon/llstacktrace.h index ca72c64c5d..335765386a 100755 --- a/indra/llcommon/llstacktrace.h +++ b/indra/llcommon/llstacktrace.h @@ -33,6 +33,7 @@  #include <string>  LL_COMMON_API bool ll_get_stack_trace(std::vector<std::string>& lines); +LL_COMMON_API void ll_get_stack_trace_internal(std::vector<std::string>& lines);  #endif diff --git a/indra/llcommon/llstring.cpp b/indra/llcommon/llstring.cpp index 227f81e88f..f3b8999883 100755 --- a/indra/llcommon/llstring.cpp +++ b/indra/llcommon/llstring.cpp @@ -107,7 +107,7 @@ bool iswindividual(llwchar elem)  bool _read_file_into_string(std::string& str, const std::string& filename)  { -	std::ifstream ifs(filename.c_str(), std::ifstream::binary); +	llifstream ifs(filename.c_str(), llifstream::binary);  	if (!ifs.is_open())  	{  		LL_INFOS() << "Unable to open file " << filename << LL_ENDL; diff --git a/indra/llcommon/lluriparser.cpp b/indra/llcommon/lluriparser.cpp index ef4481d32f..d98bc297e5 100644 --- a/indra/llcommon/lluriparser.cpp +++ b/indra/llcommon/lluriparser.cpp @@ -29,7 +29,7 @@  #include "linden_common.h"  #include "lluriparser.h" -LLUriParser::LLUriParser(const std::string& u) : mTmpScheme(false), mRes(0) +LLUriParser::LLUriParser(const std::string& u) : mTmpScheme(false), mNormalizedTmp(false), mRes(0)  {  	mState.uri = &mUri; @@ -118,17 +118,20 @@ void LLUriParser::fragment(const std::string& s)  void LLUriParser::textRangeToString(UriTextRangeA& textRange, std::string& str)  { -	S32 len = textRange.afterLast - textRange.first; -	if (len) +	if (textRange.first != NULL && textRange.afterLast != NULL && textRange.first < textRange.afterLast)  	{ -		str = textRange.first; -		str = str.substr(0, len); +		const ptrdiff_t len = textRange.afterLast - textRange.first; +		str.assign(textRange.first, static_cast<std::string::size_type>(len)); +	} +	else +	{ +		str = LLStringUtil::null;  	}  }  void LLUriParser::extractParts()  { -	if (mTmpScheme) +	if (mTmpScheme || mNormalizedTmp)  	{  		mScheme.clear();  	} @@ -157,6 +160,7 @@ void LLUriParser::extractParts()  S32 LLUriParser::normalize()  { +	mNormalizedTmp = mTmpScheme;  	if (!mRes)  	{  		mRes = uriNormalizeSyntaxExA(&mUri, URI_NORMALIZE_SCHEME | URI_NORMALIZE_HOST); @@ -175,29 +179,58 @@ S32 LLUriParser::normalize()  				if (!mRes)  				{  					mNormalizedUri = &label_buf[mTmpScheme ? 7 : 0]; +					mTmpScheme = false;  				}  			}  		}  	} +	if(mTmpScheme) +	{ +		mNormalizedUri = mNormalizedUri.substr(7); +		mTmpScheme = false; +	} +  	return mRes;  }  void LLUriParser::glue(std::string& uri) const  { +	std::string first_part; +	glueFirst(first_part); + +	std::string second_part; +	glueSecond(second_part); + +	uri = first_part + second_part; +} + +void LLUriParser::glueFirst(std::string& uri) const +{  	if (mScheme.size())  	{  		uri = mScheme;  		uri += "://";  	} +	else +	{ +		uri.clear(); +	}  	uri += mHost; +} +void LLUriParser::glueSecond(std::string& uri) const +{  	if (mPort.size())  	{ -		uri += ':'; +		uri = ':';  		uri += mPort;  	} +	else +	{ +		uri.clear(); +	}  	uri += mPath; diff --git a/indra/llcommon/lluriparser.h b/indra/llcommon/lluriparser.h index 719f916837..2df8085ae6 100644 --- a/indra/llcommon/lluriparser.h +++ b/indra/llcommon/lluriparser.h @@ -36,7 +36,7 @@ class LL_COMMON_API LLUriParser  {  public:  	LLUriParser(const std::string& u); -	virtual ~LLUriParser(); +	~LLUriParser();  	const char * scheme() const;  	void sheme (const std::string& s); @@ -60,6 +60,8 @@ public:  	void extractParts();  	void glue(std::string& uri) const; +	void glueFirst(std::string& uri) const; +	void glueSecond(std::string& uri) const;  	bool test() const;  	S32 normalize(); @@ -79,6 +81,7 @@ private:  	S32 mRes;  	bool mTmpScheme; +	bool mNormalizedTmp;  };  #endif // LL_LLURIPARSER_H | 
