diff options
| author | Don Kjer <don@lindenlab.com> | 2012-11-28 23:46:06 +0000 | 
|---|---|---|
| committer | Don Kjer <don@lindenlab.com> | 2012-11-28 23:46:06 +0000 | 
| commit | 96ef49df75c0248e4843f9a5b53f010b819d59f3 (patch) | |
| tree | 9f542fae939073bbb39464500d3fd477d1ed5fe5 /indra/llcommon | |
| parent | dc71cae16b9c49a1d6b4d4a888c3a574049fd087 (diff) | |
| parent | e0432f98ee515f9777604aa784d28b63d2abfe40 (diff) | |
Automated merge
Diffstat (limited to 'indra/llcommon')
| -rw-r--r-- | indra/llcommon/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | indra/llcommon/fix_macros.h | 25 | ||||
| -rw-r--r-- | indra/llcommon/llapp.cpp | 3 | ||||
| -rw-r--r-- | indra/llcommon/llapr.h | 2 | ||||
| -rw-r--r-- | indra/llcommon/llmemory.cpp | 31 | ||||
| -rw-r--r-- | indra/llcommon/llmemory.h | 37 | ||||
| -rw-r--r-- | indra/llcommon/llqueuedthread.cpp | 4 | ||||
| -rw-r--r-- | indra/llcommon/llstring.cpp | 3 | ||||
| -rw-r--r-- | indra/llcommon/llsys.cpp | 34 | ||||
| -rw-r--r-- | indra/llcommon/llthread.cpp | 42 | ||||
| -rw-r--r-- | indra/llcommon/llthread.h | 36 | ||||
| -rw-r--r-- | indra/llcommon/lluri.cpp | 36 | ||||
| -rw-r--r-- | indra/llcommon/llversionviewer.h | 2 | ||||
| -rw-r--r-- | indra/llcommon/tests/bitpack_test.cpp | 1 | ||||
| -rw-r--r-- | indra/llcommon/tests/lluri_test.cpp | 94 | 
15 files changed, 241 insertions, 110 deletions
| diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt index 36a8319189..66e2bc9095 100644 --- a/indra/llcommon/CMakeLists.txt +++ b/indra/llcommon/CMakeLists.txt @@ -116,6 +116,7 @@ set(llcommon_HEADER_FILES      bitpack.h      ctype_workaround.h      doublelinkedlist.h +    fix_macros.h      imageids.h      indra_constants.h      linden_common.h diff --git a/indra/llcommon/fix_macros.h b/indra/llcommon/fix_macros.h new file mode 100644 index 0000000000..ef959decff --- /dev/null +++ b/indra/llcommon/fix_macros.h @@ -0,0 +1,25 @@ +/** + * @file   fix_macros.h + * @author Nat Goodspeed + * @date   2012-11-16 + * @brief  The Mac system headers seem to #define macros with obnoxiously + *         generic names, preventing any library from using those names. We've + *         had to fix these in so many places that it's worth making a header + *         file to handle it. + *  + * $LicenseInfo:firstyear=2012&license=viewerlgpl$ + * Copyright (c) 2012, Linden Research, Inc. + * $/LicenseInfo$ + */ + +// DON'T use an #include guard: every time we encounter this header, #undef +// these macros all over again. + +// who injects MACROS with such generic names?! Grr. +#ifdef equivalent +#undef equivalent +#endif  + +#ifdef check +#undef check +#endif diff --git a/indra/llcommon/llapp.cpp b/indra/llcommon/llapp.cpp index ed192a9975..ca258900c7 100644 --- a/indra/llcommon/llapp.cpp +++ b/indra/llcommon/llapp.cpp @@ -289,6 +289,7 @@ void LLApp::setupErrorHandling()  	// occasionally checks to see if the app is in an error state, and sees if it needs to be run.  #if LL_WINDOWS +#if LL_SEND_CRASH_REPORTS  	// This sets a callback to handle w32 signals to the console window.  	// The viewer shouldn't be affected, sicne its a windowed app.  	SetConsoleCtrlHandler( (PHANDLER_ROUTINE) ConsoleCtrlHandler, TRUE); @@ -300,7 +301,7 @@ void LLApp::setupErrorHandling()  		mExceptionHandler = new google_breakpad::ExceptionHandler(  			L"C:\\Temp\\", 0, windows_post_minidump_callback, 0, google_breakpad::ExceptionHandler::HANDLER_ALL);  	} - +#endif  #else  	//  	// Start up signal handling. diff --git a/indra/llcommon/llapr.h b/indra/llcommon/llapr.h index af33ce666f..034546c3f3 100644 --- a/indra/llcommon/llapr.h +++ b/indra/llcommon/llapr.h @@ -168,7 +168,7 @@ public:  	void operator -=(Type x) { apr_atomic_sub32(&mData, apr_uint32_t(x)); }  	void operator +=(Type x) { apr_atomic_add32(&mData, apr_uint32_t(x)); }  	Type operator ++(int) { return apr_atomic_inc32(&mData); } // Type++ -	Type operator --(int) { return apr_atomic_dec32(&mData); } // Type-- +	Type operator --(int) { return apr_atomic_dec32(&mData); } // approximately --Type (0 if final is 0, non-zero otherwise)  private:  	apr_uint32_t mData; diff --git a/indra/llcommon/llmemory.cpp b/indra/llcommon/llmemory.cpp index afaf366668..70ad10ad55 100644 --- a/indra/llcommon/llmemory.cpp +++ b/indra/llcommon/llmemory.cpp @@ -252,21 +252,6 @@ U32 LLMemory::getAllocatedMemKB()  	return sAllocatedMemInKB ;  } -void* ll_allocate (size_t size) -{ -	if (size == 0) -	{ -		llwarns << "Null allocation" << llendl; -	} -	void *p = malloc(size); -	if (p == NULL) -	{ -		LLMemory::freeReserve(); -		llerrs << "Out of memory Error" << llendl; -	} -	return p; -} -  //----------------------------------------------------------------------------  #if defined(LL_WINDOWS) @@ -1365,7 +1350,7 @@ char* LLPrivateMemoryPool::allocate(U32 size)  	//if the asked size larger than MAX_BLOCK_SIZE, fetch from heap directly, the pool does not manage it  	if(size >= CHUNK_SIZE)  	{ -		return (char*)malloc(size) ; +		return (char*)ll_aligned_malloc_16(size) ;  	}  	char* p = NULL ; @@ -1422,7 +1407,7 @@ char* LLPrivateMemoryPool::allocate(U32 size)  			to_log = false ;  		} -		return (char*)malloc(size) ; +		return (char*)ll_aligned_malloc_16(size) ;  	}  	return p ; @@ -1441,7 +1426,7 @@ void LLPrivateMemoryPool::freeMem(void* addr)  	if(!chunk)  	{ -		free(addr) ; //release from heap +		ll_aligned_free_16(addr) ; //release from heap  	}  	else  	{ @@ -1565,7 +1550,7 @@ LLPrivateMemoryPool::LLMemoryChunk* LLPrivateMemoryPool::addChunk(S32 chunk_inde  	mReservedPoolSize += preferred_size + overhead ; -	char* buffer = (char*)malloc(preferred_size + overhead) ; +	char* buffer = (char*)ll_aligned_malloc_16(preferred_size + overhead) ;  	if(!buffer)  	{  		return NULL ; @@ -1633,7 +1618,7 @@ void LLPrivateMemoryPool::removeChunk(LLMemoryChunk* chunk)  	mReservedPoolSize -= chunk->getBufferSize() ;  	//release memory -	free(chunk->getBuffer()) ; +	ll_aligned_free_16(chunk->getBuffer()) ;  }  U16 LLPrivateMemoryPool::findHashKey(const char* addr) @@ -1977,7 +1962,7 @@ char* LLPrivateMemoryPoolManager::allocate(LLPrivateMemoryPool* poolp, U32 size,  	if(!poolp)  	{ -		p = (char*)malloc(size) ; +		p = (char*)ll_aligned_malloc_16(size) ;  	}  	else  	{ @@ -2006,7 +1991,7 @@ char* LLPrivateMemoryPoolManager::allocate(LLPrivateMemoryPool* poolp, U32 size)  	}  	else  	{ -		return (char*)malloc(size) ; +		return (char*)ll_aligned_malloc_16(size) ;  	}  }  #endif @@ -2031,7 +2016,7 @@ void  LLPrivateMemoryPoolManager::freeMem(LLPrivateMemoryPool* poolp, void* addr  	{  		if(!sPrivatePoolEnabled)  		{ -			free(addr) ; //private pool is disabled. +			ll_aligned_free_16(addr) ; //private pool is disabled.  		}  		else if(!sInstance) //the private memory manager is destroyed, try the dangling list  		{ diff --git a/indra/llcommon/llmemory.h b/indra/llcommon/llmemory.h index 9dd776ff57..10013e0f92 100644 --- a/indra/llcommon/llmemory.h +++ b/indra/llcommon/llmemory.h @@ -27,6 +27,13 @@  #define LLMEMORY_H  #include "llmemtype.h" + +#if LL_WINDOWS && LL_DEBUG +#define LL_CHECK_MEMORY llassert(_CrtCheckMemory()); +#else +#define LL_CHECK_MEMORY +#endif +  inline void* ll_aligned_malloc( size_t size, int align )  {  	void* mem = malloc( size + (align - 1) + sizeof(void*) ); @@ -58,31 +65,43 @@ inline void* ll_aligned_malloc_16(size_t size) // returned hunk MUST be freed wi  #endif  } -inline void* ll_aligned_realloc_16(void* ptr, size_t size) // returned hunk MUST be freed with ll_aligned_free_16(). +inline void ll_aligned_free_16(void *p)  {  #if defined(LL_WINDOWS) -	return _aligned_realloc(ptr, size, 16); +	_aligned_free(p);  #elif defined(LL_DARWIN) -	return realloc(ptr,size); // default osx malloc is 16 byte aligned. +	return free(p);  #else -	return realloc(ptr,size); // FIXME not guaranteed to be aligned. +	free(p); // posix_memalign() is compatible with heap deallocator  #endif  } -inline void ll_aligned_free_16(void *p) +inline void* ll_aligned_realloc_16(void* ptr, size_t size, size_t old_size) // returned hunk MUST be freed with ll_aligned_free_16().  {  #if defined(LL_WINDOWS) -	_aligned_free(p); +	return _aligned_realloc(ptr, size, 16);  #elif defined(LL_DARWIN) -	return free(p); +	return realloc(ptr,size); // default osx malloc is 16 byte aligned.  #else -	free(p); // posix_memalign() is compatible with heap deallocator +	//FIXME: memcpy is SLOW +	void* ret = ll_aligned_malloc_16(size); +	if (ptr) +	{ +		if (ret) +		{ +			// Only copy the size of the smallest memory block to avoid memory corruption. +			memcpy(ret, ptr, llmin(old_size, size)); +		} +		ll_aligned_free_16(ptr); +	} +	return ret;  #endif  } +  #else // USE_TCMALLOC  // ll_aligned_foo_16 are not needed with tcmalloc  #define ll_aligned_malloc_16 malloc -#define ll_aligned_realloc_16 realloc +#define ll_aligned_realloc_16(a,b,c) realloc(a,b)  #define ll_aligned_free_16 free  #endif // USE_TCMALLOC diff --git a/indra/llcommon/llqueuedthread.cpp b/indra/llcommon/llqueuedthread.cpp index 1738c16dea..abf47a0f57 100644 --- a/indra/llcommon/llqueuedthread.cpp +++ b/indra/llcommon/llqueuedthread.cpp @@ -134,8 +134,8 @@ S32 LLQueuedThread::updateQueue(F32 max_time_ms)  		pending = getPending();  		if(pending > 0)  		{ -		unpause(); -	} +			unpause(); +		}  	}  	else  	{ diff --git a/indra/llcommon/llstring.cpp b/indra/llcommon/llstring.cpp index fa0eb9f72c..0c32679744 100644 --- a/indra/llcommon/llstring.cpp +++ b/indra/llcommon/llstring.cpp @@ -47,7 +47,8 @@ std::string ll_safe_string(const char* in)  std::string ll_safe_string(const char* in, S32 maxlen)  { -	if(in) return std::string(in, maxlen); +	if(in && maxlen > 0 ) return std::string(in, maxlen); +  	return std::string();  } diff --git a/indra/llcommon/llsys.cpp b/indra/llcommon/llsys.cpp index 6073bcd0a6..c96f2191f3 100644 --- a/indra/llcommon/llsys.cpp +++ b/indra/llcommon/llsys.cpp @@ -944,13 +944,15 @@ LLSD LLMemoryInfo::loadStatsMap()  	state.dwLength = sizeof(state);  	GlobalMemoryStatusEx(&state); -	stats.add("Percent Memory use", state.dwMemoryLoad); -	stats.add("Total Physical KB",  state.ullTotalPhys/1024); -	stats.add("Avail Physical KB",  state.ullAvailPhys/1024); -	stats.add("Total page KB",      state.ullTotalPageFile/1024); -	stats.add("Avail page KB",      state.ullAvailPageFile/1024); -	stats.add("Total Virtual KB",   state.ullTotalVirtual/1024); -	stats.add("Avail Virtual KB",   state.ullAvailVirtual/1024); +	DWORDLONG div = 1024; + +	stats.add("Percent Memory use", state.dwMemoryLoad/div); +	stats.add("Total Physical KB",  state.ullTotalPhys/div); +	stats.add("Avail Physical KB",  state.ullAvailPhys/div); +	stats.add("Total page KB",      state.ullTotalPageFile/div); +	stats.add("Avail page KB",      state.ullAvailPageFile/div); +	stats.add("Total Virtual KB",   state.ullTotalVirtual/div); +	stats.add("Avail Virtual KB",   state.ullAvailVirtual/div);  	PERFORMANCE_INFORMATION perf;  	perf.cb = sizeof(perf); @@ -982,15 +984,15 @@ LLSD LLMemoryInfo::loadStatsMap()  	GetProcessMemoryInfo(GetCurrentProcess(), PPROCESS_MEMORY_COUNTERS(&pmem), sizeof(pmem));  	stats.add("Page Fault Count",              pmem.PageFaultCount); -	stats.add("PeakWorkingSetSize KB",         pmem.PeakWorkingSetSize/1024); -	stats.add("WorkingSetSize KB",             pmem.WorkingSetSize/1024); -	stats.add("QutaPeakPagedPoolUsage KB",     pmem.QuotaPeakPagedPoolUsage/1024); -	stats.add("QuotaPagedPoolUsage KB",        pmem.QuotaPagedPoolUsage/1024); -	stats.add("QuotaPeakNonPagedPoolUsage KB", pmem.QuotaPeakNonPagedPoolUsage/1024); -	stats.add("QuotaNonPagedPoolUsage KB",     pmem.QuotaNonPagedPoolUsage/1024); -	stats.add("PagefileUsage KB",              pmem.PagefileUsage/1024); -	stats.add("PeakPagefileUsage KB",          pmem.PeakPagefileUsage/1024); -	stats.add("PrivateUsage KB",               pmem.PrivateUsage/1024); +	stats.add("PeakWorkingSetSize KB",         pmem.PeakWorkingSetSize/div); +	stats.add("WorkingSetSize KB",             pmem.WorkingSetSize/div); +	stats.add("QutaPeakPagedPoolUsage KB",     pmem.QuotaPeakPagedPoolUsage/div); +	stats.add("QuotaPagedPoolUsage KB",        pmem.QuotaPagedPoolUsage/div); +	stats.add("QuotaPeakNonPagedPoolUsage KB", pmem.QuotaPeakNonPagedPoolUsage/div); +	stats.add("QuotaNonPagedPoolUsage KB",     pmem.QuotaNonPagedPoolUsage/div); +	stats.add("PagefileUsage KB",              pmem.PagefileUsage/div); +	stats.add("PeakPagefileUsage KB",          pmem.PeakPagefileUsage/div); +	stats.add("PrivateUsage KB",               pmem.PrivateUsage/div);  #elif LL_DARWIN diff --git a/indra/llcommon/llthread.cpp b/indra/llcommon/llthread.cpp index a6ad6b125c..1d56a52c32 100644 --- a/indra/llcommon/llthread.cpp +++ b/indra/llcommon/llthread.cpp @@ -71,6 +71,13 @@ LL_COMMON_API void assert_main_thread()  	}  } +void LLThread::registerThreadID() +{ +#if !LL_DARWIN +	sThreadID = ++sIDIter; +#endif +} +  //  // Handed to the APR thread creation function  // @@ -114,7 +121,7 @@ LLThread::LLThread(const std::string& name, apr_pool_t *poolp) :  		apr_pool_create(&mAPRPoolp, NULL); // Create a subpool for this thread  	}  	mRunCondition = new LLCondition(mAPRPoolp); - +	mDataLock = new LLMutex(mAPRPoolp);  	mLocalAPRFilePoolp = NULL ;  } @@ -173,7 +180,10 @@ void LLThread::shutdown()  	}  	delete mRunCondition; -	mRunCondition = 0; +	mRunCondition = NULL; + +	delete mDataLock; +	mDataLock = NULL;  	if (mIsLocalPool && mAPRPoolp)  	{ @@ -242,28 +252,30 @@ bool LLThread::runCondition(void)  // Stop thread execution if requested until unpaused.  void LLThread::checkPause()  { -	mRunCondition->lock(); +	mDataLock->lock();  	// This is in a while loop because the pthread API allows for spurious wakeups.  	while(shouldSleep())  	{ +		mDataLock->unlock();  		mRunCondition->wait(); // unlocks mRunCondition +		mDataLock->lock();  		// mRunCondition is locked when the thread wakes up  	} - 	mRunCondition->unlock(); + 	mDataLock->unlock();  }  //============================================================================  void LLThread::setQuitting()  { -	mRunCondition->lock(); +	mDataLock->lock();  	if (mStatus == RUNNING)  	{  		mStatus = QUITTING;  	} -	mRunCondition->unlock(); +	mDataLock->unlock();  	wake();  } @@ -285,12 +297,12 @@ void LLThread::yield()  void LLThread::wake()  { -	mRunCondition->lock(); +	mDataLock->lock();  	if(!shouldSleep())  	{  		mRunCondition->signal();  	} -	mRunCondition->unlock(); +	mDataLock->unlock();  }  void LLThread::wakeLocked() @@ -481,6 +493,19 @@ LLThreadSafeRefCount::LLThreadSafeRefCount() :  {  } +LLThreadSafeRefCount::LLThreadSafeRefCount(const LLThreadSafeRefCount& src) +{ +	if (sMutex) +	{ +		sMutex->lock(); +	} +	mRef = 0; +	if (sMutex) +	{ +		sMutex->unlock(); +	} +} +  LLThreadSafeRefCount::~LLThreadSafeRefCount()  {   	if (mRef != 0) @@ -489,6 +514,7 @@ LLThreadSafeRefCount::~LLThreadSafeRefCount()  	}  } +  //============================================================================  LLResponder::~LLResponder() diff --git a/indra/llcommon/llthread.h b/indra/llcommon/llthread.h index b52e70ab2e..5c8bbca2ca 100644 --- a/indra/llcommon/llthread.h +++ b/indra/llcommon/llthread.h @@ -88,6 +88,11 @@ public:  	U32 getID() const { return mID; } +	// Called by threads *not* created via LLThread to register some +	// internal state used by LLMutex.  You must call this once early +	// in the running thread to prevent collisions with the main thread. +	static void registerThreadID(); +	  private:  	BOOL				mPaused; @@ -97,6 +102,7 @@ private:  protected:  	std::string			mName;  	LLCondition*		mRunCondition; +	LLMutex*			mDataLock;  	apr_thread_t		*mAPRThreadp;  	apr_pool_t			*mAPRPoolp; @@ -122,15 +128,15 @@ protected:  	inline void unlockData();  	// This is the predicate that decides whether the thread should sleep.   -	// It should only be called with mRunCondition locked, since the virtual runCondition() function may need to access +	// It should only be called with mDataLock locked, since the virtual runCondition() function may need to access  	// data structures that are thread-unsafe.  	bool shouldSleep(void) { return (mStatus == RUNNING) && (isPaused() || (!runCondition())); }  	// To avoid spurious signals (and the associated context switches) when the condition may or may not have changed, you can do the following: -	// mRunCondition->lock(); +	// mDataLock->lock();  	// if(!shouldSleep())  	//     mRunCondition->signal(); -	// mRunCondition->unlock(); +	// mDataLock->unlock();  };  //============================================================================ @@ -205,12 +211,12 @@ private:  void LLThread::lockData()  { -	mRunCondition->lock(); +	mDataLock->lock();  }  void LLThread::unlockData()  { -	mRunCondition->unlock(); +	mDataLock->unlock();  } @@ -227,15 +233,27 @@ public:  private:  	static LLMutex* sMutex; -private: -	LLThreadSafeRefCount(const LLThreadSafeRefCount&); // not implemented -	LLThreadSafeRefCount&operator=(const LLThreadSafeRefCount&); // not implemented -  protected:  	virtual ~LLThreadSafeRefCount(); // use unref()  public:  	LLThreadSafeRefCount(); +	LLThreadSafeRefCount(const LLThreadSafeRefCount&); +	LLThreadSafeRefCount& operator=(const LLThreadSafeRefCount& ref)  +	{ +		if (sMutex) +		{ +			sMutex->lock(); +		} +		mRef = 0; +		if (sMutex) +		{ +			sMutex->unlock(); +		} +		return *this; +	} + +  	void ref()  	{ diff --git a/indra/llcommon/lluri.cpp b/indra/llcommon/lluri.cpp index b39ea0c6f2..21456a599b 100644 --- a/indra/llcommon/lluri.cpp +++ b/indra/llcommon/lluri.cpp @@ -37,6 +37,8 @@  // system includes  #include <boost/tokenizer.hpp> +#include <boost/algorithm/string/find_iterator.hpp> +#include <boost/algorithm/string/finder.hpp>  void encode_character(std::ostream& ostr, std::string::value_type val)  { @@ -317,7 +319,7 @@ LLURI LLURI::buildHTTP(const std::string& prefix,  					   const LLSD& path)  {  	LLURI result; -	 +  	// TODO: deal with '/' '?' '#' in host_port  	if (prefix.find("://") != prefix.npos)  	{ @@ -342,15 +344,41 @@ LLURI LLURI::buildHTTP(const std::string& prefix,  			result.mEscapedPath += "/" + escapePathComponent(it->asString());  		}  	} -	else if(path.isString()) +	else if (path.isString())  	{ -		result.mEscapedPath += "/" + escapePathComponent(path.asString()); +		std::string pathstr(path); +		// Trailing slash is significant in HTTP land. If caller specified, +		// make a point of preserving. +		std::string last_slash; +		std::string::size_type len(pathstr.length()); +		if (len && pathstr[len-1] == '/') +		{ +			last_slash = "/"; +		} + +		// Escape every individual path component, recombining with slashes. +		for (boost::split_iterator<std::string::const_iterator> +				 ti(pathstr, boost::first_finder("/")), tend; +			 ti != tend; ++ti) +		{ +			// Eliminate a leading slash or duplicate slashes anywhere. (Extra +			// slashes show up here as empty components.) This test also +			// eliminates a trailing slash, hence last_slash above. +			if (! ti->empty()) +			{ +				result.mEscapedPath +					+= "/" + escapePathComponent(std::string(ti->begin(), ti->end())); +			} +		} + +		// Reinstate trailing slash, if any. +		result.mEscapedPath += last_slash;  	}   	else if(path.isUndefined())  	{  	  // do nothing  	} -    else +	else  	{  	  llwarns << "Valid path arguments to buildHTTP are array, string, or undef, you passed type"   			  << path.type() << llendl; diff --git a/indra/llcommon/llversionviewer.h b/indra/llcommon/llversionviewer.h index 295fed3c4b..a254fa4467 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 = 4; -const S32 LL_VERSION_PATCH = 1; +const S32 LL_VERSION_PATCH = 4;  const S32 LL_VERSION_BUILD = 264760;  const char * const LL_CHANNEL = "Second Life Developer"; diff --git a/indra/llcommon/tests/bitpack_test.cpp b/indra/llcommon/tests/bitpack_test.cpp index afc0c18cd0..49cae16400 100644 --- a/indra/llcommon/tests/bitpack_test.cpp +++ b/indra/llcommon/tests/bitpack_test.cpp @@ -94,6 +94,7 @@ 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 diff --git a/indra/llcommon/tests/lluri_test.cpp b/indra/llcommon/tests/lluri_test.cpp index f6d4221256..4c64f15ca7 100644 --- a/indra/llcommon/tests/lluri_test.cpp +++ b/indra/llcommon/tests/lluri_test.cpp @@ -58,12 +58,12 @@ namespace tut  			ensure_equals("escape/unescape escaped", uri_esc_2, uri_esc_1);  		}  	}; -	 +  	typedef test_group<URITestData>	URITestGroup;  	typedef URITestGroup::object	URITestObject;  	URITestGroup uriTestGroup("LLURI"); -	 +  	template<> template<>  	void URITestObject::test<1>()  	{ @@ -89,14 +89,14 @@ namespace tut  	template<> template<>  	void URITestObject::test<2>()  	{ -		// empty string +		set_test_name("empty string");  		checkParts(LLURI(""), "", "", "", "");  	} -	 +  	template<> template<>  	void URITestObject::test<3>()  	{ -		// no scheme +		set_test_name("no scheme");  		checkParts(LLURI("foo"), "", "foo", "", "");  		checkParts(LLURI("foo%3A"), "", "foo:", "", "");  	} @@ -104,7 +104,7 @@ namespace tut  	template<> template<>  	void URITestObject::test<4>()  	{ -		// scheme w/o paths +		set_test_name("scheme w/o paths");  		checkParts(LLURI("mailto:zero@ll.com"),  			"mailto", "zero@ll.com", "", "");  		checkParts(LLURI("silly://abc/def?foo"), @@ -114,16 +114,16 @@ namespace tut  	template<> template<>  	void URITestObject::test<5>()  	{ -		// authority section +		set_test_name("authority section");  		checkParts(LLURI("http:///"),  			"http", "///", "", "/"); -			 +  		checkParts(LLURI("http://abc"),  			"http", "//abc", "abc", ""); -			 +  		checkParts(LLURI("http://a%2Fb/cd"),  			"http", "//a/b/cd", "a/b", "/cd"); -			 +  		checkParts(LLURI("http://host?"),  			"http", "//host?", "host", "");  	} @@ -131,13 +131,13 @@ namespace tut  	template<> template<>  	void URITestObject::test<6>()  	{		 -		// path section +		set_test_name("path section");  		checkParts(LLURI("http://host/a/b/"),  				"http", "//host/a/b/", "host", "/a/b/"); -				 +  		checkParts(LLURI("http://host/a%3Fb/"),  				"http", "//host/a?b/", "host", "/a?b/"); -				 +  		checkParts(LLURI("http://host/a:b/"),  				"http", "//host/a:b/", "host", "/a:b/");  	} @@ -145,16 +145,16 @@ namespace tut  	template<> template<>  	void URITestObject::test<7>()  	{		 -		// query string +		set_test_name("query string");  		checkParts(LLURI("http://host/?"),  				"http", "//host/?", "host", "/", ""); -				 +  		checkParts(LLURI("http://host/?x"),  				"http", "//host/?x", "host", "/", "x"); -				 +  		checkParts(LLURI("http://host/??"),  				"http", "//host/??", "host", "/", "?"); -				 +  		checkParts(LLURI("http://host/?%3F"),  				"http", "//host/??", "host", "/", "?");  	} @@ -167,19 +167,44 @@ namespace tut  		path.append("123");  		checkParts(LLURI::buildHTTP("host", path),  			"http", "//host/x/123", "host", "/x/123"); -		 +  		LLSD query;  		query["123"] = "12";  		query["abcd"] = "abc";  		checkParts(LLURI::buildHTTP("host", path, query),  			"http", "//host/x/123?123=12&abcd=abc",  			"host", "/x/123", "123=12&abcd=abc"); + +		ensure_equals(LLURI::buildHTTP("host", "").asString(), +					  "http://host"); +		ensure_equals(LLURI::buildHTTP("host", "/").asString(), +					  "http://host/"); +		ensure_equals(LLURI::buildHTTP("host", "//").asString(), +					  "http://host/"); +		ensure_equals(LLURI::buildHTTP("host", "dir name").asString(), +					  "http://host/dir%20name"); +		ensure_equals(LLURI::buildHTTP("host", "dir name/").asString(), +					  "http://host/dir%20name/"); +		ensure_equals(LLURI::buildHTTP("host", "/dir name").asString(), +					  "http://host/dir%20name"); +		ensure_equals(LLURI::buildHTTP("host", "/dir name/").asString(), +					  "http://host/dir%20name/"); +		ensure_equals(LLURI::buildHTTP("host", "dir name/subdir name").asString(), +					  "http://host/dir%20name/subdir%20name"); +		ensure_equals(LLURI::buildHTTP("host", "dir name/subdir name/").asString(), +					  "http://host/dir%20name/subdir%20name/"); +		ensure_equals(LLURI::buildHTTP("host", "/dir name/subdir name").asString(), +					  "http://host/dir%20name/subdir%20name"); +		ensure_equals(LLURI::buildHTTP("host", "/dir name/subdir name/").asString(), +					  "http://host/dir%20name/subdir%20name/"); +		ensure_equals(LLURI::buildHTTP("host", "//dir name//subdir name//").asString(), +					  "http://host/dir%20name/subdir%20name/");  	}  	template<> template<>  	void URITestObject::test<9>()  	{ -		// test unescaped path components +		set_test_name("test unescaped path components");  		LLSD path;  		path.append("x@*//*$&^");  		path.append("123"); @@ -190,7 +215,7 @@ namespace tut  	template<> template<>  	void URITestObject::test<10>()  	{ -		// test unescaped query components +		set_test_name("test unescaped query components");  		LLSD path;  		path.append("x");  		path.append("123"); @@ -205,7 +230,7 @@ namespace tut  	template<> template<>  	void URITestObject::test<11>()  	{ -		// test unescaped host components +		set_test_name("test unescaped host components");  		LLSD path;  		path.append("x");  		path.append("123"); @@ -216,16 +241,16 @@ namespace tut  			"http", "//hi123*33--}{:portstuffs/x/123?123=12&abcd=abc",  			"hi123*33--}{:portstuffs", "/x/123", "123=12&abcd=abc");  	} -	 +  	template<> template<>  	void URITestObject::test<12>()  	{ -		// test funky host_port values that are actually prefixes -		 +		set_test_name("test funky host_port values that are actually prefixes"); +  		checkParts(LLURI::buildHTTP("http://example.com:8080", LLSD()),  			"http", "//example.com:8080",  			"example.com:8080", ""); -			 +  		checkParts(LLURI::buildHTTP("http://example.com:8080/", LLSD()),  			"http", "//example.com:8080/",  			"example.com:8080", "/"); @@ -242,7 +267,7 @@ namespace tut  			"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"  			"0123456789"  			"-._~"; -		// test escape +		set_test_name("test escape");  		ensure_equals("escaping", LLURI::escape("abcdefg", "abcdef"), "abcdef%67");  		ensure_equals("escaping", LLURI::escape("|/&\\+-_!@", ""), "%7C%2F%26%5C%2B%2D%5F%21%40");  		ensure_equals("escaping as query variable",  @@ -259,13 +284,12 @@ namespace tut  		cedilla.push_back( (char)0xA7 );  		ensure_equals("escape UTF8", LLURI::escape( cedilla, unreserved), "%C3%A7");  	} -	 +  	template<> template<>  	void URITestObject::test<14>()  	{ -		// make sure escape and unescape of empty strings return empty -		// strings. +		set_test_name("make sure escape and unescape of empty strings return empty strings.");  		std::string uri_esc(LLURI::escape(""));  		ensure("escape string empty", uri_esc.empty());  		std::string uri_raw(LLURI::unescape("")); @@ -275,7 +299,7 @@ namespace tut  	template<> template<>  	void URITestObject::test<15>()  	{ -		// do some round-trip tests +		set_test_name("do some round-trip tests");  		escapeRoundTrip("http://secondlife.com");  		escapeRoundTrip("http://secondlife.com/url with spaces");  		escapeRoundTrip("http://bad[domain]name.com/"); @@ -286,7 +310,7 @@ namespace tut  	template<> template<>  	void URITestObject::test<16>()  	{ -		// Test the default escaping +		set_test_name("Test the default escaping");  		// yes -- this mangles the url. This is expected behavior  		std::string simple("http://secondlife.com");  		ensure_equals( @@ -302,7 +326,7 @@ namespace tut  	template<> template<>  	void URITestObject::test<17>()  	{ -		// do some round-trip tests with very long strings. +		set_test_name("do some round-trip tests with very long strings.");  		escapeRoundTrip("Welcome to Second Life.We hope you'll have a richly rewarding experience, filled with creativity, self expression and fun.The goals of the Community Standards are simple: treat each other with respect and without harassment, adhere to local standards as indicated by simulator ratings, and refrain from any hate activity which slurs a real-world individual or real-world community. Behavioral Guidelines - The Big Six");  		escapeRoundTrip(  			"'asset_data':b(12100){'task_id':ucc706f2d-0b68-68f8-11a4-f1043ff35ca0}\n{\n\tname\tObject|\n\tpermissions 0\n\t{\n\t\tbase_mask\t7fffffff\n\t\towner_mask\t7fffffff\n\t\tgroup_mask\t00000000\n\t\teveryone_mask\t00000000\n\t\tnext_owner_mask\t7fffffff\n\t\tcreator_id\t13fd9595-a47b-4d64-a5fb-6da645f038e0\n\t\towner_id\t3c115e51-04f4-523c-9fa6-98aff1034730\n\t\tlast_owner_id\t3c115e51-04f4-523c-9fa6-98aff1034730\n\t\tgroup_id\t00000000-0000-0000-0000-000000000000\n\t}\n\tlocal_id\t217444921\n\ttotal_crc\t323\n\ttype\t2\n\ttask_valid\t2\n\ttravel_access\t13\n\tdisplayopts\t2\n\tdisplaytype\tv\n\tpos\t-0.368634403\t0.00781063363\t-0.569040775\n\toldpos\t150.117996\t25.8658009\t8.19664001\n\trotation\t-0.06293071806430816650390625\t-0.6995697021484375\t-0.7002241611480712890625\t0.1277817934751510620117188\n\tchildpos\t-0.00499999989\t-0.0359999985\t0.307999998\n\tchildrot\t-0.515492737293243408203125\t-0.46601200103759765625\t0.529055416584014892578125\t0.4870323240756988525390625\n\tscale" @@ -322,7 +346,7 @@ namespace tut  			"D STRING RW SV 20f36c3a-b44b-9bc7-87f3-018bfdfc8cda\n\tscratchpad\t0\n\t{\n\t\n\t}\n\tsale_info\t0\n\t{\n\t\tsale_type\tnot\n\t\tsale_price\t10\n\t}\n\torig_asset_id\t8747acbc-d391-1e59-69f1-41d06830e6c0\n\torig_item_id\t20f36c3a-b44b-9bc7-87f3-018bfdfc8cda\n\tfrom_task_id\t3c115e51-04f4-523c-9fa6-98aff1034730\n\tcorrect_family_id\t00000000-0000-0000-0000-000000000000\n\thas_rezzed\t0\n\tpre_link_base_mask\t7fffffff\n\tlinked \tlinked\n\tdefault_pay_price\t-2\t1\t5\t10\t20\n}\n");  	} -	  +  	template<> template<>  	void URITestObject::test<18>()  	{ @@ -335,7 +359,7 @@ namespace tut  		ensure_equals("pathmap",	u.pathArray()[1].asString(),	"login");  		ensure_equals("query",		u.query(),		"first_name=Testert4&last_name=Tester&web_login_key=test");  		ensure_equals("query map element", u.queryMap()["last_name"].asString(), "Tester"); -		 +  		u = LLURI("secondlife://Da Boom/128/128/128");  		// if secondlife is the scheme, LLURI should parse /128/128/128 as path, with Da Boom as authority  		ensure_equals("scheme",		u.scheme(),		"secondlife"); @@ -350,7 +374,7 @@ namespace tut  	template<> template<>  	void URITestObject::test<19>()  	{ -		// Parse about: schemes +		set_test_name("Parse about: schemes");  		LLURI u("about:blank?redirect-http-hack=secondlife%3A%2F%2F%2Fapp%2Flogin%3Ffirst_name%3DCallum%26last_name%3DLinden%26location%3Dspecify%26grid%3Dvaak%26region%3D%2FMorris%2F128%2F128%26web_login_key%3Defaa4795-c2aa-4c58-8966-763c27931e78");  		ensure_equals("scheme",		u.scheme(),		"about");  		ensure_equals("authority",	u.authority(),	""); | 
