diff options
Diffstat (limited to 'indra/llcommon')
269 files changed, 2538 insertions, 1029 deletions
| diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt index 5cce8ff2c4..95b1d536fe 100644..100755 --- a/indra/llcommon/CMakeLists.txt +++ b/indra/llcommon/CMakeLists.txt @@ -17,6 +17,7 @@ include_directories(      ${EXPAT_INCLUDE_DIRS}      ${LLCOMMON_INCLUDE_DIRS}      ${ZLIB_INCLUDE_DIRS} +    ${BREAKPAD_INCLUDE_DIRECTORIES}      )  # add_executable(lltreeiterators lltreeiterators.cpp) @@ -246,7 +247,6 @@ set(llcommon_HEADER_FILES      lluuid.h      lluuidhashmap.h      llversionserver.h -    llversionviewer.h      llworkerthread.h      ll_template_cast.h      metaclass.h diff --git a/indra/llcommon/bitpack.cpp b/indra/llcommon/bitpack.cpp index cdcaba0765..cdcaba0765 100644..100755 --- a/indra/llcommon/bitpack.cpp +++ b/indra/llcommon/bitpack.cpp diff --git a/indra/llcommon/bitpack.h b/indra/llcommon/bitpack.h index 037300dd14..037300dd14 100644..100755 --- a/indra/llcommon/bitpack.h +++ b/indra/llcommon/bitpack.h diff --git a/indra/llcommon/ctype_workaround.h b/indra/llcommon/ctype_workaround.h index 552be9fb90..552be9fb90 100644..100755 --- a/indra/llcommon/ctype_workaround.h +++ b/indra/llcommon/ctype_workaround.h diff --git a/indra/llcommon/doublelinkedlist.h b/indra/llcommon/doublelinkedlist.h index 0aeaa69df3..0aeaa69df3 100644..100755 --- a/indra/llcommon/doublelinkedlist.h +++ b/indra/llcommon/doublelinkedlist.h diff --git a/indra/llcommon/fix_macros.h b/indra/llcommon/fix_macros.h index ef959decff..ef959decff 100644..100755 --- a/indra/llcommon/fix_macros.h +++ b/indra/llcommon/fix_macros.h diff --git a/indra/llcommon/imageids.cpp b/indra/llcommon/imageids.cpp index fe11465221..7d647e5c36 100644..100755 --- 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 index e0c2683fdc..18c8ecb074 100644..100755 --- 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 diff --git a/indra/llcommon/indra_constants.cpp b/indra/llcommon/indra_constants.cpp index d32ae6c041..d32ae6c041 100644..100755 --- a/indra/llcommon/indra_constants.cpp +++ b/indra/llcommon/indra_constants.cpp diff --git a/indra/llcommon/indra_constants.h b/indra/llcommon/indra_constants.h index 0da83720bd..0da83720bd 100644..100755 --- a/indra/llcommon/indra_constants.h +++ b/indra/llcommon/indra_constants.h diff --git a/indra/llcommon/is_approx_equal_fraction.h b/indra/llcommon/is_approx_equal_fraction.h index 4a9b2e2725..4a9b2e2725 100644..100755 --- a/indra/llcommon/is_approx_equal_fraction.h +++ b/indra/llcommon/is_approx_equal_fraction.h diff --git a/indra/llcommon/linden_common.h b/indra/llcommon/linden_common.h index 5cfcdab41c..5cfcdab41c 100644..100755 --- a/indra/llcommon/linden_common.h +++ b/indra/llcommon/linden_common.h diff --git a/indra/llcommon/linked_lists.h b/indra/llcommon/linked_lists.h index 6b25295b7b..6b25295b7b 100644..100755 --- a/indra/llcommon/linked_lists.h +++ b/indra/llcommon/linked_lists.h diff --git a/indra/llcommon/ll_template_cast.h b/indra/llcommon/ll_template_cast.h index c8f9a2f7eb..c8f9a2f7eb 100644..100755 --- a/indra/llcommon/ll_template_cast.h +++ b/indra/llcommon/ll_template_cast.h diff --git a/indra/llcommon/llaccountingcost.h b/indra/llcommon/llaccountingcost.h index 0ef3b50c6d..0ef3b50c6d 100644..100755 --- a/indra/llcommon/llaccountingcost.h +++ b/indra/llcommon/llaccountingcost.h diff --git a/indra/llcommon/llagentconstants.h b/indra/llcommon/llagentconstants.h index cd237da4eb..cd237da4eb 100644..100755 --- a/indra/llcommon/llagentconstants.h +++ b/indra/llcommon/llagentconstants.h diff --git a/indra/llcommon/llallocator.cpp b/indra/llcommon/llallocator.cpp index 34fc28d8cc..34fc28d8cc 100644..100755 --- a/indra/llcommon/llallocator.cpp +++ b/indra/llcommon/llallocator.cpp diff --git a/indra/llcommon/llallocator.h b/indra/llcommon/llallocator.h index d26ad73c5b..d26ad73c5b 100644..100755 --- a/indra/llcommon/llallocator.h +++ b/indra/llcommon/llallocator.h diff --git a/indra/llcommon/llallocator_heap_profile.cpp b/indra/llcommon/llallocator_heap_profile.cpp index b574ef668b..b574ef668b 100644..100755 --- a/indra/llcommon/llallocator_heap_profile.cpp +++ b/indra/llcommon/llallocator_heap_profile.cpp diff --git a/indra/llcommon/llallocator_heap_profile.h b/indra/llcommon/llallocator_heap_profile.h index 69300b829b..69300b829b 100644..100755 --- a/indra/llcommon/llallocator_heap_profile.h +++ b/indra/llcommon/llallocator_heap_profile.h diff --git a/indra/llcommon/llapp.cpp b/indra/llcommon/llapp.cpp index ca258900c7..c6da205815 100644..100755 --- a/indra/llcommon/llapp.cpp +++ b/indra/llcommon/llapp.cpp @@ -69,10 +69,16 @@ bool windows_post_minidump_callback(const wchar_t* dump_path,  void setup_signals();  void default_unix_signal_handler(int signum, siginfo_t *info, void *); +#if LL_LINUX +#include "google_breakpad/minidump_descriptor.h" +bool unix_minidump_callback(const google_breakpad::MinidumpDescriptor& minidump_desc, void* context, bool succeeded); +#else  // Called by breakpad exception handler after the minidump has been generated.  bool unix_post_minidump_callback(const char *dump_dir,  					  const char *minidump_id,  					  void *context, bool succeeded); +#endif +  # if LL_DARWIN  /* OSX doesn't support SIGRT* */  S32 LL_SMACKDOWN_SIGNAL = SIGUSR1; @@ -313,7 +319,7 @@ void LLApp::setupErrorHandling()  	// Add google breakpad exception handler configured for Darwin/Linux.  	bool installHandler = true; -#ifdef LL_DARWIN +#if LL_DARWIN  	// For the special case of Darwin, we do not want to install the handler if  	// the process is being debugged as the app will exit with value ABRT (6) if  	// we do.  Unfortunately, the code below which performs that test relies on @@ -346,14 +352,21 @@ void LLApp::setupErrorHandling()  		installHandler = true;  	}  	#endif -#endif +  	if(installHandler && (mExceptionHandler == 0))  	{  		std::string dumpPath = "/tmp/"; -		mExceptionHandler = new google_breakpad::ExceptionHandler(dumpPath, 0, &unix_post_minidump_callback, 0, true); +		mExceptionHandler = new google_breakpad::ExceptionHandler(dumpPath, 0, &unix_post_minidump_callback, 0, true, 0); +	} +#elif LL_LINUX +	if(installHandler && (mExceptionHandler == 0)) +	{ +		google_breakpad::MinidumpDescriptor desc("/tmp"); +	        new google_breakpad::ExceptionHandler(desc, 0, &unix_minidump_callback, 0, true, 0);  	}  #endif +#endif  	startErrorThread();  } @@ -410,6 +423,9 @@ void LLApp::setMiniDumpDir(const std::string &path)  	wchar_t buffer[MAX_MINDUMP_PATH_LENGTH];  	mbstowcs(buffer, path.c_str(), MAX_MINDUMP_PATH_LENGTH);  	mExceptionHandler->set_dump_path(std::wstring(buffer)); +#elif LL_LINUX +        google_breakpad::MinidumpDescriptor desc(path); +	mExceptionHandler->set_minidump_descriptor(desc);  #else  	mExceptionHandler->set_dump_path(path);  #endif @@ -857,6 +873,43 @@ void default_unix_signal_handler(int signum, siginfo_t *info, void *)  	}  } +#if LL_LINUX +bool unix_minidump_callback(const google_breakpad::MinidumpDescriptor& minidump_desc, void* context, bool succeeded) +{ +	// Copy minidump file path into fixed buffer in the app instance to avoid +	// heap allocations in a crash handler. +	 +	// path format: <dump_dir>/<minidump_id>.dmp +	int dirPathLength = strlen(minidump_desc.path()); +	 +	// The path must not be truncated. +	llassert((dirPathLength + 5) <= LLApp::MAX_MINDUMP_PATH_LENGTH); +	 +	char * path = LLApp::instance()->getMiniDumpFilename(); +	S32 remaining = LLApp::MAX_MINDUMP_PATH_LENGTH; +	strncpy(path, minidump_desc.path(), remaining); +	remaining -= dirPathLength; +	path += dirPathLength; +	if (remaining > 0 && dirPathLength > 0 && path[-1] != '/') +	{ +		*path++ = '/'; +		--remaining; +	} +	 +	llinfos << "generated minidump: " << LLApp::instance()->getMiniDumpFilename() << llendl; +	LLApp::runErrorHandler(); +	 +#ifndef LL_RELEASE_FOR_DOWNLOAD +	clear_signals(); +	return false; +#else +	return true; +#endif + +} +#endif + +  bool unix_post_minidump_callback(const char *dump_dir,  					  const char *minidump_id,  					  void *context, bool succeeded) diff --git a/indra/llcommon/llapp.h b/indra/llcommon/llapp.h index a536a06ea5..afa06df23e 100644..100755 --- a/indra/llcommon/llapp.h +++ b/indra/llcommon/llapp.h @@ -38,7 +38,7 @@ typedef LLAtomic32<U32> LLAtomicU32;  class LLErrorThread;  class LLLiveFile;  #if LL_LINUX -typedef struct siginfo siginfo_t; +#include <signal.h>  #endif  typedef void (*LLAppErrorHandler)(); diff --git a/indra/llcommon/llapr.cpp b/indra/llcommon/llapr.cpp index d1c44c9403..d1c44c9403 100644..100755 --- a/indra/llcommon/llapr.cpp +++ b/indra/llcommon/llapr.cpp diff --git a/indra/llcommon/llapr.h b/indra/llcommon/llapr.h index 034546c3f3..034546c3f3 100644..100755 --- a/indra/llcommon/llapr.h +++ b/indra/llcommon/llapr.h diff --git a/indra/llcommon/llassettype.cpp b/indra/llcommon/llassettype.cpp index 5e566d6c7c..5ae2df3994 100644..100755 --- 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..100755 --- 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/llassoclist.h b/indra/llcommon/llassoclist.h index 2950504155..2950504155 100644..100755 --- a/indra/llcommon/llassoclist.h +++ b/indra/llcommon/llassoclist.h diff --git a/indra/llcommon/llavatarconstants.h b/indra/llcommon/llavatarconstants.h index f47f447b45..f47f447b45 100644..100755 --- a/indra/llcommon/llavatarconstants.h +++ b/indra/llcommon/llavatarconstants.h diff --git a/indra/llcommon/llavatarname.cpp b/indra/llcommon/llavatarname.cpp index 3206843bf4..642bd82e90 100644..100755 --- 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,14 @@ 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; + +// 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(), @@ -61,6 +70,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,21 +105,75 @@ 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; +	} +} + +// 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); +		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;  } @@ -118,3 +192,48 @@ std::string LLAvatarName::getLegacyName() const  	name += mLegacyLastName;  	return name;  } + +std::string LLAvatarName::getDisplayName() const +{ +	if (sUseDisplayNames) +	{ +		return mDisplayName; +	} +	else +	{ +		return getUserName(); +	} +} + +std::string LLAvatarName::getUserName() const +{ +	std::string name; +	if (mLegacyLastName.empty() || (mLegacyLastName == "Resident")) +	{ +		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; +	} +	return name; +} + +void LLAvatarName::dump() const +{ +	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..7542a8dece 100644..100755 --- a/indra/llcommon/llavatarname.h +++ b/indra/llcommon/llavatarname.h @@ -39,10 +39,27 @@ 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 +	// 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(); +	 +	// 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)"  	// When display names are disabled returns just "James Linden"  	std::string getCompleteName() const; @@ -51,11 +68,38 @@ public:  	// 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; +	 +	// 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; +	 +	// 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 +125,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 diff --git a/indra/llcommon/llbase32.cpp b/indra/llcommon/llbase32.cpp index 053ac0d32f..053ac0d32f 100644..100755 --- a/indra/llcommon/llbase32.cpp +++ b/indra/llcommon/llbase32.cpp diff --git a/indra/llcommon/llbase32.h b/indra/llcommon/llbase32.h index eeb96d789d..eeb96d789d 100644..100755 --- a/indra/llcommon/llbase32.h +++ b/indra/llcommon/llbase32.h diff --git a/indra/llcommon/llbase64.cpp b/indra/llcommon/llbase64.cpp index 4e82cf7f20..4e82cf7f20 100644..100755 --- a/indra/llcommon/llbase64.cpp +++ b/indra/llcommon/llbase64.cpp diff --git a/indra/llcommon/llbase64.h b/indra/llcommon/llbase64.h index 16d2c217d0..16d2c217d0 100644..100755 --- a/indra/llcommon/llbase64.h +++ b/indra/llcommon/llbase64.h diff --git a/indra/llcommon/llboost.h b/indra/llcommon/llboost.h index 57d958a51a..57d958a51a 100644..100755 --- a/indra/llcommon/llboost.h +++ b/indra/llcommon/llboost.h diff --git a/indra/llcommon/llchat.h b/indra/llcommon/llchat.h index f5b242fdfc..f5b242fdfc 100644..100755 --- a/indra/llcommon/llchat.h +++ b/indra/llcommon/llchat.h diff --git a/indra/llcommon/llclickaction.h b/indra/llcommon/llclickaction.h index 1f87d8eec3..1f87d8eec3 100644..100755 --- a/indra/llcommon/llclickaction.h +++ b/indra/llcommon/llclickaction.h diff --git a/indra/llcommon/llcommon.cpp b/indra/llcommon/llcommon.cpp index 8be9e4f4de..8be9e4f4de 100644..100755 --- a/indra/llcommon/llcommon.cpp +++ b/indra/llcommon/llcommon.cpp diff --git a/indra/llcommon/llcommon.h b/indra/llcommon/llcommon.h index ca9cad5d05..ca9cad5d05 100644..100755 --- a/indra/llcommon/llcommon.h +++ b/indra/llcommon/llcommon.h diff --git a/indra/llcommon/llcommonutils.cpp b/indra/llcommon/llcommonutils.cpp index d82554c202..d82554c202 100644..100755 --- a/indra/llcommon/llcommonutils.cpp +++ b/indra/llcommon/llcommonutils.cpp diff --git a/indra/llcommon/llcommonutils.h b/indra/llcommon/llcommonutils.h index 755dc41fb4..755dc41fb4 100644..100755 --- a/indra/llcommon/llcommonutils.h +++ b/indra/llcommon/llcommonutils.h diff --git a/indra/llcommon/llcoros.cpp b/indra/llcommon/llcoros.cpp index 9122704306..9122704306 100644..100755 --- a/indra/llcommon/llcoros.cpp +++ b/indra/llcommon/llcoros.cpp diff --git a/indra/llcommon/llcoros.h b/indra/llcommon/llcoros.h index 03df406b68..03df406b68 100644..100755 --- a/indra/llcommon/llcoros.h +++ b/indra/llcommon/llcoros.h diff --git a/indra/llcommon/llcrc.cpp b/indra/llcommon/llcrc.cpp index e80da0bb0d..e80da0bb0d 100644..100755 --- a/indra/llcommon/llcrc.cpp +++ b/indra/llcommon/llcrc.cpp diff --git a/indra/llcommon/llcrc.h b/indra/llcommon/llcrc.h index 2d291d92a1..2d291d92a1 100644..100755 --- a/indra/llcommon/llcrc.h +++ b/indra/llcommon/llcrc.h diff --git a/indra/llcommon/llcriticaldamp.cpp b/indra/llcommon/llcriticaldamp.cpp index 87d79b1ee0..87d79b1ee0 100644..100755 --- a/indra/llcommon/llcriticaldamp.cpp +++ b/indra/llcommon/llcriticaldamp.cpp diff --git a/indra/llcommon/llcriticaldamp.h b/indra/llcommon/llcriticaldamp.h index 52f052ae25..52f052ae25 100644..100755 --- a/indra/llcommon/llcriticaldamp.h +++ b/indra/llcommon/llcriticaldamp.h diff --git a/indra/llcommon/llcursortypes.cpp b/indra/llcommon/llcursortypes.cpp index ec60097195..ec60097195 100644..100755 --- a/indra/llcommon/llcursortypes.cpp +++ b/indra/llcommon/llcursortypes.cpp diff --git a/indra/llcommon/llcursortypes.h b/indra/llcommon/llcursortypes.h index cb6d6636a0..cb6d6636a0 100644..100755 --- a/indra/llcommon/llcursortypes.h +++ b/indra/llcommon/llcursortypes.h diff --git a/indra/llcommon/lldarray.h b/indra/llcommon/lldarray.h index 131b819c99..131b819c99 100644..100755 --- a/indra/llcommon/lldarray.h +++ b/indra/llcommon/lldarray.h diff --git a/indra/llcommon/lldarrayptr.h b/indra/llcommon/lldarrayptr.h index c9a0b204d1..c9a0b204d1 100644..100755 --- a/indra/llcommon/lldarrayptr.h +++ b/indra/llcommon/lldarrayptr.h diff --git a/indra/llcommon/lldate.cpp b/indra/llcommon/lldate.cpp index 030ef6a3c7..030ef6a3c7 100644..100755 --- a/indra/llcommon/lldate.cpp +++ b/indra/llcommon/lldate.cpp diff --git a/indra/llcommon/lldate.h b/indra/llcommon/lldate.h index 7ff8b550ad..7ff8b550ad 100644..100755 --- a/indra/llcommon/lldate.h +++ b/indra/llcommon/lldate.h diff --git a/indra/llcommon/lldefs.h b/indra/llcommon/lldefs.h index 5a4b8325f4..5a4b8325f4 100644..100755 --- a/indra/llcommon/lldefs.h +++ b/indra/llcommon/lldefs.h diff --git a/indra/llcommon/lldeleteutils.h b/indra/llcommon/lldeleteutils.h index f250dc3028..f250dc3028 100644..100755 --- a/indra/llcommon/lldeleteutils.h +++ b/indra/llcommon/lldeleteutils.h diff --git a/indra/llcommon/lldependencies.cpp b/indra/llcommon/lldependencies.cpp index 0e72c175cb..0e72c175cb 100644..100755 --- a/indra/llcommon/lldependencies.cpp +++ b/indra/llcommon/lldependencies.cpp diff --git a/indra/llcommon/lldependencies.h b/indra/llcommon/lldependencies.h index e0294e271b..e0294e271b 100644..100755 --- a/indra/llcommon/lldependencies.h +++ b/indra/llcommon/lldependencies.h diff --git a/indra/llcommon/lldepthstack.h b/indra/llcommon/lldepthstack.h index d9db54efc7..d9db54efc7 100644..100755 --- a/indra/llcommon/lldepthstack.h +++ b/indra/llcommon/lldepthstack.h diff --git a/indra/llcommon/lldictionary.cpp b/indra/llcommon/lldictionary.cpp index e16c35ed6a..e16c35ed6a 100644..100755 --- a/indra/llcommon/lldictionary.cpp +++ b/indra/llcommon/lldictionary.cpp diff --git a/indra/llcommon/lldictionary.h b/indra/llcommon/lldictionary.h index bc3bc3e74a..c752859a36 100644..100755 --- a/indra/llcommon/lldictionary.h +++ b/indra/llcommon/lldictionary.h @@ -30,6 +30,8 @@  #include <map>  #include <string> +#include "llerror.h" +  struct LL_COMMON_API LLDictionaryEntry  {  	LLDictionaryEntry(const std::string &name); diff --git a/indra/llcommon/lldlinked.h b/indra/llcommon/lldlinked.h index 3f7c197be7..3f7c197be7 100644..100755 --- a/indra/llcommon/lldlinked.h +++ b/indra/llcommon/lldlinked.h diff --git a/indra/llcommon/lldoubledispatch.h b/indra/llcommon/lldoubledispatch.h index 8ed295b6f1..8ed295b6f1 100644..100755 --- a/indra/llcommon/lldoubledispatch.h +++ b/indra/llcommon/lldoubledispatch.h diff --git a/indra/llcommon/lldqueueptr.h b/indra/llcommon/lldqueueptr.h index 9fe08191e1..9fe08191e1 100644..100755 --- a/indra/llcommon/lldqueueptr.h +++ b/indra/llcommon/lldqueueptr.h diff --git a/indra/llcommon/llendianswizzle.h b/indra/llcommon/llendianswizzle.h index 4c08074a9c..4c08074a9c 100644..100755 --- a/indra/llcommon/llendianswizzle.h +++ b/indra/llcommon/llendianswizzle.h diff --git a/indra/llcommon/llenum.h b/indra/llcommon/llenum.h index f57b2bc0b5..f57b2bc0b5 100644..100755 --- a/indra/llcommon/llenum.h +++ b/indra/llcommon/llenum.h diff --git a/indra/llcommon/llerror.cpp b/indra/llcommon/llerror.cpp index 9b0141eb76..9b0141eb76 100644..100755 --- a/indra/llcommon/llerror.cpp +++ b/indra/llcommon/llerror.cpp diff --git a/indra/llcommon/llerror.h b/indra/llcommon/llerror.h index b65b410153..b65b410153 100644..100755 --- a/indra/llcommon/llerror.h +++ b/indra/llcommon/llerror.h diff --git a/indra/llcommon/llerrorcontrol.h b/indra/llcommon/llerrorcontrol.h index 480654b1a2..480654b1a2 100644..100755 --- a/indra/llcommon/llerrorcontrol.h +++ b/indra/llcommon/llerrorcontrol.h diff --git a/indra/llcommon/llerrorlegacy.h b/indra/llcommon/llerrorlegacy.h index 37cee579cd..37cee579cd 100644..100755 --- a/indra/llcommon/llerrorlegacy.h +++ b/indra/llcommon/llerrorlegacy.h diff --git a/indra/llcommon/llerrorthread.cpp b/indra/llcommon/llerrorthread.cpp index 950fcd6e83..950fcd6e83 100644..100755 --- a/indra/llcommon/llerrorthread.cpp +++ b/indra/llcommon/llerrorthread.cpp diff --git a/indra/llcommon/llerrorthread.h b/indra/llcommon/llerrorthread.h index 474cef3a50..474cef3a50 100644..100755 --- a/indra/llcommon/llerrorthread.h +++ b/indra/llcommon/llerrorthread.h diff --git a/indra/llcommon/llevent.cpp b/indra/llcommon/llevent.cpp index 633df01588..633df01588 100644..100755 --- a/indra/llcommon/llevent.cpp +++ b/indra/llcommon/llevent.cpp diff --git a/indra/llcommon/llevent.h b/indra/llcommon/llevent.h index 8cd682b8bf..8cd682b8bf 100644..100755 --- a/indra/llcommon/llevent.h +++ b/indra/llcommon/llevent.h diff --git a/indra/llcommon/lleventapi.cpp b/indra/llcommon/lleventapi.cpp index ff5459c1eb..ff5459c1eb 100644..100755 --- a/indra/llcommon/lleventapi.cpp +++ b/indra/llcommon/lleventapi.cpp diff --git a/indra/llcommon/lleventapi.h b/indra/llcommon/lleventapi.h index 1a37d780b6..1a37d780b6 100644..100755 --- a/indra/llcommon/lleventapi.h +++ b/indra/llcommon/lleventapi.h diff --git a/indra/llcommon/lleventcoro.cpp b/indra/llcommon/lleventcoro.cpp index 81cc33fbba..81cc33fbba 100644..100755 --- a/indra/llcommon/lleventcoro.cpp +++ b/indra/llcommon/lleventcoro.cpp diff --git a/indra/llcommon/lleventcoro.h b/indra/llcommon/lleventcoro.h index a42af63b65..a42af63b65 100644..100755 --- a/indra/llcommon/lleventcoro.h +++ b/indra/llcommon/lleventcoro.h diff --git a/indra/llcommon/lleventdispatcher.cpp b/indra/llcommon/lleventdispatcher.cpp index 5b6d4efbe9..5b6d4efbe9 100644..100755 --- a/indra/llcommon/lleventdispatcher.cpp +++ b/indra/llcommon/lleventdispatcher.cpp diff --git a/indra/llcommon/lleventdispatcher.h b/indra/llcommon/lleventdispatcher.h index 7acc61de4e..7acc61de4e 100644..100755 --- a/indra/llcommon/lleventdispatcher.h +++ b/indra/llcommon/lleventdispatcher.h diff --git a/indra/llcommon/lleventemitter.h b/indra/llcommon/lleventemitter.h index cd82fc56f9..cd82fc56f9 100644..100755 --- a/indra/llcommon/lleventemitter.h +++ b/indra/llcommon/lleventemitter.h diff --git a/indra/llcommon/lleventfilter.cpp b/indra/llcommon/lleventfilter.cpp index d36a107254..d36a107254 100644..100755 --- a/indra/llcommon/lleventfilter.cpp +++ b/indra/llcommon/lleventfilter.cpp diff --git a/indra/llcommon/lleventfilter.h b/indra/llcommon/lleventfilter.h index e822a664f5..e822a664f5 100644..100755 --- a/indra/llcommon/lleventfilter.h +++ b/indra/llcommon/lleventfilter.h diff --git a/indra/llcommon/llevents.cpp b/indra/llcommon/llevents.cpp index 0855180dcd..0855180dcd 100644..100755 --- a/indra/llcommon/llevents.cpp +++ b/indra/llcommon/llevents.cpp diff --git a/indra/llcommon/llevents.h b/indra/llcommon/llevents.h index 65b0fef354..65b0fef354 100644..100755 --- a/indra/llcommon/llevents.h +++ b/indra/llcommon/llevents.h diff --git a/indra/llcommon/lleventtimer.cpp b/indra/llcommon/lleventtimer.cpp index 0d96e03da4..0d96e03da4 100644..100755 --- a/indra/llcommon/lleventtimer.cpp +++ b/indra/llcommon/lleventtimer.cpp diff --git a/indra/llcommon/lleventtimer.h b/indra/llcommon/lleventtimer.h index 7f42623d01..7f42623d01 100644..100755 --- a/indra/llcommon/lleventtimer.h +++ b/indra/llcommon/lleventtimer.h diff --git a/indra/llcommon/llextendedstatus.h b/indra/llcommon/llextendedstatus.h index 8ce173d1ff..8ce173d1ff 100644..100755 --- a/indra/llcommon/llextendedstatus.h +++ b/indra/llcommon/llextendedstatus.h diff --git a/indra/llcommon/llfasttimer.cpp b/indra/llcommon/llfasttimer.cpp index 6970c29092..9b15804e97 100644..100755 --- a/indra/llcommon/llfasttimer.cpp +++ b/indra/llcommon/llfasttimer.cpp @@ -561,6 +561,12 @@ std::vector<LLFastTimer::NamedTimer*>& 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..100755 --- 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; diff --git a/indra/llcommon/llfile.cpp b/indra/llcommon/llfile.cpp index c51d042a3d..864b6e6975 100644..100755 --- 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<char,std::char_traits < char > > _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)  {	// open a file  	static const char *mods[] =  	{	// fopen mode strings corresponding to valid[i] @@ -385,117 +388,690 @@ 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 +//} + + +// *TODO: Seek the underlying c stream for better cross-platform compatibility? +#if !LL_WINDOWS +llstdio_filebuf::int_type llstdio_filebuf::overflow(llstdio_filebuf::int_type __c) +{ +	int_type __ret = traits_type::eof(); +	const bool __testeof = traits_type::eq_int_type(__c, __ret); +	const bool __testout = _M_mode & ios_base::out; +	if (__testout && !_M_reading)  	{ -		_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<char*>(__ibuf), __ilen); +		__elen = fwrite(reinterpret_cast<void*>(__ibuf), 1, +						__ilen, _M_file.file()); +		__plen = __ilen; +	} +	else +	{ +		// Worst-case number of external bytes needed. +		// XXX Not done encoding() == -1. +		streamsize __blen = __ilen * _M_codecvt->max_length(); +		char* __buf = static_cast<char*>(__builtin_alloca(__blen)); -	LLFILE* filep = LLFile::_Fiopen(_Filename,_Mode | ios_base::in, _Prot); -	if(filep == NULL) +		char* __bend; +		const char_type* __iend; +		codecvt_base::result __r; +		__r = _M_codecvt->out(_M_state_cur, __ibuf, __ibuf + __ilen, +				__iend, __buf, __buf + __blen, __bend); + +		if (__r == codecvt_base::ok || __r == codecvt_base::partial) +			__blen = __bend - __buf; +		else if (__r == codecvt_base::noconv) +		{ +			// Same as the always_noconv case above. +			__buf = reinterpret_cast<char*>(__ibuf); +			__blen = __ilen; +		} +		else +			__throw_ios_failure(__N("llstdio_filebuf::_convert_to_external " +									"conversion error")); +   +		//__elen = _M_file.xsputn(__buf, __blen); +		__elen = fwrite(__buf, 1, __blen, _M_file.file()); +		__plen = __blen; + +		// Try once more for partial conversions. +		if (__r == codecvt_base::partial && __elen == __plen) +		{ +			const char_type* __iresume = __iend; +			streamsize __rlen = this->pptr() - __iend; +			__r = _M_codecvt->out(_M_state_cur, __iresume, +					__iresume + __rlen, __iend, __buf, +					__buf + __blen, __bend); +			if (__r != codecvt_base::error) +			{ +				__rlen = __bend - __buf; +				//__elen = _M_file.xsputn(__buf, __rlen); +				__elen = fwrite(__buf, 1, __rlen, _M_file.file()); +				__plen = __rlen; +			} +			else +			{ +				__throw_ios_failure(__N("llstdio_filebuf::_convert_to_external " +										"conversion error")); +			} +		} +	} +	return __elen == __plen; +} + +llstdio_filebuf::int_type llstdio_filebuf::underflow() +{ +	int_type __ret = traits_type::eof(); +	const bool __testin = _M_mode & ios_base::in; +	if (__testin)  	{ -		_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<char*>(this->eback()), +			//			__buflen); +			__ilen = fread(reinterpret_cast<void*>(this->eback()), 1, +						__buflen, _M_file.file()); +			if (__ilen == 0) +				__got_eof = true; +		} +		else +	    { +			// Worst-case number of external bytes. +			// XXX Not done encoding() == -1. +			const int __enc = _M_codecvt->encoding(); +			streamsize __blen; // Minimum buffer size. +			streamsize __rlen; // Number of chars to read. +			if (__enc > 0) +				__blen = __rlen = __buflen * __enc; +			else +			{ +				__blen = __buflen + _M_codecvt->max_length() - 1; +				__rlen = __buflen; +			} +			const streamsize __remainder = _M_ext_end - _M_ext_next; +			__rlen = __rlen > __remainder ? __rlen - __remainder : 0; + +			// An imbue in 'read' mode implies first converting the external +			// chars already present. +			if (_M_reading && this->egptr() == this->eback() && __remainder) +				__rlen = 0; + +			// Allocate buffer if necessary and move unconverted +			// bytes to front. +			if (_M_ext_buf_size < __blen) +			{ +				char* __buf = new char[__blen]; +				if (__remainder) +					__builtin_memcpy(__buf, _M_ext_next, __remainder); + +				delete [] _M_ext_buf; +				_M_ext_buf = __buf; +				_M_ext_buf_size = __blen; +			} +			else if (__remainder) +				__builtin_memmove(_M_ext_buf, _M_ext_next, __remainder); + +			_M_ext_next = _M_ext_buf; +			_M_ext_end = _M_ext_buf + __remainder; +			_M_state_last = _M_state_cur; + +			do +			{ +				if (__rlen > 0) +				{ +					// Sanity check! +					// This may fail if the return value of +					// codecvt::max_length() is bogus. +					if (_M_ext_end - _M_ext_buf + __rlen > _M_ext_buf_size) +					{ +						__throw_ios_failure(__N("llstdio_filebuf::underflow " +							"codecvt::max_length() " +							"is not valid")); +					} +					//streamsize __elen = _M_file.xsgetn(_M_ext_end, __rlen); +					streamsize __elen = fread(_M_ext_end, 1, +						__rlen, _M_file.file()); +					if (__elen == 0) +						__got_eof = true; +					else if (__elen == -1) +					break; +					//_M_ext_end += __elen; +				} + +				char_type* __iend = this->eback(); +				if (_M_ext_next < _M_ext_end) +				{ +					__r = _M_codecvt->in(_M_state_cur, _M_ext_next, +							_M_ext_end, _M_ext_next, +							this->eback(), +							this->eback() + __buflen, __iend); +				} +				if (__r == codecvt_base::noconv) +				{ +					size_t __avail = _M_ext_end - _M_ext_buf; +					__ilen = std::min(__avail, __buflen); +					traits_type::copy(this->eback(), +						reinterpret_cast<char_type*> +						(_M_ext_buf), __ilen); +					_M_ext_next = _M_ext_buf + __ilen; +				} +				else +					__ilen = __iend - this->eback(); + +				// _M_codecvt->in may return error while __ilen > 0: this is +				// ok, and actually occurs in case of mixed encodings (e.g., +				// XML files). +				if (__r == codecvt_base::error) +					break; + +				__rlen = 1; +			} while (__ilen == 0 && !__got_eof); +		} + +		if (__ilen > 0) +		{ +			_M_set_buffer(__ilen); +			_M_reading = true; +			__ret = traits_type::to_int_type(*this->gptr()); +		} +		else if (__got_eof) +		{ +			// If the actual end of file is reached, set 'uncommitted' +			// mode, thus allowing an immediate write without an +			// intervening seek. +			_M_set_buffer(-1); +			_M_reading = false; +			// However, reaching it while looping on partial means that +			// the file has got an incomplete character. +			if (__r == codecvt_base::partial) +				__throw_ios_failure(__N("llstdio_filebuf::underflow " +					"incomplete character in file")); +		} +		else if (__r == codecvt_base::error) +			__throw_ios_failure(__N("llstdio_filebuf::underflow " +					"invalid byte sequence in file")); +		else +			__throw_ios_failure(__N("llstdio_filebuf::underflow " +					"error reading the file"));  	} -	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<char*>(__s), __n); +			__len = fread(reinterpret_cast<void*>(__s), 1,  +						__n, _M_file.file()); +			if (__len == -1) +				__throw_ios_failure(__N("llstdio_filebuf::xsgetn " +										"error reading the file")); +			if (__len == 0) +				break; + +			__n -= __len; +			__ret += __len; +			if (__n == 0) +				break; + +			__s += __len; +		} + +		if (__n == 0) +		{ +			_M_set_buffer(0); +			_M_reading = true; +		} +		else if (__len == 0) +		{ +			// If end of file is reached, set 'uncommitted' +			// mode, thus allowing an immediate write without +			// an intervening seek. +			_M_set_buffer(-1); +			_M_reading = false; +		} +	} +	else +		__ret += __streambuf_type::xsgetn(__s, __n); + +	return __ret;  } -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<const char*>(this->pbase()); +			//__ret = _M_file.xsputn_2(__buf, __buffill, +			//			reinterpret_cast<const char*>(__s), __n); +			if (__buffill) +			{ +				__ret = fwrite(__buf, 1, __buffill, _M_file.file()); +			} +			if (__ret == __buffill) +			{ +				__ret += fwrite(reinterpret_cast<const char*>(__s), 1, +								__n, _M_file.file()); +			} +			if (__ret == __buffill + __n) +			{ +				_M_set_buffer(0); +				_M_writing = true; +			} +			if (__ret > __buffill) +				__ret -= __buffill; +			else +				__ret = 0; +		} +		else +			__ret = __streambuf_type::xsputn(__s, __n);  	} -	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); +} +#endif + +/************** input file stream ********************************/ + -{	// construct with named file and specified mode -	open(_Filename, _Mode | ios_base::in, _Prot);	/* Flawfinder: ignore */ +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) +{ +	llutf16string wideName = utf8str_to_utf16str( _Filename ); +	if (_M_filebuf.open(wideName.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 -/************** output file stream ********************************/ +// explicit +llifstream::llifstream(const char* _Filename,  +		ios_base::openmode _Mode) : _M_filebuf(), +#if LL_WINDOWS +	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); +	} +} +#else +	std::istream() +{ +	this->init(&_M_filebuf); +	this->open(_Filename, _Mode | ios_base::in); +} +#endif -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 LL_WINDOWS +	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::setstate(ios_base::failbit);	/*Flawfinder: ignore*/ -		return; +		_Myios::clear();  	} -	llassert(_Filebuffer==NULL); -	_Filebuffer = new _Myfb(filep); -	_ShouldClose = true; -	_Myios::init(_Filebuffer); +#else +	if (_M_filebuf.open(_Filename, _Mode | ios_base::in) == 0) +	{ +		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<char,std::char_traits < char > >(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) +{ +	llutf16string wideName = utf8str_to_utf16str( _Filename ); +	if (_M_filebuf.open( wideName.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) +{ +	llutf16string wideName = utf8str_to_utf16str( _Filename ); +	if (_M_filebuf.open( wideName.c_str(), _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 LL_WINDOWS +	llutf16string wideName = utf8str_to_utf16str( _Filename ); +	if (_M_filebuf.open( wideName.c_str(), _Mode | ios_base::out) == 0) +	{ +		_Myios::setstate(ios_base::failbit); +	} +	else  	{ -		close(); +		_Myios::clear();  	} -	delete _Filebuffer; +#else +	if (_M_filebuf.open(_Filename, _Mode | ios_base::out) == 0) +	{ +		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..9d70db96ea 100644..100755 --- a/indra/llcommon/llfile.h +++ b/indra/llcommon/llfile.h @@ -35,16 +35,9 @@   * Attempts to mostly mirror the POSIX style IO functions.   */ -typedef FILE	LLFILE; +typedef FILE LLFILE;  #include <fstream> - -#ifdef LL_WINDOWS -#define	USE_LLFILESTREAMS	1 -#else -#define	USE_LLFILESTREAMS	0 -#endif -  #include <sys/stat.h>  #if LL_WINDOWS @@ -52,6 +45,8 @@ typedef FILE	LLFILE;  typedef struct _stat	llstat;  #else  typedef struct stat		llstat; +#include <ext/stdio_filebuf.h> +#include <bits/postypes.h>  #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<char,std::char_traits < char > > _Myt; -	typedef std::basic_filebuf<char,std::char_traits< char > > _Myfb; -	typedef std::basic_ios<char,std::char_traits< char > > _Myios; - -	llifstream() -		: std::basic_istream<char,std::char_traits< char > >(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<size_t>(BUFSIZ)) : +		    size_t __size = static_cast<size_t>(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<char,std::char_traits< char > >(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<size_t>(BUFSIZ)) : +		size_t __size = static_cast<size_t>(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<char,std::char_traits < char > > _Myios; - -	llofstream() -		: std::basic_ostream<char,std::char_traits < char > >(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<char,std::char_traits < char > >(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<size_t>(BUFSIZ)); +			size_t _Size = static_cast<size_t>(1)); + +	/** +	 *  @brief  Create a stream using an open file descriptor. +	 *  @param  fd    An open file descriptor. +        @param  Mode  Same meaning as in a standard filebuf. +        @param  Size  Optimal or preferred size of internal buffer, in chars. +                      Defaults to system's @c BUFSIZ. +	*/ +#if !LL_WINDOWS +	explicit llifstream(int __fd, +			ios_base::openmode _Mode = ios_base::in, +			//size_t _Size = static_cast<size_t>(BUFSIZ)); +			size_t _Size = static_cast<size_t>(1)); +#endif +	/** +	 *  @brief  The destructor does nothing. +	 * +	 *  The file is closed by the filebuf object, not the formatting +	 *  stream. +	*/ +	virtual ~llifstream() {} + +	// Members: +	/** +	 *  @brief  Accessing the underlying buffer. +	 *  @return  The current basic_filebuf buffer. +	 * +	 *  This hides both signatures of std::basic_ios::rdbuf(). +	*/ +	llstdio_filebuf* rdbuf() const +	{ return const_cast<llstdio_filebuf*>(&_M_filebuf); } + +	/** +	 *  @brief  Wrapper to test for an open file. +	 *  @return  @c rdbuf()->is_open() +	*/  	bool is_open() const; -	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<size_t>(BUFSIZ)); +			size_t _Size = static_cast<size_t>(1)); + +	/** +	 *  @brief  Create a stream using an open file descriptor. +	 *  @param  fd    An open file descriptor. +        @param  Mode  Same meaning as in a standard filebuf. +        @param  Size  Optimal or preferred size of internal buffer, in chars. +                      Defaults to system's @c BUFSIZ. +	*/ +#if !LL_WINDOWS +	explicit llofstream(int __fd, +			ios_base::openmode _Mode = ios_base::out, +			//size_t _Size = static_cast<size_t>(BUFSIZ)); +			size_t _Size = static_cast<size_t>(1)); +#endif -	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<llstdio_filebuf*>(&_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. diff --git a/indra/llcommon/llfindlocale.cpp b/indra/llcommon/llfindlocale.cpp index cd7c0c7c09..cd7c0c7c09 100644..100755 --- a/indra/llcommon/llfindlocale.cpp +++ b/indra/llcommon/llfindlocale.cpp diff --git a/indra/llcommon/llfindlocale.h b/indra/llcommon/llfindlocale.h index 6770db5774..6770db5774 100644..100755 --- a/indra/llcommon/llfindlocale.h +++ b/indra/llcommon/llfindlocale.h diff --git a/indra/llcommon/llfixedbuffer.cpp b/indra/llcommon/llfixedbuffer.cpp index d394f179fb..d394f179fb 100644..100755 --- a/indra/llcommon/llfixedbuffer.cpp +++ b/indra/llcommon/llfixedbuffer.cpp diff --git a/indra/llcommon/llfixedbuffer.h b/indra/llcommon/llfixedbuffer.h index 554cf48a4c..554cf48a4c 100644..100755 --- a/indra/llcommon/llfixedbuffer.h +++ b/indra/llcommon/llfixedbuffer.h diff --git a/indra/llcommon/llfoldertype.cpp b/indra/llcommon/llfoldertype.cpp index f6d0f5bce8..f6d0f5bce8 100644..100755 --- a/indra/llcommon/llfoldertype.cpp +++ b/indra/llcommon/llfoldertype.cpp diff --git a/indra/llcommon/llfoldertype.h b/indra/llcommon/llfoldertype.h index a0c847914f..a0c847914f 100644..100755 --- a/indra/llcommon/llfoldertype.h +++ b/indra/llcommon/llfoldertype.h diff --git a/indra/llcommon/llformat.cpp b/indra/llcommon/llformat.cpp index 3b2b3038ea..3b2b3038ea 100644..100755 --- a/indra/llcommon/llformat.cpp +++ b/indra/llcommon/llformat.cpp diff --git a/indra/llcommon/llformat.h b/indra/llcommon/llformat.h index a4ec5e01de..a4ec5e01de 100644..100755 --- a/indra/llcommon/llformat.h +++ b/indra/llcommon/llformat.h diff --git a/indra/llcommon/llframetimer.cpp b/indra/llcommon/llframetimer.cpp index ec64195b21..ec64195b21 100644..100755 --- a/indra/llcommon/llframetimer.cpp +++ b/indra/llcommon/llframetimer.cpp diff --git a/indra/llcommon/llframetimer.h b/indra/llcommon/llframetimer.h index 45754f3785..45754f3785 100644..100755 --- a/indra/llcommon/llframetimer.h +++ b/indra/llcommon/llframetimer.h diff --git a/indra/llcommon/llhandle.h b/indra/llcommon/llhandle.h index 6af5e198d6..401e4d759a 100644..100755 --- a/indra/llcommon/llhandle.h +++ b/indra/llcommon/llhandle.h @@ -194,13 +194,6 @@ public:  		return mHandle;   	} -protected: -	typedef LLHandle<T> handle_type_t; -	LLHandleProvider()  -	{ -		// provided here to enforce T deriving from LLHandleProvider<T> -	}  -  	template <typename U>  	LLHandle<U> getDerivedHandle(typename boost::enable_if< typename boost::is_convertible<U*, T*> >::type* dummy = 0) const  	{ @@ -209,6 +202,12 @@ protected:  		return downcast_handle;  	} +protected: +	typedef LLHandle<T> handle_type_t; +	LLHandleProvider()  +	{ +		// provided here to enforce T deriving from LLHandleProvider<T> +	}   private:  	mutable LLRootHandle<T> mHandle; diff --git a/indra/llcommon/llhash.h b/indra/llcommon/llhash.h index c077ebe93f..c077ebe93f 100644..100755 --- a/indra/llcommon/llhash.h +++ b/indra/llcommon/llhash.h diff --git a/indra/llcommon/llheartbeat.cpp b/indra/llcommon/llheartbeat.cpp index 18a0c489bd..18a0c489bd 100644..100755 --- a/indra/llcommon/llheartbeat.cpp +++ b/indra/llcommon/llheartbeat.cpp diff --git a/indra/llcommon/llheartbeat.h b/indra/llcommon/llheartbeat.h index 4a75fcc103..4a75fcc103 100644..100755 --- a/indra/llcommon/llheartbeat.h +++ b/indra/llcommon/llheartbeat.h diff --git a/indra/llcommon/llhttpstatuscodes.h b/indra/llcommon/llhttpstatuscodes.h index 0173461dad..0173461dad 100644..100755 --- a/indra/llcommon/llhttpstatuscodes.h +++ b/indra/llcommon/llhttpstatuscodes.h diff --git a/indra/llcommon/llindexedqueue.h b/indra/llcommon/llindexedqueue.h index aa2675d87d..aa2675d87d 100644..100755 --- a/indra/llcommon/llindexedqueue.h +++ b/indra/llcommon/llindexedqueue.h diff --git a/indra/llcommon/llinitparam.cpp b/indra/llcommon/llinitparam.cpp index db72aa19b9..89c831d296 100644..100755 --- a/indra/llcommon/llinitparam.cpp +++ b/indra/llcommon/llinitparam.cpp @@ -40,7 +40,9 @@ namespace LLInitParam  	{  		const U8* my_addr = reinterpret_cast<const U8*>(this);  		const U8* block_addr = reinterpret_cast<const U8*>(enclosing_block); -		mEnclosingBlockOffset = 0x7FFFffff & (U32)(my_addr - block_addr); +		U32 enclosing_block_offset = 0x7FFFffff & (U32)(my_addr - block_addr); +		mEnclosingBlockOffsetLow = enclosing_block_offset & 0x0000ffff; +		mEnclosingBlockOffsetHigh = (enclosing_block_offset & 0x007f0000) >> 16;  	}  	// @@ -112,6 +114,35 @@ namespace LLInitParam  		std::copy(src_block_data.mAllParams.begin(), src_block_data.mAllParams.end(), std::back_inserter(mAllParams));  	} +	void BlockDescriptor::addParam(const ParamDescriptorPtr in_param, const char* char_name) +	{ +		// create a copy of the param descriptor in mAllParams +		// so other data structures can store a pointer to it +		mAllParams.push_back(in_param); +		ParamDescriptorPtr param(mAllParams.back()); + +		std::string name(char_name); +		if ((size_t)param->mParamHandle > mMaxParamOffset) +		{ +			llerrs << "Attempted to register param with block defined for parent class, make sure to derive from LLInitParam::Block<YOUR_CLASS, PARAM_BLOCK_BASE_CLASS>" << llendl; +		} + +		if (name.empty()) +		{ +			mUnnamedParams.push_back(param); +		} +		else +		{ +			// don't use insert, since we want to overwrite existing entries +			mNamedParams[name] = param; +		} + +		if (param->mValidationFunc) +		{ +			mValidationList.push_back(std::make_pair(param->mParamHandle, param->mValidationFunc)); +		} +	} +  	BlockDescriptor::BlockDescriptor()  	:	mMaxParamOffset(0),  		mInitializationState(UNINITIALIZED), @@ -150,7 +181,8 @@ namespace LLInitParam  	bool BaseBlock::submitValue(Parser::name_stack_t& name_stack, Parser& p, bool silent)  	{ -		if (!deserializeBlock(p, std::make_pair(name_stack.begin(), name_stack.end()), true)) +		Parser::name_stack_range_t range = std::make_pair(name_stack.begin(), name_stack.end()); +		if (!deserializeBlock(p, range, true))  		{  			if (!silent)  			{ @@ -196,12 +228,7 @@ namespace LLInitParam  			if (serialize_func)  			{  				const Param* diff_param = diff_block ? diff_block->getParamFromHandle(param_handle) : NULL; -				// each param descriptor remembers its serial number -				// so we can inspect the same param under different names -				// and see that it has the same number -				name_stack.push_back(std::make_pair("", true));  				serialize_func(*param, parser, name_stack, diff_param); -				name_stack.pop_back();  			}  		} @@ -295,7 +322,7 @@ namespace LLInitParam  		return true;  	} -	bool BaseBlock::deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack_range, bool ignored) +	bool BaseBlock::deserializeBlock(Parser& p, Parser::name_stack_range_t& name_stack_range, bool ignored)  	{  		BlockDescriptor& block_data = mostDerivedBlockDescriptor();  		bool names_left = name_stack_range.first != name_stack_range.second; @@ -308,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; @@ -358,36 +382,6 @@ namespace LLInitParam  		return false;  	} -	//static  -	void BaseBlock::addParam(BlockDescriptor& block_data, const ParamDescriptorPtr in_param, const char* char_name) -	{ -		// create a copy of the param descriptor in mAllParams -		// so other data structures can store a pointer to it -		block_data.mAllParams.push_back(in_param); -		ParamDescriptorPtr param(block_data.mAllParams.back()); - -		std::string name(char_name); -		if ((size_t)param->mParamHandle > block_data.mMaxParamOffset) -		{ -			llerrs << "Attempted to register param with block defined for parent class, make sure to derive from LLInitParam::Block<YOUR_CLASS, PARAM_BLOCK_BASE_CLASS>" << llendl; -		} - -		if (name.empty()) -		{ -			block_data.mUnnamedParams.push_back(param); -		} -		else -		{ -			// don't use insert, since we want to overwrite existing entries -			block_data.mNamedParams[name] = param; -		} - -		if (param->mValidationFunc) -		{ -			block_data.mValidationList.push_back(std::make_pair(param->mParamHandle, param->mValidationFunc)); -		} -	} -  	void BaseBlock::addSynonym(Param& param, const std::string& synonym)  	{  		BlockDescriptor& block_data = mostDerivedBlockDescriptor(); @@ -460,7 +454,7 @@ namespace LLInitParam  			if (merge_func)  			{  				Param* paramp = getParamFromHandle((*it)->mParamHandle); -				llassert(paramp->mEnclosingBlockOffset == (*it)->mParamHandle); +				llassert(paramp->getEnclosingBlockOffset() == (*it)->mParamHandle);  				some_param_changed |= merge_func(*paramp, *other_paramp, overwrite);  			}  		} diff --git a/indra/llcommon/llinitparam.h b/indra/llcommon/llinitparam.h index 0dd6030fa2..ae836645b9 100644..100755 --- a/indra/llcommon/llinitparam.h +++ b/indra/llcommon/llinitparam.h @@ -38,6 +38,71 @@  #include "llerror.h"  #include "llstl.h" +namespace LLTypeTags +{ +	template <typename INNER_TYPE, int _SORT_ORDER> +	struct TypeTagBase +	{ +		typedef void		is_tag_t; +		typedef INNER_TYPE	inner_t; +		static const int	SORT_ORDER=_SORT_ORDER; +	}; + +	template <int VAL1, int VAL2> +	struct GreaterThan +	{ +		static const bool value = VAL1 > VAL2; +	}; + +	template<typename ITEM, typename REST, bool NEEDS_SWAP = GreaterThan<ITEM::SORT_ORDER, REST::SORT_ORDER>::value > +	struct Swap +	{ +		typedef typename ITEM::template Cons<REST>::value_t value_t; +	}; + +	template<typename ITEM, typename REST> +	struct Swap<ITEM, REST, true> +	{ +		typedef typename REST::template Cons<Swap<ITEM, typename REST::inner_t>::value_t>::value_t value_t; +	}; + +	template<typename T, typename SORTABLE = void> +	struct IsSortable +	{ +		static const bool value = false; +	}; + +	template<typename T> +	struct IsSortable<T, typename T::is_tag_t> +	{ +		static const bool value = true; +	}; + +	template<typename ITEM, typename REST, bool IS_REST_SORTABLE = IsSortable<REST>::value> +	struct InsertInto +	{ +		typedef typename ITEM::template Cons<REST>::value_t value_t; +	}; + +	template<typename ITEM, typename REST> +	struct InsertInto <ITEM, REST, true> +	{ +		typedef typename Swap<ITEM, REST>::value_t value_t; +	}; + +	template<typename T, bool SORTABLE = IsSortable<T>::value> +	struct Sorted +	{ +		typedef T value_t; +	}; + +	template<typename T> +	struct Sorted <T, true> +	{ +		typedef typename InsertInto<T, typename Sorted<typename T::inner_t>::value_t>::value_t value_t; +	}; +} +  namespace LLInitParam  {  	// used to indicate no matching value to a given name when parsing @@ -45,6 +110,8 @@ namespace LLInitParam  	template<typename T> const T& defaultValue() { static T value; return value; } +	// wraps comparison operator between any 2 values of the same type +	// specialize to handle cases where equality isn't defined well, or at all  	template <typename T, bool IS_BOOST_FUNCTION = boost::is_convertible<T, boost::function_base>::value >      struct ParamCompare   	{ @@ -79,24 +146,123 @@ namespace LLInitParam  	// helper functions and classes  	typedef ptrdiff_t param_handle_t; +	struct IS_A_BLOCK {}; +	struct NOT_BLOCK {}; + +	// these templates allow us to distinguish between template parameters +	// that derive from BaseBlock and those that don't +	template<typename T, typename BLOCK_IDENTIFIER = void> +	struct IsBlock +	{ +		typedef NOT_BLOCK value_t; +	}; + +	template<typename T> +	struct IsBlock<T, typename T::baseblock_base_class_t> +	{ +		typedef IS_A_BLOCK value_t; +	}; + +	// ParamValue class directly manages the wrapped value +	// by holding on to a copy (scalar params) +	// or deriving from it (blocks) +	// has specializations for custom value behavior +	// and "tag" values like Lazy and Atomic +	template<typename T, typename VALUE_IS_BLOCK = typename IsBlock<T>::value_t> +	class ParamValue +	{ +		typedef ParamValue<T, VALUE_IS_BLOCK>	self_t; + +	public: +		typedef T	default_value_t; +		typedef T	value_t; + +		ParamValue(): mValue() {} +		ParamValue(const default_value_t& other) : mValue(other) {} + +		void setValue(const value_t& val) +		{ +			mValue = val; +		} + +		const value_t& getValue() const +		{ +			return mValue; +		} + +		T& getValue() +		{ +			return mValue; +		} + +	protected: +		T mValue; +	}; + +	template<typename T> +	class ParamValue<T, IS_A_BLOCK>  +	:	public T +	{ +		typedef ParamValue<T, IS_A_BLOCK>	self_t; +	public: +		typedef T	default_value_t; +		typedef T	value_t; + +		ParamValue()  +		:	T(), +			mValidated(false) +		{} + +		ParamValue(const default_value_t& other) +		:	T(other), +			mValidated(false) +		{} + +		void setValue(const value_t& val) +		{ +			*this = val; +		} + +		const value_t& getValue() const +		{ +			return *this; +		} + +		T& getValue() +		{ +			return *this; +		} + +	protected: +		mutable bool 	mValidated; // lazy validation flag +	}; +  	// empty default implementation of key cache  	// leverages empty base class optimization  	template <typename T>  	class TypeValues +	:	public ParamValue<typename LLTypeTags::Sorted<T>::value_t>  	{  	private:  		struct Inaccessable{};  	public:  		typedef std::map<std::string, T> value_name_map_t;  		typedef Inaccessable name_t; +		typedef TypeValues<T> type_value_t; +		typedef ParamValue<typename LLTypeTags::Sorted<T>::value_t>	param_value_t; +		typedef typename param_value_t::value_t	value_t; + +		TypeValues(const typename param_value_t::value_t& val) +		:	param_value_t(val) +		{}  		void setValueName(const std::string& key) {}  		std::string getValueName() const { return ""; } -		std::string calcValueName(const T& value) const { return ""; } +		std::string calcValueName(const value_t& value) const { return ""; }  		void clearValueName() const {} -		static bool getValueFromName(const std::string& name, T& value) +		static bool getValueFromName(const std::string& name, value_t& value)  		{  			return false;  		} @@ -111,15 +277,39 @@ namespace LLInitParam  			return NULL;  		} +		void assignNamedValue(const Inaccessable& name) +		{} + +		operator const value_t&() const +		{ +			return param_value_t::getValue(); +		} + +		const value_t& operator()() const +		{ +			return param_value_t::getValue(); +		} +  		static value_name_map_t* getValueNames() {return NULL;}  	}; -	template <typename T, typename DERIVED_TYPE = TypeValues<T> > +	// helper class to implement name value lookups +	// and caching of last used name +	template <typename T, typename DERIVED_TYPE = TypeValues<T>, bool IS_SPECIALIZED = true >  	class TypeValuesHelper +	:	public ParamValue<typename LLTypeTags::Sorted<T>::value_t>  	{ +		typedef TypeValuesHelper<T, DERIVED_TYPE, IS_SPECIALIZED> self_t;  	public:  		typedef typename std::map<std::string, T> value_name_map_t;  		typedef std::string name_t; +		typedef self_t type_value_t; +		typedef ParamValue<typename LLTypeTags::Sorted<T>::value_t> param_value_t; +		typedef typename param_value_t::value_t	value_t; + +		TypeValuesHelper(const typename param_value_t::value_t& val) +		:	param_value_t(val) +		{}  		//TODO: cache key by index to save on param block size  		void setValueName(const std::string& value_name)  @@ -132,7 +322,7 @@ namespace LLInitParam  			return mValueName;   		} -		std::string calcValueName(const T& value) const +		std::string calcValueName(const value_t& value) const  		{  			value_name_map_t* map = getValueNames();  			for (typename value_name_map_t::iterator it = map->begin(), end_it = map->end(); @@ -153,7 +343,7 @@ namespace LLInitParam  			mValueName.clear();  		} -		static bool getValueFromName(const std::string& name, T& value) +		static bool getValueFromName(const std::string& name, value_t& value)  		{  			value_name_map_t* map = getValueNames();  			typename value_name_map_t::iterator found_it = map->find(name); @@ -195,18 +385,90 @@ namespace LLInitParam  			return &sValues;  		} -		static void declare(const std::string& name, const T& value) +		static void declare(const std::string& name, const value_t& value)  		{  			(*getValueNames())[name] = value;  		} +		void operator ()(const std::string& name) +		{ +			*this = name; +		} + +		void assignNamedValue(const std::string& name) +		{ +			if (getValueFromName(name, param_value_t::getValue())) +			{ +				setValueName(name); +			} +		} + +		operator const value_t&() const +		{ +			return param_value_t::getValue(); +		} + +		const value_t& operator()() const +		{ +			return param_value_t::getValue(); +		} +  	protected: -		static void getName(const std::string& name, const T& value) +		static void getName(const std::string& name, const value_t& value)  		{}  		mutable std::string	mValueName;  	}; +	// string types can support custom named values, but need +	// to disambiguate in code between a string that is a named value +	// and a string that is a name +	template <typename DERIVED_TYPE> +	class TypeValuesHelper<std::string, DERIVED_TYPE, true> +	:	public TypeValuesHelper<std::string, DERIVED_TYPE, false> +	{ +	public: +		typedef TypeValuesHelper<std::string, DERIVED_TYPE, true> self_t; +		typedef TypeValuesHelper<std::string, DERIVED_TYPE, false> base_t; +		typedef std::string value_t; +		typedef std::string name_t; +		typedef self_t type_value_t; + +		TypeValuesHelper(const std::string& val) +		:	TypeValuesHelper(val) +		{} + +		void operator ()(const std::string& name) +	{ +			*this = name; +		} + +		self_t& operator =(const std::string& name) +		{ +			if (base_t::getValueFromName(name, ParamValue<std::string>::getValue())) +			{ +				base_t::setValueName(name); +			} +			else +			{ +				ParamValue<std::string>::setValue(name); +			} +			return *this; +		} +		 +		operator const value_t&() const +		{ +			return ParamValue<std::string>::getValue(); +		} + +		const value_t& operator()() const +		{ +			return ParamValue<std::string>::getValue(); +		} + +	}; + +	// parser base class with mechanisms for registering readers/writers/inspectors of different types  	class LL_COMMON_API Parser  	{  		LOG_CLASS(Parser); @@ -223,82 +485,58 @@ namespace LLInitParam  		typedef std::map<const std::type_info*, parser_write_func_t>	parser_write_func_map_t;  		typedef std::map<const std::type_info*, parser_inspect_func_t>	parser_inspect_func_map_t; -	private: -		template<typename T, bool is_enum = boost::is_enum<T>::value> -		struct ReaderWriter -		{ -			static bool read(T& param, Parser* parser) +	public: + +		Parser(parser_read_func_map_t& read_map, parser_write_func_map_t& write_map, parser_inspect_func_map_t& inspect_map) +		:	mParseSilently(false), +			mParserReadFuncs(&read_map), +			mParserWriteFuncs(&write_map), +			mParserInspectFuncs(&inspect_map) +		{} + +		virtual ~Parser(); + +		template <typename T> bool readValue(T& param, typename boost::disable_if<boost::is_enum<T> >::type* dummy = 0)  			{ -				parser_read_func_map_t::iterator found_it = parser->mParserReadFuncs->find(&typeid(T)); -				if (found_it != parser->mParserReadFuncs->end()) +			parser_read_func_map_t::iterator found_it = mParserReadFuncs->find(&typeid(T)); +			if (found_it != mParserReadFuncs->end())  				{ -					return found_it->second(*parser, (void*)¶m); +				return found_it->second(*this, (void*)¶m);  				} +			  				return false;  			} -			static bool write(const T& param, Parser* parser, name_stack_t& name_stack) +		template <typename T> bool readValue(T& param, typename boost::enable_if<boost::is_enum<T> >::type* dummy = 0)  			{ -				parser_write_func_map_t::iterator found_it = parser->mParserWriteFuncs->find(&typeid(T)); -				if (found_it != parser->mParserWriteFuncs->end()) +			parser_read_func_map_t::iterator found_it = mParserReadFuncs->find(&typeid(T)); +			if (found_it != mParserReadFuncs->end())  				{ -					return found_it->second(*parser, (const void*)¶m, name_stack); +				return found_it->second(*this, (void*)¶m);  				} -				return false; -			} -		}; - -		// read enums as ints -		template<typename T> -		struct ReaderWriter<T, true> +			else  		{ -			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()) +				found_it = mParserReadFuncs->find(&typeid(S32)); +				if (found_it != mParserReadFuncs->end())  				{ -					S32 value; -					if (found_it->second(*parser, (void*)&value)) -					{ -						param = (T)value; -						return true; +					S32 int_value; +					bool parsed = found_it->second(*this, (void*)&int_value); +					param = (T)int_value; +					return parsed;  					}  				}  				return false;  			} -			static bool write(const T& param, Parser* parser, name_stack_t& name_stack) +		template <typename T> bool writeValue(const T& param, name_stack_t& name_stack)  			{ -				parser_write_func_map_t::iterator found_it = parser->mParserWriteFuncs->find(&typeid(S32)); -				if (found_it != parser->mParserWriteFuncs->end()) +			parser_write_func_map_t::iterator found_it = mParserWriteFuncs->find(&typeid(T)); +			if (found_it != mParserWriteFuncs->end())  				{ -					return found_it->second(*parser, (const void*)¶m, name_stack); +				return found_it->second(*this, (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) -		:	mParseSilently(false), -			mParserReadFuncs(&read_map), -			mParserWriteFuncs(&write_map), -			mParserInspectFuncs(&inspect_map) -		{} - -		virtual ~Parser(); - -		template <typename T> bool readValue(T& param) -	    { -			return ReaderWriter<T>::read(param, this); -	    } - -		template <typename T> bool writeValue(const T& param, name_stack_t& name_stack) -		{ -			return ReaderWriter<T>::write(param, this, name_stack); -		}  		// dispatch inspection to registered inspection functions, for each parameter in a param block  		template <typename T> bool inspectValue(name_stack_t& name_stack, S32 min_count, S32 max_count, const possible_values_t* possible_values) @@ -350,7 +588,7 @@ namespace LLInitParam  		};  		typedef bool(*merge_func_t)(Param&, const Param&, bool); -		typedef bool(*deserialize_func_t)(Param&, Parser&, const Parser::name_stack_range_t&, bool); +		typedef bool(*deserialize_func_t)(Param&, Parser&, Parser::name_stack_range_t&, bool);  		typedef void(*serialize_func_t)(const Param&, Parser&, Parser::name_stack_t&, const Param* diff_param);  		typedef void(*inspect_func_t)(const Param&, Parser&, Parser::name_stack_t&, S32 min_count, S32 max_count);  		typedef bool(*validation_func_t)(const Param*); @@ -395,6 +633,7 @@ namespace LLInitParam  		} EInitializationState;  		void aggregateBlockData(BlockDescriptor& src_block_data); +		void addParam(ParamDescriptorPtr param, const char* name);  		typedef boost::unordered_map<const std::string, ParamDescriptorPtr>						param_map_t;   		typedef std::vector<ParamDescriptorPtr>													param_list_t;  @@ -410,48 +649,58 @@ namespace LLInitParam  		class BaseBlock*				mCurrentBlockPtr;		// pointer to block currently being constructed  	}; -	class LL_COMMON_API BaseBlock -	{ -	public:  		//TODO: implement in terms of owned_ptr  		template<typename T> -		class Lazy +	class LazyValue  		{  		public: -			Lazy() +		LazyValue()  				: mPtr(NULL)  			{} -			~Lazy() +		~LazyValue()  			{  				delete mPtr;  			} -			Lazy(const Lazy& other) +		LazyValue(const T& value)  			{ -				if (other.mPtr) +			mPtr = new T(value); +		} + +		LazyValue(const LazyValue& other) +		:	mPtr(NULL)  				{ -					mPtr = new T(*other.mPtr); +			*this = other;  				} -				else + +		LazyValue& operator = (const LazyValue& other)  				{ +			if (!other.mPtr) +			{ +				delete mPtr;  					mPtr = NULL;  				} -			} - -			Lazy<T>& operator = (const Lazy<T>& other) +			else  			{ -				if (other.mPtr) +				if (!mPtr)  				{  					mPtr = new T(*other.mPtr);  				}  				else  				{ -					mPtr = NULL; +					*mPtr = *(other.mPtr); +				}  				}  				return *this;  			} +		bool operator==(const LazyValue& other) const +		{ +			if (empty() || other.empty()) return false; +			return *mPtr == *other.mPtr; +		} +  			bool empty() const  			{  				return mPtr == NULL; @@ -459,18 +708,29 @@ namespace LLInitParam  			void set(const T& other)  			{ -				delete mPtr; +			if (!mPtr) +			{  				mPtr = new T(other);  			} +			else +			{ +				*mPtr = other; +			} +		}  			const T& get() const  			{ -				return ensureInstance(); +			return *ensureInstance();  			}  			T& get()  			{ -				return ensureInstance(); +			return *ensureInstance(); +		} + +		operator const T&() const +		{  +			return get();   			}  		private: @@ -485,13 +745,50 @@ namespace LLInitParam  			}  		private: -			// if you get a compilation error with this, that means you are using a forward declared struct for T -			// unfortunately, the type traits we rely on don't work with forward declared typed -			//static const int dummy = sizeof(T);  			mutable T* mPtr;  		}; +	// root class of all parameter blocks + +	class LL_COMMON_API BaseBlock +	{ +	public: +		// lift block tags into baseblock namespace so derived classes do not need to qualify them +		typedef LLInitParam::IS_A_BLOCK IS_A_BLOCK; +		typedef LLInitParam::NOT_BLOCK NOT_A_BLOCK; + +		template<typename T> +		struct Sequential : public LLTypeTags::TypeTagBase<T, 2> +		{ +			template <typename S> struct Cons { typedef Sequential<ParamValue<S> > value_t; }; +			template <typename S> struct Cons<Sequential<S> > { typedef Sequential<S> value_t; }; +		}; + +		template<typename T> +		struct Atomic : public LLTypeTags::TypeTagBase<T, 1> +		{ +			template <typename S> struct Cons { typedef Atomic<ParamValue<S> > value_t; }; +			template <typename S> struct Cons<Atomic<S> > { typedef Atomic<S> value_t; }; +		}; + +		template<typename T, typename BLOCK_T = typename IsBlock<T>::value_t > +		struct Lazy : public LLTypeTags::TypeTagBase<T, 0> +		{ +			template <typename S> struct Cons +			{ +				typedef Lazy<ParamValue<S, BLOCK_T>, BLOCK_T> value_t; +			}; +			template <typename S> struct Cons<Lazy<S, IS_A_BLOCK> > +			{ +				typedef Lazy<S, IS_A_BLOCK> value_t; +			}; +			template <typename S> struct Cons<Lazy<S, NOT_A_BLOCK> > +			{ +				typedef Lazy<S, BLOCK_T> value_t; +			}; +		}; +  		// "Multiple" constraint types, put here in root class to avoid ambiguity during use  		struct AnyAmount  		{ @@ -557,12 +854,12 @@ namespace LLInitParam  		// Blocks can override this to do custom tracking of changes  		virtual void paramChanged(const Param& changed_param, bool user_provided) {} -		bool deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack_range, bool new_name); +		bool deserializeBlock(Parser& p, Parser::name_stack_range_t& name_stack_range, bool new_name);  		void serializeBlock(Parser& p, Parser::name_stack_t& name_stack, const BaseBlock* diff_block = NULL) const;  		bool inspectBlock(Parser& p, Parser::name_stack_t name_stack = Parser::name_stack_t(), S32 min_count = 0, S32 max_count = S32_MAX) const; -		virtual const BlockDescriptor& mostDerivedBlockDescriptor() const { return selfBlockDescriptor(); } -		virtual BlockDescriptor& mostDerivedBlockDescriptor() { return selfBlockDescriptor(); } +		virtual const BlockDescriptor& mostDerivedBlockDescriptor() const { return getBlockDescriptor(); } +		virtual BlockDescriptor& mostDerivedBlockDescriptor() { return getBlockDescriptor(); }  		// take all provided params from other and apply to self  		bool overwriteFrom(const BaseBlock& other) @@ -576,10 +873,17 @@ namespace LLInitParam  			return false;  		} -		static void addParam(BlockDescriptor& block_data, ParamDescriptorPtr param, const char* name); -  		ParamDescriptorPtr findParamDescriptor(const Param& param); +		// take all provided params from other and apply to self +		bool mergeBlock(BlockDescriptor& block_data, const BaseBlock& other, bool overwrite); + +		static BlockDescriptor& getBlockDescriptor() +		{ +			static BlockDescriptor sBlockDescriptor; +			return sBlockDescriptor; +		} +  	protected:  		void init(BlockDescriptor& descriptor, BlockDescriptor& base_descriptor, size_t block_size); @@ -588,25 +892,11 @@ namespace LLInitParam  		{  			return mergeBlock(block_data, source, overwrite);  		} -		// take all provided params from other and apply to self -		bool mergeBlock(BlockDescriptor& block_data, const BaseBlock& other, bool overwrite); - -		static BlockDescriptor& selfBlockDescriptor() -		{ -			static BlockDescriptor sBlockDescriptor; -			return sBlockDescriptor; -		}  	private:  		const std::string& getParamName(const BlockDescriptor& block_data, const Param* paramp) const;  	}; -	template<typename T> -	struct ParamCompare<BaseBlock::Lazy<T>, false > -	{ -		static bool equals(const BaseBlock::Lazy<T>& a, const BaseBlock::Lazy<T>& b) { return !a.empty() || !b.empty(); } -	}; -  	class LL_COMMON_API Param  	{  	public: @@ -635,256 +925,68 @@ namespace LLInitParam  			// get address of enclosing BLOCK class using stored offset to enclosing BaseBlock class  			return *const_cast<BaseBlock*>  				(reinterpret_cast<const BaseBlock*> -					(my_addr - (ptrdiff_t)(S32)mEnclosingBlockOffset)); -		} - -	private: -		friend class BaseBlock; - -		U32		mEnclosingBlockOffset:31; -		U32		mIsProvided:1; - -	}; - -	// these templates allow us to distinguish between template parameters -	// that derive from BaseBlock and those that don't -	template<typename T, typename Void = void> -	struct IsBlock -	{ -		static const bool value = false; -		struct EmptyBase {}; -		typedef EmptyBase base_class_t; -	}; - -	template<typename T> -	struct IsBlock<T, typename T::baseblock_base_class_t> -	{ -		static const bool value = true; -		typedef BaseBlock base_class_t; -	}; - -	template<typename T> -	struct IsBlock<BaseBlock::Lazy<T>, typename T::baseblock_base_class_t > -	{ -		static const bool value = true; -		typedef BaseBlock base_class_t; -	}; - -	template<typename T, typename NAME_VALUE_LOOKUP, bool VALUE_IS_BLOCK = IsBlock<T>::value> -	class ParamValue : public NAME_VALUE_LOOKUP -	{ -	public: -		typedef const T&							value_assignment_t; -		typedef T									value_t; -		typedef ParamValue<T, NAME_VALUE_LOOKUP, VALUE_IS_BLOCK>	self_t; - -		ParamValue(): mValue() {} -		ParamValue(value_assignment_t other) : mValue(other) {} - -		void setValue(value_assignment_t val) -		{ -			mValue = val; -		} - -		value_assignment_t getValue() const -		{ -			return mValue; -		} - -		T& getValue() -		{ -			return mValue; -		} - -		operator value_assignment_t() const -		{ -			return mValue; -		} - -		value_assignment_t operator()() const -		{ -			return mValue; -		} - -		void operator ()(const typename NAME_VALUE_LOOKUP::name_t& name) -		{ -			*this = name; -		} - -		self_t& operator =(const typename NAME_VALUE_LOOKUP::name_t& name) -		{ -			if (NAME_VALUE_LOOKUP::getValueFromName(name, mValue)) -			{ -				setValueName(name); -			} - -			return *this; -		} - -	protected: -		T mValue; -	}; - -	template<typename T, typename NAME_VALUE_LOOKUP> -	class ParamValue<T, NAME_VALUE_LOOKUP, true>  -	:	public T, -		public NAME_VALUE_LOOKUP -	{ -	public: -		typedef const T&							value_assignment_t; -		typedef T									value_t; -		typedef ParamValue<T, NAME_VALUE_LOOKUP, true>	self_t; - -		ParamValue()  -		:	T(), -			mValidated(false) -		{} - -		ParamValue(value_assignment_t other) -		:	T(other), -			mValidated(false) -		{} - -		void setValue(value_assignment_t val) -		{ -			*this = val; -		} - -		value_assignment_t getValue() const -		{ -			return *this; -		} - -		T& getValue() -		{ -			return *this; -		} - -		operator value_assignment_t() const -		{ -			return *this; -		} -		 -		value_assignment_t operator()() const -		{ -			return *this; -		} - -		void operator ()(const typename NAME_VALUE_LOOKUP::name_t& name) -		{ -			*this = name; -		} - -		self_t& operator =(const typename NAME_VALUE_LOOKUP::name_t& name) -		{ -			if (NAME_VALUE_LOOKUP::getValueFromName(name, *this)) -			{ -				setValueName(name); -			} - -			return *this; +					(my_addr - (ptrdiff_t)getEnclosingBlockOffset()));  		} -	protected: -		mutable bool 	mValidated; // lazy validation flag -	}; - -	template<typename NAME_VALUE_LOOKUP> -	class ParamValue<std::string, NAME_VALUE_LOOKUP, false> -	: public NAME_VALUE_LOOKUP +		U32 getEnclosingBlockOffset() const  	{ -	public: -		typedef const std::string&	value_assignment_t; -		typedef std::string			value_t; -		typedef ParamValue<std::string, NAME_VALUE_LOOKUP, false>	self_t; - -		ParamValue(): mValue() {} -		ParamValue(value_assignment_t other) : mValue(other) {} - -		void setValue(value_assignment_t val) -		{ -			if (NAME_VALUE_LOOKUP::getValueFromName(val, mValue)) -			{ -				NAME_VALUE_LOOKUP::setValueName(val); -			} -			else -			{ -				mValue = val; -			} -		} - -		value_assignment_t getValue() const -		{ -			return mValue; -		} - -		std::string& getValue() -		{ -			return mValue; +			return ((U32)mEnclosingBlockOffsetHigh << 16) | (U32)mEnclosingBlockOffsetLow;  		} -		operator value_assignment_t() const -		{ -			return mValue; -		} +	private: +		friend class BaseBlock; -		value_assignment_t operator()() const -		{ -			return mValue; -		} +		//24 bits for member offset field and 1 bit for provided flag +		U16		mEnclosingBlockOffsetLow; +		U8		mEnclosingBlockOffsetHigh:7; +		U8		mIsProvided:1; -	protected: -		std::string mValue;  	}; -  	template<typename T, typename NAME_VALUE_LOOKUP = TypeValues<T> >  	struct ParamIterator  	{ -		typedef typename std::vector<ParamValue<T, NAME_VALUE_LOOKUP> >::const_iterator		const_iterator; -		typedef typename std::vector<ParamValue<T, NAME_VALUE_LOOKUP> >::iterator			iterator; +		typedef typename std::vector<typename NAME_VALUE_LOOKUP::type_value_t >::const_iterator	const_iterator; +		typedef typename std::vector<typename NAME_VALUE_LOOKUP::type_value_t >::iterator			iterator;  	}; -	// specialize for custom parsing/decomposition of specific classes -	// e.g. TypedParam<LLRect> has left, top, right, bottom, etc... +	// wrapper for parameter with a known type +	// specialized to handle 4 cases: +	// simple "scalar" value +	// parameter that is itself a block +	// multiple scalar values, stored in a vector +	// multiple blocks, stored in a vector  	template<typename	T,  			typename	NAME_VALUE_LOOKUP = TypeValues<T>,  			bool		HAS_MULTIPLE_VALUES = false, -			bool		VALUE_IS_BLOCK = IsBlock<ParamValue<T, NAME_VALUE_LOOKUP> >::value> +			typename	VALUE_IS_BLOCK = typename IsBlock<ParamValue<typename LLTypeTags::Sorted<T>::value_t> >::value_t>  	class TypedParam   	:	public Param,  -		public ParamValue<T, NAME_VALUE_LOOKUP> +		public NAME_VALUE_LOOKUP::type_value_t  	{ +	protected: +		typedef	TypedParam<T, NAME_VALUE_LOOKUP, HAS_MULTIPLE_VALUES, VALUE_IS_BLOCK>	self_t; +		typedef ParamValue<typename LLTypeTags::Sorted<T>::value_t>						param_value_t; +		typedef typename param_value_t::default_value_t									default_value_t; +		typedef typename NAME_VALUE_LOOKUP::type_value_t								named_value_t;  	public: -		typedef	TypedParam<T, NAME_VALUE_LOOKUP, HAS_MULTIPLE_VALUES, VALUE_IS_BLOCK>		self_t; -		typedef ParamValue<T, NAME_VALUE_LOOKUP>											param_value_t; -		typedef typename param_value_t::value_assignment_t				value_assignment_t; -		typedef NAME_VALUE_LOOKUP															name_value_lookup_t; +		typedef typename param_value_t::value_t											value_t; -		using param_value_t::operator(); +		using named_value_t::operator(); -		TypedParam(BlockDescriptor& block_descriptor, const char* name, value_assignment_t value, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count)  -		:	Param(block_descriptor.mCurrentBlockPtr) +		TypedParam(BlockDescriptor& block_descriptor, const char* name, const default_value_t& value, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count) +		:	Param(block_descriptor.mCurrentBlockPtr), +			named_value_t(value)  		{  			if (LL_UNLIKELY(block_descriptor.mInitializationState == BlockDescriptor::INITIALIZING))  			{ - 				ParamDescriptorPtr param_descriptor = ParamDescriptorPtr(new ParamDescriptor( -												block_descriptor.mCurrentBlockPtr->getHandleFromParam(this), -												&mergeWith, -												&deserializeParam, -												&serializeParam, -												validate_func, -												&inspectParam, -												min_count, max_count)); -				BaseBlock::addParam(block_descriptor, param_descriptor, name); +				init(block_descriptor, validate_func, min_count, max_count, name);  			} - -			setValue(value);  		}   		bool isProvided() const { return Param::anyProvided(); } -		static bool deserializeParam(Param& param, Parser& parser, const Parser::name_stack_range_t& name_stack_range, bool new_name) +		static bool deserializeParam(Param& param, Parser& parser, Parser::name_stack_range_t& name_stack_range, bool new_name)  		{   			self_t& typed_param = static_cast<self_t&>(param);  			// no further names in stack, attempt to parse value now @@ -893,9 +995,9 @@ namespace LLInitParam  				std::string name;  				// try to parse a known named value -				if(name_value_lookup_t::valueNamesExist() +				if(named_value_t::valueNamesExist()  					&& parser.readValue(name) -					&& name_value_lookup_t::getValueFromName(name, typed_param.getValue())) +					&& named_value_t::getValueFromName(name, typed_param.getValue()))  				{  					typed_param.setValueName(name);  					typed_param.setProvided(); @@ -939,7 +1041,9 @@ namespace LLInitParam  				if (!parser.writeValue(typed_param.getValue(), name_stack))   				{  					std::string calculated_key = typed_param.calcValueName(typed_param.getValue()); -					if (!diff_param || !ParamCompare<std::string>::equals(static_cast<const self_t*>(diff_param)->getValueName(), calculated_key)) +					if (calculated_key.size()  +						&& (!diff_param  +							|| !ParamCompare<std::string>::equals(static_cast<const self_t*>(diff_param)->getValueName(), calculated_key)))  					{  						parser.writeValue(calculated_key, name_stack);  					} @@ -952,22 +1056,23 @@ namespace LLInitParam  			// tell parser about our actual type  			parser.inspectValue<T>(name_stack, min_count, max_count, NULL);  			// then tell it about string-based alternatives ("red", "blue", etc. for LLColor4) -			if (name_value_lookup_t::getPossibleValues()) +			if (named_value_t::getPossibleValues())  			{ -				parser.inspectValue<std::string>(name_stack, min_count, max_count, name_value_lookup_t::getPossibleValues()); +				parser.inspectValue<std::string>(name_stack, min_count, max_count, named_value_t::getPossibleValues());  			}  		} -		void set(value_assignment_t val, bool flag_as_provided = true) +		void set(const value_t& val, bool flag_as_provided = true)  		{ -			param_value_t::clearValueName(); +			named_value_t::clearValueName();  			setValue(val);  			setProvided(flag_as_provided);  		} -		self_t& operator =(const typename NAME_VALUE_LOOKUP::name_t& name) +		self_t& operator =(const typename named_value_t::name_t& name)  		{ -			return static_cast<self_t&>(param_value_t::operator =(name)); +			named_value_t::assignNamedValue(name); +			return *this;  		}  	protected: @@ -992,41 +1097,47 @@ namespace LLInitParam  			}  			return false;  		} +	private: +		void init( BlockDescriptor &block_descriptor, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count, const char* name )  +		{ +			ParamDescriptorPtr param_descriptor = ParamDescriptorPtr(new ParamDescriptor( +				block_descriptor.mCurrentBlockPtr->getHandleFromParam(this), +				&mergeWith, +				&deserializeParam, +				&serializeParam, +				validate_func, +				&inspectParam, +				min_count, max_count)); +			block_descriptor.addParam(param_descriptor, name); +		}  	};  	// parameter that is a block  	template <typename T, typename NAME_VALUE_LOOKUP> -	class TypedParam<T, NAME_VALUE_LOOKUP, false, true>  +	class TypedParam<T, NAME_VALUE_LOOKUP, false, IS_A_BLOCK>   	:	public Param, -		public ParamValue<T, NAME_VALUE_LOOKUP> +		public NAME_VALUE_LOOKUP::type_value_t  	{ +	protected: +		typedef ParamValue<typename LLTypeTags::Sorted<T>::value_t>	param_value_t; +		typedef typename param_value_t::default_value_t				default_value_t; +		typedef TypedParam<T, NAME_VALUE_LOOKUP, false, IS_A_BLOCK>	self_t; +		typedef typename NAME_VALUE_LOOKUP::type_value_t			named_value_t;  	public: -		typedef ParamValue<T, NAME_VALUE_LOOKUP>				param_value_t; -		typedef typename param_value_t::value_assignment_t		value_assignment_t; -		typedef TypedParam<T, NAME_VALUE_LOOKUP, false, true>	self_t; -		typedef NAME_VALUE_LOOKUP								name_value_lookup_t; - -		using param_value_t::operator(); +		using named_value_t::operator(); +		typedef typename param_value_t::value_t						value_t; -		TypedParam(BlockDescriptor& block_descriptor, const char* name, value_assignment_t value, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count) +		TypedParam(BlockDescriptor& block_descriptor, const char* name, const default_value_t& value, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count)  		:	Param(block_descriptor.mCurrentBlockPtr), -			param_value_t(value) +			named_value_t(value)  		{  			if (LL_UNLIKELY(block_descriptor.mInitializationState == BlockDescriptor::INITIALIZING))  			{ -				ParamDescriptorPtr param_descriptor = ParamDescriptorPtr(new ParamDescriptor( -												block_descriptor.mCurrentBlockPtr->getHandleFromParam(this), -												&mergeWith, -												&deserializeParam, -												&serializeParam, -												validate_func,  -												&inspectParam, -												min_count, max_count)); -				BaseBlock::addParam(block_descriptor, param_descriptor, name); +				init(block_descriptor, validate_func, min_count, max_count, name);  			}  		} -		static bool deserializeParam(Param& param, Parser& parser, const Parser::name_stack_range_t& name_stack_range, bool new_name) +		static bool deserializeParam(Param& param, Parser& parser, Parser::name_stack_range_t& name_stack_range, bool new_name)  		{   			self_t& typed_param = static_cast<self_t&>(param); @@ -1034,9 +1145,9 @@ namespace LLInitParam  			{	// try to parse a known named value  				std::string name; -				if(name_value_lookup_t::valueNamesExist() +				if(named_value_t::valueNamesExist()  					&& parser.readValue(name)				 -					&& name_value_lookup_t::getValueFromName(name, typed_param.getValue())) +					&& named_value_t::getValueFromName(name, typed_param.getValue()))  				{  					typed_param.setValueName(name);  					typed_param.setProvided(); @@ -1068,9 +1179,9 @@ namespace LLInitParam  			std::string key = typed_param.getValueName();  			if (!key.empty())  			{ -				if (!parser.writeValue(key, name_stack)) +				if (!diff_param || !ParamCompare<std::string>::equals(static_cast<const self_t*>(diff_param)->getValueName(), key))  				{ -					return; +					parser.writeValue(key, name_stack);  				}  			}  			else @@ -1081,8 +1192,16 @@ namespace LLInitParam  		static void inspectParam(const Param& param, Parser& parser, Parser::name_stack_t& name_stack, S32 min_count, S32 max_count)  		{ -			// I am a param that is also a block, so just recurse into my contents  			const self_t& typed_param = static_cast<const self_t&>(param); + +			// tell parser about our actual type +			parser.inspectValue<value_t>(name_stack, min_count, max_count, NULL); +			// then tell it about string-based alternatives ("red", "blue", etc. for LLColor4) +			if (named_value_t::getPossibleValues()) +			{ +				parser.inspectValue<std::string>(name_stack, min_count, max_count, named_value_t::getPossibleValues()); +			} +  			typed_param.inspectBlock(parser, name_stack, min_count, max_count);  		} @@ -1100,32 +1219,34 @@ namespace LLInitParam  		}  		// assign block contents to this param-that-is-a-block -		void set(value_assignment_t val, bool flag_as_provided = true) +		void set(const value_t& val, bool flag_as_provided = true)  		{  			setValue(val); -			param_value_t::clearValueName(); +			named_value_t::clearValueName();  			// force revalidation of block  			// next call to isProvided() will update provision status based on validity  			param_value_t::mValidated = false;  			setProvided(flag_as_provided);  		} -		self_t& operator =(const typename NAME_VALUE_LOOKUP::name_t& name) +		self_t& operator =(const typename named_value_t::name_t& name)  		{ -			return static_cast<self_t&>(param_value_t::operator =(name)); +			named_value_t::assignNamedValue(name); +			return *this;  		}  		// propagate changed status up to enclosing block  		/*virtual*/ void paramChanged(const Param& changed_param, bool user_provided)  		{   			param_value_t::paramChanged(changed_param, user_provided); +  			if (user_provided)  			{  				// a child param has been explicitly changed  				// so *some* aspect of this block is now provided  				param_value_t::mValidated = false;  				setProvided(); -				param_value_t::clearValueName(); +				named_value_t::clearValueName();  			}  			else  			{ @@ -1149,7 +1270,7 @@ namespace LLInitParam  			if (src_typed_param.anyProvided())  			{ -				if (dst_typed_param.mergeBlockParam(src_typed_param.isProvided(), dst_typed_param.isProvided(), param_value_t::selfBlockDescriptor(), src_typed_param, overwrite)) +				if (dst_typed_param.mergeBlockParam(src_typed_param.isProvided(), dst_typed_param.isProvided(), param_value_t::getBlockDescriptor(), src_typed_param, overwrite))  				{  					dst_typed_param.clearValueName();  					dst_typed_param.setProvided(true); @@ -1158,56 +1279,72 @@ namespace LLInitParam  			}  			return false;  		} + +	private: +		void init( BlockDescriptor &block_descriptor, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count, const char* name )  +		{ +			ParamDescriptorPtr param_descriptor = ParamDescriptorPtr(new ParamDescriptor( +				block_descriptor.mCurrentBlockPtr->getHandleFromParam(this), +				&mergeWith, +				&deserializeParam, +				&serializeParam, +				validate_func,  +				&inspectParam, +				min_count, max_count)); +			block_descriptor.addParam(param_descriptor, name); +		}  	}; -	// container of non-block parameters +	// list of non-block parameters  	template <typename VALUE_TYPE, typename NAME_VALUE_LOOKUP> -	class TypedParam<VALUE_TYPE, NAME_VALUE_LOOKUP, true, false>  +	class TypedParam<VALUE_TYPE, NAME_VALUE_LOOKUP, true, NOT_BLOCK>   	:	public Param  	{ +	protected: +		typedef TypedParam<VALUE_TYPE, NAME_VALUE_LOOKUP, true, NOT_BLOCK>		self_t; +		typedef ParamValue<typename LLTypeTags::Sorted<VALUE_TYPE>::value_t>	param_value_t; +		typedef typename std::vector<typename NAME_VALUE_LOOKUP::type_value_t>	container_t; +		typedef container_t														default_value_t; +		typedef typename NAME_VALUE_LOOKUP::type_value_t						named_value_t; +		  	public: -		typedef TypedParam<VALUE_TYPE, NAME_VALUE_LOOKUP, true, false>		self_t; -		typedef ParamValue<VALUE_TYPE, NAME_VALUE_LOOKUP>					param_value_t; -		typedef typename std::vector<param_value_t>							container_t; -		typedef const container_t&											value_assignment_t; -  		typedef typename param_value_t::value_t								value_t; -		typedef NAME_VALUE_LOOKUP											name_value_lookup_t; -		TypedParam(BlockDescriptor& block_descriptor, const char* name, value_assignment_t value, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count)  +		TypedParam(BlockDescriptor& block_descriptor, const char* name, const default_value_t& value, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count)  		:	Param(block_descriptor.mCurrentBlockPtr)  		{  			std::copy(value.begin(), value.end(), std::back_inserter(mValues));  			if (LL_UNLIKELY(block_descriptor.mInitializationState == BlockDescriptor::INITIALIZING))  			{ -				ParamDescriptorPtr param_descriptor = ParamDescriptorPtr(new ParamDescriptor( -												block_descriptor.mCurrentBlockPtr->getHandleFromParam(this), -												&mergeWith, -												&deserializeParam, -												&serializeParam, -												validate_func, -												&inspectParam, -												min_count, max_count)); -				BaseBlock::addParam(block_descriptor, param_descriptor, name); +				init(block_descriptor, validate_func, min_count, max_count, name); +  			}  		}   		bool isProvided() const { return Param::anyProvided(); } -		static bool deserializeParam(Param& param, Parser& parser, const Parser::name_stack_range_t& name_stack_range, bool new_name) +		static bool deserializeParam(Param& param, Parser& parser, Parser::name_stack_range_t& name_stack_range, bool new_name)  		{  +			Parser::name_stack_range_t new_name_stack_range(name_stack_range);  			self_t& typed_param = static_cast<self_t&>(param);  			value_t value; + +			// pop first element if empty string +			if (new_name_stack_range.first != new_name_stack_range.second && new_name_stack_range.first->first.empty()) +			{ +				++new_name_stack_range.first; +			} +  			// no further names in stack, attempt to parse value now  			if (name_stack_range.first == name_stack_range.second)  			{	  				std::string name;  				// try to parse a known named value -				if(name_value_lookup_t::valueNamesExist() +				if(named_value_t::valueNamesExist()  					&& parser.readValue(name) -					&& name_value_lookup_t::getValueFromName(name, value)) +					&& named_value_t::getValueFromName(name, value))  				{  					typed_param.add(value);  					typed_param.mValues.back().setValueName(name); @@ -1225,14 +1362,14 @@ namespace LLInitParam  		static void serializeParam(const Param& param, Parser& parser, Parser::name_stack_t& name_stack, const Param* diff_param)  		{  			const self_t& typed_param = static_cast<const self_t&>(param); -			if (!typed_param.isProvided() || name_stack.empty()) return; +			if (!typed_param.isProvided()) return;  			for (const_iterator it = typed_param.mValues.begin(), end_it = typed_param.mValues.end();  				it != end_it;  				++it)  			{  				std::string key = it->getValueName(); -				name_stack.back().second = true; +				name_stack.push_back(std::make_pair(std::string(), true));  				if(key.empty())  				// not parsed via name values, write out value directly @@ -1254,19 +1391,21 @@ namespace LLInitParam  						break;  					}  				} + +				name_stack.pop_back();  			}  		}  		static void inspectParam(const Param& param, Parser& parser, Parser::name_stack_t& name_stack, S32 min_count, S32 max_count)  		{  			parser.inspectValue<VALUE_TYPE>(name_stack, min_count, max_count, NULL); -			if (name_value_lookup_t::getPossibleValues()) +			if (named_value_t::getPossibleValues())  			{ -				parser.inspectValue<std::string>(name_stack, min_count, max_count, name_value_lookup_t::getPossibleValues()); +				parser.inspectValue<std::string>(name_stack, min_count, max_count, named_value_t::getPossibleValues());  			}  		} -		void set(value_assignment_t val, bool flag_as_provided = true) +		void set(const container_t& val, bool flag_as_provided = true)  		{  			mValues = val;  			setProvided(flag_as_provided); @@ -1274,26 +1413,24 @@ namespace LLInitParam  		param_value_t& add()  		{ -			mValues.push_back(param_value_t(value_t())); +			mValues.push_back(value_t());  			Param::setProvided();  			return mValues.back();  		}  		self_t& add(const value_t& item)  		{ -			param_value_t param_value; -			param_value.setValue(item); -			mValues.push_back(param_value); +			mValues.push_back(item);  			setProvided();  			return *this;  		} -		self_t& add(const typename name_value_lookup_t::name_t& name) +		self_t& add(const typename named_value_t::name_t& name)  		{  			value_t value;  			// try to parse a per type named value -			if (name_value_lookup_t::getValueFromName(name, value)) +			if (named_value_t::getValueFromName(name, value))  			{  				add(value);  				mValues.back().setValueName(name); @@ -1303,9 +1440,9 @@ namespace LLInitParam  		}  		// implicit conversion -		operator value_assignment_t() const { return mValues; }  +		operator const container_t&() const { return mValues; }   		// explicit conversion		 -		value_assignment_t operator()() const { return mValues; } +		const container_t& operator()() const { return mValues; }  		typedef typename container_t::iterator iterator;  		typedef typename container_t::const_iterator const_iterator; @@ -1346,62 +1483,79 @@ namespace LLInitParam  		}  		container_t		mValues; + +	private: +		void init( BlockDescriptor &block_descriptor, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count, const char* name )  +		{ +			ParamDescriptorPtr param_descriptor = ParamDescriptorPtr(new ParamDescriptor( +				block_descriptor.mCurrentBlockPtr->getHandleFromParam(this), +				&mergeWith, +				&deserializeParam, +				&serializeParam, +				validate_func, +				&inspectParam, +				min_count, max_count)); +			block_descriptor.addParam(param_descriptor, name); +		}  	}; -	// container of block parameters +	// list of block parameters  	template <typename VALUE_TYPE, typename NAME_VALUE_LOOKUP> -	class TypedParam<VALUE_TYPE, NAME_VALUE_LOOKUP, true, true>  +	class TypedParam<VALUE_TYPE, NAME_VALUE_LOOKUP, true, IS_A_BLOCK>   	:	public Param  	{ +	protected: +		typedef TypedParam<VALUE_TYPE, NAME_VALUE_LOOKUP, true, IS_A_BLOCK>		self_t; +		typedef ParamValue<typename LLTypeTags::Sorted<VALUE_TYPE>::value_t>	param_value_t; +		typedef typename std::vector<typename NAME_VALUE_LOOKUP::type_value_t>	container_t; +		typedef typename NAME_VALUE_LOOKUP::type_value_t						named_value_t; +		typedef container_t														default_value_t; +		typedef typename container_t::iterator									iterator; +		typedef typename container_t::const_iterator							const_iterator;  	public: -		typedef TypedParam<VALUE_TYPE, NAME_VALUE_LOOKUP, true, true>	self_t; -		typedef ParamValue<VALUE_TYPE, NAME_VALUE_LOOKUP>				param_value_t; -		typedef typename std::vector<param_value_t>						container_t; -		typedef const container_t&										value_assignment_t;  		typedef typename param_value_t::value_t							value_t; -		typedef NAME_VALUE_LOOKUP										name_value_lookup_t; -		TypedParam(BlockDescriptor& block_descriptor, const char* name, value_assignment_t value, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count)  +		TypedParam(BlockDescriptor& block_descriptor, const char* name, const default_value_t& value, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count)  		:	Param(block_descriptor.mCurrentBlockPtr)  		{  			std::copy(value.begin(), value.end(), back_inserter(mValues));  			if (LL_UNLIKELY(block_descriptor.mInitializationState == BlockDescriptor::INITIALIZING))  			{ -				ParamDescriptorPtr param_descriptor = ParamDescriptorPtr(new ParamDescriptor( -												block_descriptor.mCurrentBlockPtr->getHandleFromParam(this), -												&mergeWith, -												&deserializeParam, -												&serializeParam, -												validate_func, -												&inspectParam, -												min_count, max_count)); -				BaseBlock::addParam(block_descriptor, param_descriptor, name); +				init(block_descriptor, validate_func, min_count, max_count, name);  			}  		}   		bool isProvided() const { return Param::anyProvided(); } -		static bool deserializeParam(Param& param, Parser& parser, const Parser::name_stack_range_t& name_stack_range, bool new_name)  +		static bool deserializeParam(Param& param, Parser& parser, Parser::name_stack_range_t& name_stack_range, bool new_name)   		{  +			Parser::name_stack_range_t new_name_stack_range(name_stack_range);  			self_t& typed_param = static_cast<self_t&>(param);  			bool new_value = false; +			bool new_array_value = false; -			if (new_name || typed_param.mValues.empty()) +			// pop first element if empty string +			if (new_name_stack_range.first != new_name_stack_range.second && new_name_stack_range.first->first.empty()) +			{ +				new_array_value = new_name_stack_range.first->second; +				++new_name_stack_range.first; +			} + +			if (new_name || new_array_value || typed_param.mValues.empty())  			{  				new_value = true;  				typed_param.mValues.push_back(value_t());  			} -  			param_value_t& value = typed_param.mValues.back();  			if (name_stack_range.first == name_stack_range.second)  			{	// try to parse a known named value  				std::string name; -				if(name_value_lookup_t::valueNamesExist() +				if(named_value_t::valueNamesExist()  					&& parser.readValue(name) -					&& name_value_lookup_t::getValueFromName(name, value.getValue())) +					&& named_value_t::getValueFromName(name, value.getValue()))  				{  					typed_param.mValues.back().setValueName(name);  					typed_param.setProvided(); @@ -1410,9 +1564,13 @@ namespace LLInitParam  			}  			// attempt to parse block... -			if(value.deserializeBlock(parser, name_stack_range, new_name)) +			if(value.deserializeBlock(parser, new_name_stack_range, new_name))  			{  				typed_param.setProvided(); +				if (new_array_value) +				{ +					name_stack_range.first->second = false; +				}  				return true;  			} @@ -1428,13 +1586,13 @@ namespace LLInitParam  		static void serializeParam(const Param& param, Parser& parser, Parser::name_stack_t& name_stack, const Param* diff_param)  		{  			const self_t& typed_param = static_cast<const self_t&>(param); -			if (!typed_param.isProvided() || name_stack.empty()) return; +			if (!typed_param.isProvided()) return;  			for (const_iterator it = typed_param.mValues.begin(), end_it = typed_param.mValues.end();  				it != end_it;  				++it)  			{ -				name_stack.back().second = true; +				name_stack.push_back(std::make_pair(std::string(), true));  				std::string key = it->getValueName();  				if (!key.empty()) @@ -1447,16 +1605,27 @@ namespace LLInitParam  				{  					it->serializeBlock(parser, name_stack, NULL);  				} + +				name_stack.pop_back();  			}  		}  		static void inspectParam(const Param& param, Parser& parser, Parser::name_stack_t& name_stack, S32 min_count, S32 max_count)  		{ -			// I am a vector of blocks, so describe my contents recursively -			param_value_t(value_t()).inspectBlock(parser, name_stack, min_count, max_count); +			const param_value_t& value_param = param_value_t(value_t()); + +			// tell parser about our actual type +			parser.inspectValue<value_t>(name_stack, min_count, max_count, NULL); +			// then tell it about string-based alternatives ("red", "blue", etc. for LLColor4) +			if (named_value_t::getPossibleValues()) +			{ +				parser.inspectValue<std::string>(name_stack, min_count, max_count, named_value_t::getPossibleValues());  		} -		void set(value_assignment_t val, bool flag_as_provided = true) +			value_param.inspectBlock(parser, name_stack, min_count, max_count); +		} + +		void set(const container_t& val, bool flag_as_provided = true)  		{  			mValues = val;  			setProvided(flag_as_provided); @@ -1476,12 +1645,12 @@ namespace LLInitParam  			return *this;  		} -		self_t& add(const typename name_value_lookup_t::name_t& name) +		self_t& add(const typename named_value_t::name_t& name)  		{  			value_t value;  			// try to parse a per type named value -			if (name_value_lookup_t::getValueFromName(name, value)) +			if (named_value_t::getValueFromName(name, value))  			{  				add(value);  				mValues.back().setValueName(name); @@ -1490,12 +1659,10 @@ namespace LLInitParam  		}  		// implicit conversion -		operator value_assignment_t() const { return mValues; }  +		operator const container_t&() const { return mValues; }   		// explicit conversion -		value_assignment_t operator()() const { return mValues; } +		const container_t& operator()() const { return mValues; } -		typedef typename container_t::iterator iterator; -		typedef typename container_t::const_iterator const_iterator;  		iterator begin() { return mValues.begin(); }  		iterator end() { return mValues.end(); }  		const_iterator begin() const { return mValues.begin(); } @@ -1542,6 +1709,20 @@ namespace LLInitParam  		}  		container_t			mValues; + +	private: +		void init( BlockDescriptor &block_descriptor, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count, const char* name )  +		{ +			ParamDescriptorPtr param_descriptor = ParamDescriptorPtr(new ParamDescriptor( +				block_descriptor.mCurrentBlockPtr->getHandleFromParam(this), +				&mergeWith, +				&deserializeParam, +				&serializeParam, +				validate_func, +				&inspectParam, +				min_count, max_count)); +			block_descriptor.addParam(param_descriptor, name); +		}  	};  	template <typename DERIVED_BLOCK, typename BASE_BLOCK = BaseBlock> @@ -1556,13 +1737,13 @@ namespace LLInitParam  		// take all provided params from other and apply to self  		bool overwriteFrom(const self_t& other)  		{ -			return static_cast<DERIVED_BLOCK*>(this)->mergeBlock(selfBlockDescriptor(), other, true); +			return static_cast<DERIVED_BLOCK*>(this)->mergeBlock(getBlockDescriptor(), other, true);  		}  		// take all provided params that are not already provided, and apply to self  		bool fillFrom(const self_t& other)  		{ -			return static_cast<DERIVED_BLOCK*>(this)->mergeBlock(selfBlockDescriptor(), other, false); +			return static_cast<DERIVED_BLOCK*>(this)->mergeBlock(getBlockDescriptor(), other, false);  		}  		bool mergeBlockParam(bool source_provided, bool dest_provided, BlockDescriptor& block_data, const self_t& source, bool overwrite) @@ -1580,7 +1761,7 @@ namespace LLInitParam  		bool mergeBlock(BlockDescriptor& block_data, const self_t& other, bool overwrite)  		{  			mCurChoice = other.mCurChoice; -			return base_block_t::mergeBlock(selfBlockDescriptor(), other, overwrite); +			return base_block_t::mergeBlock(getBlockDescriptor(), other, overwrite);  		}  		// clear out old choice when param has changed @@ -1601,38 +1782,38 @@ namespace LLInitParam  			base_block_t::paramChanged(changed_param, user_provided);  		} -		virtual const BlockDescriptor& mostDerivedBlockDescriptor() const { return selfBlockDescriptor(); } -		virtual BlockDescriptor& mostDerivedBlockDescriptor() { return selfBlockDescriptor(); } +		virtual const BlockDescriptor& mostDerivedBlockDescriptor() const { return getBlockDescriptor(); } +		virtual BlockDescriptor& mostDerivedBlockDescriptor() { return getBlockDescriptor(); }  	protected:  		ChoiceBlock()  		:	mCurChoice(0)  		{ -			BaseBlock::init(selfBlockDescriptor(), base_block_t::selfBlockDescriptor(), sizeof(DERIVED_BLOCK)); +			BaseBlock::init(getBlockDescriptor(), base_block_t::getBlockDescriptor(), sizeof(DERIVED_BLOCK));  		}  		// Alternatives are mutually exclusive wrt other Alternatives in the same block.    		// One alternative in a block will always have isChosen() == true.  		// At most one alternative in a block will have isProvided() == true. -		template <typename T, typename NAME_VALUE_LOOKUP = TypeValues<T> > +		template <typename T, typename NAME_VALUE_LOOKUP = typename TypeValues<T>::type_value_t >  		class Alternative : public TypedParam<T, NAME_VALUE_LOOKUP, false>  		{ +			typedef TypedParam<T, NAME_VALUE_LOOKUP, false>	super_t; +			typedef typename super_t::value_t				value_t; +			typedef typename super_t::default_value_t		default_value_t; +  		public:  			friend class ChoiceBlock<DERIVED_BLOCK>; -			typedef Alternative<T, NAME_VALUE_LOOKUP>									self_t; -			typedef TypedParam<T, NAME_VALUE_LOOKUP, false, IsBlock<ParamValue<T, NAME_VALUE_LOOKUP> >::value>		super_t; -			typedef typename super_t::value_assignment_t								value_assignment_t; -  			using super_t::operator =; -			explicit Alternative(const char* name = "", value_assignment_t val = defaultValue<T>()) -			:	super_t(DERIVED_BLOCK::selfBlockDescriptor(), name, val, NULL, 0, 1), +			explicit Alternative(const char* name = "", const default_value_t& val = defaultValue<default_value_t>()) +			:	super_t(DERIVED_BLOCK::getBlockDescriptor(), name, val, NULL, 0, 1),  				mOriginalValue(val)  			{  				// assign initial choice to first declared option -				DERIVED_BLOCK* blockp = ((DERIVED_BLOCK*)DERIVED_BLOCK::selfBlockDescriptor().mCurrentBlockPtr); -				if (LL_UNLIKELY(DERIVED_BLOCK::selfBlockDescriptor().mInitializationState == BlockDescriptor::INITIALIZING)) +				DERIVED_BLOCK* blockp = ((DERIVED_BLOCK*)DERIVED_BLOCK::getBlockDescriptor().mCurrentBlockPtr); +				if (LL_UNLIKELY(DERIVED_BLOCK::getBlockDescriptor().mInitializationState == BlockDescriptor::INITIALIZING))  				{  					if(blockp->mCurChoice == 0)  					{ @@ -1646,27 +1827,27 @@ namespace LLInitParam  				static_cast<enclosing_block_t&>(Param::enclosingBlock()).paramChanged(*this, true);  			} -			void chooseAs(value_assignment_t val) +			void chooseAs(const value_t& val)  			{  				super_t::set(val);  			} -			void operator =(value_assignment_t val) +			void operator =(const value_t& val)  			{  				super_t::set(val);  			} -			void operator()(typename super_t::value_assignment_t val)  +			void operator()(const value_t& val)   			{   				super_t::set(val);  			} -			operator value_assignment_t() const  +			operator const value_t&() const   			{  				return (*this)();  			}  -			value_assignment_t operator()() const  +			const value_t& operator()() const   			{   				if (static_cast<enclosing_block_t&>(Param::enclosingBlock()).getCurrentChoice() == this)  				{ @@ -1681,11 +1862,11 @@ namespace LLInitParam  			}  		private: -			T			mOriginalValue; +			default_value_t mOriginalValue;  		}; -	protected: -		static BlockDescriptor& selfBlockDescriptor() +	public: +		static BlockDescriptor& getBlockDescriptor()  		{  			static BlockDescriptor sBlockDescriptor;  			return sBlockDescriptor; @@ -1705,6 +1886,8 @@ namespace LLInitParam  	:	public BASE_BLOCK  	{  		typedef Block<DERIVED_BLOCK, BASE_BLOCK>	self_t; + +	protected:  		typedef Block<DERIVED_BLOCK, BASE_BLOCK>	block_t;  	public: @@ -1713,80 +1896,82 @@ namespace LLInitParam  		// take all provided params from other and apply to self  		bool overwriteFrom(const self_t& other)  		{ -			return static_cast<DERIVED_BLOCK*>(this)->mergeBlock(selfBlockDescriptor(), other, true); +			return static_cast<DERIVED_BLOCK*>(this)->mergeBlock(getBlockDescriptor(), other, true);  		}  		// take all provided params that are not already provided, and apply to self  		bool fillFrom(const self_t& other)  		{ -			return static_cast<DERIVED_BLOCK*>(this)->mergeBlock(selfBlockDescriptor(), other, false); +			return static_cast<DERIVED_BLOCK*>(this)->mergeBlock(getBlockDescriptor(), other, false);  		} -		virtual const BlockDescriptor& mostDerivedBlockDescriptor() const { return selfBlockDescriptor(); } -		virtual BlockDescriptor& mostDerivedBlockDescriptor() { return selfBlockDescriptor(); } +		virtual const BlockDescriptor& mostDerivedBlockDescriptor() const { return getBlockDescriptor(); } +		virtual BlockDescriptor& mostDerivedBlockDescriptor() { return getBlockDescriptor(); }  	protected:  		Block()  		{  			//#pragma message("Parsing LLInitParam::Block") -			BaseBlock::init(selfBlockDescriptor(), BASE_BLOCK::selfBlockDescriptor(), sizeof(DERIVED_BLOCK)); +			BaseBlock::init(getBlockDescriptor(), BASE_BLOCK::getBlockDescriptor(), sizeof(DERIVED_BLOCK));  		}  		//  		// Nested classes for declaring parameters  		// -		template <typename T, typename NAME_VALUE_LOOKUP = TypeValues<T> > +		template <typename T, typename NAME_VALUE_LOOKUP = typename TypeValues<T>::type_value_t >  		class Optional : public TypedParam<T, NAME_VALUE_LOOKUP, false>  		{ -		public: -			typedef TypedParam<T, NAME_VALUE_LOOKUP, false, IsBlock<ParamValue<T, NAME_VALUE_LOOKUP> >::value>		super_t; -			typedef typename super_t::value_assignment_t								value_assignment_t; +			typedef TypedParam<T, NAME_VALUE_LOOKUP, false>		super_t; +			typedef typename super_t::value_t					value_t; +			typedef typename super_t::default_value_t			default_value_t; +		public:  			using super_t::operator();  			using super_t::operator =; -			explicit Optional(const char* name = "", value_assignment_t val = defaultValue<T>()) -			:	super_t(DERIVED_BLOCK::selfBlockDescriptor(), name, val, NULL, 0, 1) +			explicit Optional(const char* name = "", const default_value_t& val = defaultValue<default_value_t>()) +			:	super_t(DERIVED_BLOCK::getBlockDescriptor(), name, val, NULL, 0, 1)  			{  				//#pragma message("Parsing LLInitParam::Block::Optional")  			} -			Optional& operator =(value_assignment_t val) +			Optional& operator =(const value_t& val)  			{  				set(val);  				return *this;  			} -			DERIVED_BLOCK& operator()(value_assignment_t val) +			DERIVED_BLOCK& operator()(const value_t& val)  			{  				super_t::set(val);  				return static_cast<DERIVED_BLOCK&>(Param::enclosingBlock());  			}  		}; -		template <typename T, typename NAME_VALUE_LOOKUP = TypeValues<T> > +		template <typename T, typename NAME_VALUE_LOOKUP = typename TypeValues<T>::type_value_t >  		class Mandatory : public TypedParam<T, NAME_VALUE_LOOKUP, false>  		{ -		public: -			typedef TypedParam<T, NAME_VALUE_LOOKUP, false, IsBlock<ParamValue<T, NAME_VALUE_LOOKUP> >::value>		super_t; +			typedef TypedParam<T, NAME_VALUE_LOOKUP, false>		super_t;  			typedef Mandatory<T, NAME_VALUE_LOOKUP>										self_t; -			typedef typename super_t::value_assignment_t								value_assignment_t; +			typedef typename super_t::value_t					value_t; +			typedef typename super_t::default_value_t			default_value_t; +		public:  			using super_t::operator();  			using super_t::operator =;  			// mandatory parameters require a name to be parseable -			explicit Mandatory(const char* name = "", value_assignment_t val = defaultValue<T>()) -			:	super_t(DERIVED_BLOCK::selfBlockDescriptor(), name, val, &validate, 1, 1) +			explicit Mandatory(const char* name = "", const default_value_t& val = defaultValue<default_value_t>()) +			:	super_t(DERIVED_BLOCK::getBlockDescriptor(), name, val, &validate, 1, 1)  			{} -			Mandatory& operator =(value_assignment_t val) +			Mandatory& operator =(const value_t& val)  			{  				set(val);  				return *this;  			} -			DERIVED_BLOCK& operator()(typename super_t::value_assignment_t val) +			DERIVED_BLOCK& operator()(const value_t& val)  			{  				super_t::set(val);  				return static_cast<DERIVED_BLOCK&>(Param::enclosingBlock()); @@ -1800,28 +1985,29 @@ namespace LLInitParam  		}; -		template <typename T, typename RANGE = BaseBlock::AnyAmount, typename NAME_VALUE_LOOKUP = TypeValues<T> > +		template <typename T, typename RANGE = BaseBlock::AnyAmount, typename NAME_VALUE_LOOKUP = typename TypeValues<T>::type_value_t >  		class Multiple : public TypedParam<T, NAME_VALUE_LOOKUP, true>  		{ -		public: -			typedef TypedParam<T, NAME_VALUE_LOOKUP, true, IsBlock<ParamValue<T, NAME_VALUE_LOOKUP> >::value>	super_t; +			typedef TypedParam<T, NAME_VALUE_LOOKUP, true>	super_t;  			typedef Multiple<T, RANGE, NAME_VALUE_LOOKUP>							self_t;  			typedef typename super_t::container_t									container_t; -			typedef typename super_t::value_assignment_t							value_assignment_t; +			typedef typename super_t::value_t				value_t; + +		public:  			typedef typename super_t::iterator										iterator;  			typedef typename super_t::const_iterator								const_iterator;  			explicit Multiple(const char* name = "") -			:	super_t(DERIVED_BLOCK::selfBlockDescriptor(), name, container_t(), &validate, RANGE::minCount, RANGE::maxCount) +			:	super_t(DERIVED_BLOCK::getBlockDescriptor(), name, container_t(), &validate, RANGE::minCount, RANGE::maxCount)  			{} -			Multiple& operator =(value_assignment_t val) +			Multiple& operator =(const container_t& val)  			{  				set(val);  				return *this;  			} -			DERIVED_BLOCK& operator()(typename super_t::value_assignment_t val) +			DERIVED_BLOCK& operator()(const container_t& val)  			{  				super_t::set(val);  				return static_cast<DERIVED_BLOCK&>(Param::enclosingBlock()); @@ -1834,13 +2020,15 @@ namespace LLInitParam  			}  		}; -		class Deprecated : public Param +		// can appear in data files, but will ignored during parsing +		// cannot read or write in code +		class Ignored : public Param  		{  		public: -			explicit Deprecated(const char* name) -			:	Param(DERIVED_BLOCK::selfBlockDescriptor().mCurrentBlockPtr) +			explicit Ignored(const char* name) +			:	Param(DERIVED_BLOCK::getBlockDescriptor().mCurrentBlockPtr)  			{ -				BlockDescriptor& block_descriptor = DERIVED_BLOCK::selfBlockDescriptor(); +				BlockDescriptor& block_descriptor = DERIVED_BLOCK::getBlockDescriptor();  				if (LL_UNLIKELY(block_descriptor.mInitializationState == BlockDescriptor::INITIALIZING))  				{  					ParamDescriptorPtr param_descriptor = ParamDescriptorPtr(new ParamDescriptor( @@ -1851,11 +2039,11 @@ namespace LLInitParam  													NULL,  													NULL,   													0, S32_MAX)); -					BaseBlock::addParam(block_descriptor, param_descriptor, name); +					block_descriptor.addParam(param_descriptor, name);  				}  			} -			static bool deserializeParam(Param& param, Parser& parser, const Parser::name_stack_range_t& name_stack_range, bool new_name) +			static bool deserializeParam(Param& param, Parser& parser, Parser::name_stack_range_t& name_stack_range, bool new_name)  			{  				if (name_stack_range.first == name_stack_range.second)  				{ @@ -1868,19 +2056,46 @@ namespace LLInitParam  			}  		}; -		// different semantics for documentation purposes, but functionally identical -		typedef Deprecated Ignored; +		// can appear in data files, or be written to in code, but data will be ignored +		// cannot be read in code +		class Deprecated : public Ignored +		{ +		public: +			explicit Deprecated(const char* name) : Ignored(name) {} -	protected: -		static BlockDescriptor& selfBlockDescriptor() +			// dummy writer interfaces +			template<typename T> +			Deprecated& operator =(const T& val) +		{ +				// do nothing +				return *this; +			} + +			template<typename T> +			DERIVED_BLOCK& operator()(const T& val) +			{ +				// do nothing +				return static_cast<DERIVED_BLOCK&>(Param::enclosingBlock()); +			} + +			template<typename T> +			void set(const T& val, bool flag_as_provided = true) +			{ +				// do nothing +			} +		}; + +	public: +		static BlockDescriptor& getBlockDescriptor()  		{  			static BlockDescriptor sBlockDescriptor;  			return sBlockDescriptor;  		} -		template <typename T, typename NAME_VALUE_LOOKUP, bool multiple, bool is_block> +	protected: +		template <typename T, typename NAME_VALUE_LOOKUP, bool multiple, typename is_block>  		void changeDefault(TypedParam<T, NAME_VALUE_LOOKUP, multiple, is_block>& param,  -			typename TypedParam<T, NAME_VALUE_LOOKUP, multiple, is_block>::value_assignment_t value) +			const typename TypedParam<T, NAME_VALUE_LOOKUP, multiple, is_block>::value_t& value)  		{  			if (!param.isProvided())  			{ @@ -1890,204 +2105,420 @@ namespace LLInitParam  	}; -	template <typename DERIVED_BLOCK, typename BASE_BLOCK = BaseBlock> -	class BatchBlock -	:	public Block<DERIVED_BLOCK, BASE_BLOCK> +	template<typename T, typename BLOCK_T> +	struct IsBlock<ParamValue<BaseBlock::Lazy<T, BaseBlock::IS_A_BLOCK>, BLOCK_T >, void> +	{ +		typedef IS_A_BLOCK value_t; +	}; + +	template<typename T, typename BLOCK_T> +	struct IsBlock<ParamValue<BaseBlock::Lazy<T, BaseBlock::NOT_A_BLOCK>, BLOCK_T >, void> +	{ +		typedef NOT_BLOCK value_t; +	}; + +	template<typename T, typename BLOCK_IDENTIFIER> +	struct IsBlock<ParamValue<BaseBlock::Atomic<T>, typename IsBlock<BaseBlock::Atomic<T> >::value_t >, BLOCK_IDENTIFIER> +	{ +		typedef typename IsBlock<T>::value_t value_t; +	}; + +	template<typename T, typename BLOCK_IDENTIFIER> +	struct IsBlock<ParamValue<BaseBlock::Sequential<T>, typename IsBlock<BaseBlock::Sequential<T> >::value_t >, BLOCK_IDENTIFIER>  	{ +		typedef typename IsBlock<T>::value_t value_t; +	}; + + +	template<typename T> +	struct InnerMostType +	{ +		typedef T value_t; +	}; + +	template<typename T> +	struct InnerMostType<ParamValue<T, NOT_BLOCK> > +	{ +		typedef typename InnerMostType<T>::value_t value_t; +	}; + +	template<typename T> +	struct InnerMostType<ParamValue<T, IS_A_BLOCK> > +	{ +		typedef typename InnerMostType<T>::value_t value_t; +	}; + +	template<typename T, typename BLOCK_T> +	class ParamValue <BaseBlock::Atomic<T>, BLOCK_T> +	{ +		typedef ParamValue <BaseBlock::Atomic<T>, BLOCK_T> self_t; +  	public: -		typedef BatchBlock<DERIVED_BLOCK, BASE_BLOCK> self_t; -		typedef Block<DERIVED_BLOCK, BASE_BLOCK> super_t; +		typedef typename InnerMostType<T>::value_t	value_t; +		typedef T									default_value_t; -		BatchBlock() +		ParamValue() +		:	mValue(), +			mValidated(false)  		{} -		bool deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack_range, bool new_name) +		ParamValue(const default_value_t& value) +		:	mValue(value), +			mValidated(false) +		{} + +		void setValue(const value_t& val) +		{ +			mValue.setValue(val); +		} + +		const value_t& getValue() const +		{ +			return mValue.getValue(); +		} + +		value_t& getValue() +		{ +			return mValue.getValue(); +		} + +		bool deserializeBlock(Parser& p, Parser::name_stack_range_t& name_stack_range, bool new_name)  		{  			if (new_name)  			{ -				// reset block -				*static_cast<DERIVED_BLOCK*>(this) = defaultBatchValue(); +				resetToDefault();  			} -			return super_t::deserializeBlock(p, name_stack_range, new_name); +			return mValue.deserializeBlock(p, name_stack_range, new_name);  		} -		bool mergeBlock(BlockDescriptor& block_data, const BaseBlock& other, bool overwrite) +		void serializeBlock(Parser& p, Parser::name_stack_t& name_stack, const self_t* diff_block = NULL) const  		{ -			if (overwrite) +			const BaseBlock* base_block = diff_block +				? &(diff_block->mValue) +				: NULL; +			mValue.serializeBlock(p, name_stack, base_block); +		} + +		bool inspectBlock(Parser& p, Parser::name_stack_t name_stack = Parser::name_stack_t(), S32 min_count = 0, S32 max_count = S32_MAX) const  			{ -				*static_cast<DERIVED_BLOCK*>(this) = defaultBatchValue(); -				// merge individual parameters into destination -				return super_t::mergeBlock(super_t::selfBlockDescriptor(), other, overwrite); +			return mValue.inspectBlock(p, name_stack, min_count, max_count);  			} -			return false; + +		bool mergeBlockParam(bool source_provided, bool dst_provided, BlockDescriptor& block_data, const self_t& source, bool 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);  		} -	protected: -		static const DERIVED_BLOCK& defaultBatchValue() +			 + +			return mValue.mergeBlock(block_data, source.getValue(), overwrite); +		} + +		bool validateBlock(bool emit_errors = true) const +		{ +			return mValue.validateBlock(emit_errors); +		} + +		static BlockDescriptor& getBlockDescriptor() +		{ +			return value_t::getBlockDescriptor(); +		} + + +		mutable bool 	mValidated; // lazy validation flag + +	private: +		void resetToDefault()  		{ -			static DERIVED_BLOCK default_value; -			return default_value; +			static T default_value; +			mValue = default_value;  		} + +		T	mValue;  	}; -	// FIXME: this specialization is not currently used, as it only matches against the BatchBlock base class -	// and not the derived class with the actual params -	template<typename DERIVED_BLOCK, -			typename BASE_BLOCK, -			typename NAME_VALUE_LOOKUP> -	class ParamValue <BatchBlock<DERIVED_BLOCK, BASE_BLOCK>, -					NAME_VALUE_LOOKUP, -					true> -	:	public NAME_VALUE_LOOKUP, -		protected BatchBlock<DERIVED_BLOCK, BASE_BLOCK> +	template<typename T> +	class ParamValue <BaseBlock::Sequential<T>, IS_A_BLOCK>  	{ +		typedef ParamValue <BaseBlock::Sequential<T>, IS_A_BLOCK> self_t; +  	public: -		typedef BatchBlock<DERIVED_BLOCK, BASE_BLOCK> block_t; -		typedef const BatchBlock<DERIVED_BLOCK, BASE_BLOCK>&	value_assignment_t; -		typedef block_t value_t; +		typedef typename InnerMostType<T>::value_t	value_t; +		typedef T									default_value_t;  		ParamValue() -		:	block_t(), +		:	mValue(),  			mValidated(false) -		{} +		{ +			mCurParam = getBlockDescriptor().mAllParams.begin(); +		} -		ParamValue(value_assignment_t other) -		:	block_t(other), +		ParamValue(const default_value_t& value) +		:	mValue(value),  			mValidated(false)  		{ +			mCurParam = getBlockDescriptor().mAllParams.begin();  		} -		void setValue(value_assignment_t val) +		void setValue(const value_t& val)  		{ -			*this = val; +			mValue.setValue(val);  		} -		value_assignment_t getValue() const +		const value_t& getValue() const  		{ -			return *this; +			return mValue.getValue();  		} -		BatchBlock<DERIVED_BLOCK, BASE_BLOCK>& getValue() +		value_t& getValue()  		{ -			return *this; +			return mValue.getValue();  		} -		operator value_assignment_t() const +		bool deserializeBlock(Parser& p, Parser::name_stack_range_t& name_stack_range, bool new_name)  		{ -			return *this; +			if (new_name) +			{ +				mCurParam = getBlockDescriptor().mAllParams.begin();  		} +			if (name_stack_range.first == name_stack_range.second  +				&& mCurParam != getBlockDescriptor().mAllParams.end()) +			{ +				// deserialize to mCurParam +				ParamDescriptor& pd = *(*mCurParam); +				ParamDescriptor::deserialize_func_t deserialize_func = pd.mDeserializeFunc; +				Param* paramp = mValue.getParamFromHandle(pd.mParamHandle); -		value_assignment_t operator()() const +				if (deserialize_func  +					&& paramp  +					&& deserialize_func(*paramp, p, name_stack_range, new_name))  		{ -			return *this; +					++mCurParam; +					return true; +				} +				else +				{ +					return false; +				} +		} +			else +			{ +				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 +		{ +			const BaseBlock* base_block = diff_block +				? &(diff_block->mValue) +				: NULL; +			mValue.serializeBlock(p, name_stack, base_block); +		} + +		bool inspectBlock(Parser& p, Parser::name_stack_t name_stack = Parser::name_stack_t(), S32 min_count = 0, S32 max_count = S32_MAX) const +		{ +			return mValue.inspectBlock(p, name_stack, min_count, max_count); +		} + +		bool mergeBlockParam(bool source_provided, bool dst_provided, BlockDescriptor& block_data, const self_t& source, bool overwrite) +		{ +			return mValue.mergeBlock(block_data, source.getValue(), overwrite); +		} + +		bool validateBlock(bool emit_errors = true) const +		{ +			return mValue.validateBlock(emit_errors); +		} + +		static BlockDescriptor& getBlockDescriptor() +		{ +			return value_t::getBlockDescriptor();  		} -	protected:  		mutable bool 	mValidated; // lazy validation flag + +	private: + +		BlockDescriptor::all_params_list_t::iterator	mCurParam; +		T												mValue;  	}; -	template<typename T, bool IS_BLOCK> -	class ParamValue <BaseBlock::Lazy<T>, -					TypeValues<T>, -					IS_BLOCK> -	:	public IsBlock<T>::base_class_t +	template<typename T> +	class ParamValue <BaseBlock::Sequential<T>, NOT_BLOCK> +	: public T  	{ +		typedef ParamValue <BaseBlock::Sequential<T>, NOT_BLOCK> self_t; +  	public: -		typedef ParamValue <BaseBlock::Lazy<T>, TypeValues<T>, false> self_t; -		typedef const T& value_assignment_t; -		typedef T value_t; +		typedef typename InnerMostType<T>::value_t	value_t; +		typedef T									default_value_t; + +		ParamValue() +		:	T(), +			mValidated(false) +		{} +	 +		ParamValue(const default_value_t& value) +		:	T(value.getValue()), +			mValidated(false) +		{} + +		mutable bool 	mValidated; // lazy validation flag +	}; + +	template<typename T, typename BLOCK_T> +	class ParamValue <BaseBlock::Lazy<T, IS_A_BLOCK>, BLOCK_T>  +	{ +		typedef ParamValue <BaseBlock::Lazy<T, IS_A_BLOCK>, BLOCK_T> self_t; + +	public: +		typedef typename InnerMostType<T>::value_t	value_t; +		typedef LazyValue<T>						default_value_t;  		ParamValue()  		:	mValue(),  			mValidated(false)  		{} -		ParamValue(value_assignment_t other) +		ParamValue(const default_value_t& other)  		:	mValue(other),  			mValidated(false)  		{} -		void setValue(value_assignment_t val) +		ParamValue(const T& value) +		:	mValue(value), +			mValidated(false) +		{} + +		void setValue(const value_t& val)  		{  			mValue.set(val);  		} -		value_assignment_t getValue() const +		const value_t& getValue() const  		{ -			return mValue.get(); +			return mValue.get().getValue();  		} -		T& getValue() +		value_t& getValue()  		{ -			return mValue.get(); +			return mValue.get().getValue();  		} -		operator value_assignment_t() const +		bool deserializeBlock(Parser& p, Parser::name_stack_range_t& name_stack_range, bool new_name)  		{ -			return mValue.get(); +			return mValue.get().deserializeBlock(p, name_stack_range, new_name);  		} -		value_assignment_t operator()() const +		void serializeBlock(Parser& p, Parser::name_stack_t& name_stack, const self_t* diff_block = NULL) const  		{ -			return mValue.get(); +			if (mValue.empty()) return; +			 +			const BaseBlock* base_block = (diff_block && !diff_block->mValue.empty()) +											? &(diff_block->mValue.get().getValue()) +											: NULL; +			mValue.get().serializeBlock(p, name_stack, base_block);  		} -		bool deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack_range, bool new_name) +		bool inspectBlock(Parser& p, Parser::name_stack_t name_stack = Parser::name_stack_t(), S32 min_count = 0, S32 max_count = S32_MAX) const  		{ -			return mValue.get().deserializeBlock(p, name_stack_range, new_name); +			return mValue.get().inspectBlock(p, name_stack, min_count, max_count);  		} -		void serializeBlock(Parser& p, Parser::name_stack_t& name_stack, const BaseBlock* diff_block = NULL) const +		bool mergeBlockParam(bool source_provided, bool dst_provided, BlockDescriptor& block_data, const self_t& source, bool overwrite)  		{ -			if (mValue.empty()) return; +			return source.mValue.empty() || mValue.get().mergeBlock(block_data, source.getValue(), overwrite); +		} -			mValue.get().serializeBlock(p, name_stack, diff_block); +		bool validateBlock(bool emit_errors = true) const +		{ +			return mValue.empty() || mValue.get().validateBlock(emit_errors);  		} -		bool inspectBlock(Parser& p, Parser::name_stack_t name_stack = Parser::name_stack_t(), S32 min_count = 0, S32 max_count = S32_MAX) const +		static BlockDescriptor& getBlockDescriptor()  		{ -			if (mValue.empty()) return false; +			return value_t::getBlockDescriptor(); +		} -			return mValue.get().inspectBlock(p, name_stack, min_count, max_count); +		mutable bool 	mValidated; // lazy validation flag + +	private: +		LazyValue<T>	mValue; +	}; + +	template<typename T, typename BLOCK_T> +	class ParamValue <BaseBlock::Lazy<T, NOT_BLOCK>, BLOCK_T> +		{ +		typedef ParamValue <BaseBlock::Lazy<T, NOT_BLOCK>, BLOCK_T> self_t; + +	public: +		typedef typename InnerMostType<T>::value_t	value_t; +		typedef LazyValue<T>						default_value_t; + +		ParamValue() +		:	mValue(), +			mValidated(false) +		{} + +		ParamValue(const default_value_t& other) +		:	mValue(other), +			mValidated(false) +		{} + +		ParamValue(const T& value) +		:	mValue(value), +			mValidated(false) +		{} +			 +		void setValue(const value_t& val) +		{ +			mValue.set(val); +		} + +		const value_t& getValue() const +		{ +			return mValue.get().getValue(); +		} + +		value_t& getValue() +		{ +			return mValue.get().getValue();  		} -	protected:  		mutable bool 	mValidated; // lazy validation flag  	private: -		BaseBlock::Lazy<T>	mValue; +		LazyValue<T>	mValue;  	};  	template <> -	class ParamValue <LLSD, -					TypeValues<LLSD>, -					false> -	:	public TypeValues<LLSD>, -		public BaseBlock +	class ParamValue <LLSD, NOT_BLOCK> +	:	public BaseBlock  	{  	public: -		typedef ParamValue<LLSD, TypeValues<LLSD>, false> self_t; -		typedef const LLSD&	value_assignment_t; +		typedef LLSD			value_t; +		typedef LLSD			default_value_t;  		ParamValue()  		:	mValidated(false)  		{} -		ParamValue(value_assignment_t other) +		ParamValue(const default_value_t& other)  		:	mValue(other),  			mValidated(false)  		{} -		void setValue(value_assignment_t val) { mValue = val; } +		void setValue(const value_t& val) { mValue = val; } -		value_assignment_t getValue() const { return mValue; } +		const value_t& getValue() const { return mValue; }  		LLSD& getValue() { return mValue; } -		operator value_assignment_t() const { return mValue; } -		value_assignment_t operator()() const { return mValue; } -		 -  		// block param interface -		LL_COMMON_API bool deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack_range, bool new_name); +		LL_COMMON_API bool deserializeBlock(Parser& p, Parser::name_stack_range_t& name_stack_range, bool new_name);  		LL_COMMON_API void serializeBlock(Parser& p, Parser::name_stack_t& name_stack, const BaseBlock* diff_block = NULL) const;  		bool inspectBlock(Parser& p, Parser::name_stack_t name_stack = Parser::name_stack_t(), S32 min_count = 0, S32 max_count = S32_MAX) const  		{ @@ -2106,8 +2537,7 @@ namespace LLInitParam  	template<typename T>  	class CustomParamValue -	:	public Block<ParamValue<T, TypeValues<T> > >, -		public TypeValues<T> +	:	public Block<ParamValue<T> >  	{  	public:  		typedef enum e_value_age @@ -2117,20 +2547,21 @@ namespace LLInitParam  			BLOCK_AUTHORITATIVE		// mValue is derived from the block parameters, which are authoritative  		} EValueAge; -		typedef ParamValue<T, TypeValues<T> >	derived_t; +		typedef ParamValue<T>			derived_t;  		typedef CustomParamValue<T>				self_t;  		typedef Block<derived_t>				block_t; -		typedef const T&						value_assignment_t; +		typedef T						default_value_t;  		typedef T								value_t; +		typedef void					baseblock_base_class_t; -		CustomParamValue(const T& value = T()) +		CustomParamValue(const default_value_t& value = T())  		:	mValue(value),  			mValueAge(VALUE_AUTHORITATIVE),  			mValidated(false)  		{} -		bool deserializeBlock(Parser& parser, Parser::name_stack_range_t name_stack_range, bool new_name) +		bool deserializeBlock(Parser& parser, Parser::name_stack_range_t& name_stack_range, bool new_name)  		{  			derived_t& typed_param = static_cast<derived_t&>(*this);  			// try to parse direct value T @@ -2141,8 +2572,6 @@ namespace LLInitParam  					typed_param.mValueAge = VALUE_AUTHORITATIVE;  					typed_param.updateBlockFromValue(false); -					typed_param.clearValueName(); -  					return true;  				}  			} @@ -2156,18 +2585,8 @@ namespace LLInitParam  			const derived_t& typed_param = static_cast<const derived_t&>(*this);  			const derived_t* diff_param = static_cast<const derived_t*>(diff_block); -			std::string key = typed_param.getValueName(); - -			// first try to write out name of name/value pair -			if (!key.empty()) -			{ -				if (!diff_param || !ParamCompare<std::string>::equals(diff_param->getValueName(), key)) -				{ -					parser.writeValue(key, name_stack); -				} -			}  			// then try to serialize value directly -			else if (!diff_param || !ParamCompare<T>::equals(typed_param.getValue(), diff_param->getValue())) +			if (!diff_param || !ParamCompare<T>::equals(typed_param.getValue(), diff_param->getValue()))              {  				if (!parser.writeValue(typed_param.getValue(), name_stack))  @@ -2197,19 +2616,6 @@ namespace LLInitParam  			}  		} -		bool inspectBlock(Parser& parser, Parser::name_stack_t name_stack = Parser::name_stack_t(), S32 min_count = 0, S32 max_count = S32_MAX) const -		{ -			// first, inspect with actual type... -			parser.inspectValue<T>(name_stack, min_count, max_count, NULL); -			if (TypeValues<T>::getPossibleValues()) -			{ -				//...then inspect with possible string values... -				parser.inspectValue<std::string>(name_stack, min_count, max_count, TypeValues<T>::getPossibleValues()); -			} -			// then recursively inspect contents... -			return block_t::inspectBlock(parser, name_stack, min_count, max_count); -		} -  		bool validateBlock(bool emit_errors = true) const  		{  			if (mValueAge == VALUE_NEEDS_UPDATE) @@ -2217,7 +2623,6 @@ namespace LLInitParam  				if (block_t::validateBlock(emit_errors))  				{  					// clear stale keyword associated with old value -					TypeValues<T>::clearValueName();  					mValueAge = BLOCK_AUTHORITATIVE;  					static_cast<derived_t*>(const_cast<self_t*>(this))->updateValueFromBlock();  					return true; @@ -2247,17 +2652,15 @@ namespace LLInitParam  			}  		} -		void setValue(value_assignment_t val) +		void setValue(const value_t& val)  		{ -			derived_t& typed_param = static_cast<derived_t&>(*this);  			// set param version number to be up to date, so we ignore block contents  			mValueAge = VALUE_AUTHORITATIVE;  			mValue = val; -			typed_param.clearValueName();  			static_cast<derived_t*>(this)->updateBlockFromValue(false);  		} -		value_assignment_t getValue() const +		const value_t& getValue() const  		{  			validateBlock(true);  			return mValue; @@ -2269,20 +2672,10 @@ namespace LLInitParam  			return mValue;  		} -		operator value_assignment_t() const -		{ -			return getValue(); -		} - -		value_assignment_t operator()() const -		{ -			return getValue(); -		} -  	protected:  		// use this from within updateValueFromBlock() to set the value without making it authoritative -		void updateValue(value_assignment_t value) +		void updateValue(const value_t& value)  		{  			mValue = value;  		} diff --git a/indra/llcommon/llinstancetracker.cpp b/indra/llcommon/llinstancetracker.cpp index 5dc3ea5d7b..5dc3ea5d7b 100644..100755 --- a/indra/llcommon/llinstancetracker.cpp +++ b/indra/llcommon/llinstancetracker.cpp diff --git a/indra/llcommon/llinstancetracker.h b/indra/llcommon/llinstancetracker.h index 403df08990..1eab270e3c 100644..100755 --- 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 @@ -210,6 +210,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/llkeythrottle.h b/indra/llcommon/llkeythrottle.h index 1f576cc19e..1f576cc19e 100644..100755 --- a/indra/llcommon/llkeythrottle.h +++ b/indra/llcommon/llkeythrottle.h diff --git a/indra/llcommon/llkeyusetracker.h b/indra/llcommon/llkeyusetracker.h index 1fb222dd40..1fb222dd40 100644..100755 --- a/indra/llcommon/llkeyusetracker.h +++ b/indra/llcommon/llkeyusetracker.h diff --git a/indra/llcommon/lllazy.cpp b/indra/llcommon/lllazy.cpp index 29fa040387..29fa040387 100644..100755 --- a/indra/llcommon/lllazy.cpp +++ b/indra/llcommon/lllazy.cpp diff --git a/indra/llcommon/lllazy.h b/indra/llcommon/lllazy.h index 5f3bbce79e..5f3bbce79e 100644..100755 --- a/indra/llcommon/lllazy.h +++ b/indra/llcommon/lllazy.h diff --git a/indra/llcommon/llleap.cpp b/indra/llcommon/llleap.cpp index 0a57ef1c48..0a57ef1c48 100644..100755 --- a/indra/llcommon/llleap.cpp +++ b/indra/llcommon/llleap.cpp diff --git a/indra/llcommon/llleap.h b/indra/llcommon/llleap.h index 1a1ad23d39..1a1ad23d39 100644..100755 --- a/indra/llcommon/llleap.h +++ b/indra/llcommon/llleap.h diff --git a/indra/llcommon/llleaplistener.cpp b/indra/llcommon/llleaplistener.cpp index fa5730f112..fa5730f112 100644..100755 --- a/indra/llcommon/llleaplistener.cpp +++ b/indra/llcommon/llleaplistener.cpp diff --git a/indra/llcommon/llleaplistener.h b/indra/llcommon/llleaplistener.h index 2193d81b9e..2193d81b9e 100644..100755 --- a/indra/llcommon/llleaplistener.h +++ b/indra/llcommon/llleaplistener.h diff --git a/indra/llcommon/lllinkedqueue.h b/indra/llcommon/lllinkedqueue.h index 8336608809..8336608809 100644..100755 --- a/indra/llcommon/lllinkedqueue.h +++ b/indra/llcommon/lllinkedqueue.h diff --git a/indra/llcommon/lllistenerwrapper.h b/indra/llcommon/lllistenerwrapper.h index 09d074abca..09d074abca 100644..100755 --- a/indra/llcommon/lllistenerwrapper.h +++ b/indra/llcommon/lllistenerwrapper.h diff --git a/indra/llcommon/llliveappconfig.cpp b/indra/llcommon/llliveappconfig.cpp index 3a3dfa9f28..3a3dfa9f28 100644..100755 --- a/indra/llcommon/llliveappconfig.cpp +++ b/indra/llcommon/llliveappconfig.cpp diff --git a/indra/llcommon/llliveappconfig.h b/indra/llcommon/llliveappconfig.h index 4fd7c26a07..4fd7c26a07 100644..100755 --- a/indra/llcommon/llliveappconfig.h +++ b/indra/llcommon/llliveappconfig.h diff --git a/indra/llcommon/lllivefile.cpp b/indra/llcommon/lllivefile.cpp index c1987baf55..c1987baf55 100644..100755 --- a/indra/llcommon/lllivefile.cpp +++ b/indra/llcommon/lllivefile.cpp diff --git a/indra/llcommon/lllivefile.h b/indra/llcommon/lllivefile.h index 320aa4bc3e..320aa4bc3e 100644..100755 --- a/indra/llcommon/lllivefile.h +++ b/indra/llcommon/lllivefile.h diff --git a/indra/llcommon/lllocalidhashmap.h b/indra/llcommon/lllocalidhashmap.h index 8f4f91a560..8f4f91a560 100644..100755 --- a/indra/llcommon/lllocalidhashmap.h +++ b/indra/llcommon/lllocalidhashmap.h diff --git a/indra/llcommon/lllog.cpp b/indra/llcommon/lllog.cpp index fc4058b5c9..fc4058b5c9 100644..100755 --- a/indra/llcommon/lllog.cpp +++ b/indra/llcommon/lllog.cpp diff --git a/indra/llcommon/lllog.h b/indra/llcommon/lllog.h index 7964412e83..7964412e83 100644..100755 --- a/indra/llcommon/lllog.h +++ b/indra/llcommon/lllog.h diff --git a/indra/llcommon/lllslconstants.h b/indra/llcommon/lllslconstants.h index 9f32598e61..9f32598e61 100644..100755 --- a/indra/llcommon/lllslconstants.h +++ b/indra/llcommon/lllslconstants.h diff --git a/indra/llcommon/llmap.h b/indra/llcommon/llmap.h index 6294a15d3b..6294a15d3b 100644..100755 --- a/indra/llcommon/llmap.h +++ b/indra/llcommon/llmap.h diff --git a/indra/llcommon/llmd5.cpp b/indra/llcommon/llmd5.cpp index 1409c55d1c..1409c55d1c 100644..100755 --- a/indra/llcommon/llmd5.cpp +++ b/indra/llcommon/llmd5.cpp diff --git a/indra/llcommon/llmd5.h b/indra/llcommon/llmd5.h index 1526e6ac3c..1526e6ac3c 100644..100755 --- a/indra/llcommon/llmd5.h +++ b/indra/llcommon/llmd5.h diff --git a/indra/llcommon/llmemory.cpp b/indra/llcommon/llmemory.cpp index 70ad10ad55..70ad10ad55 100644..100755 --- a/indra/llcommon/llmemory.cpp +++ b/indra/llcommon/llmemory.cpp diff --git a/indra/llcommon/llmemory.h b/indra/llcommon/llmemory.h index e725bdd9fa..e725bdd9fa 100644..100755 --- a/indra/llcommon/llmemory.h +++ b/indra/llcommon/llmemory.h diff --git a/indra/llcommon/llmemorystream.cpp b/indra/llcommon/llmemorystream.cpp index 723d94f025..723d94f025 100644..100755 --- a/indra/llcommon/llmemorystream.cpp +++ b/indra/llcommon/llmemorystream.cpp diff --git a/indra/llcommon/llmemorystream.h b/indra/llcommon/llmemorystream.h index e28f012192..e28f012192 100644..100755 --- a/indra/llcommon/llmemorystream.h +++ b/indra/llcommon/llmemorystream.h diff --git a/indra/llcommon/llmetricperformancetester.cpp b/indra/llcommon/llmetricperformancetester.cpp index 41d3eb0bf3..731e58bd20 100644..100755 --- 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/llmetricperformancetester.h b/indra/llcommon/llmetricperformancetester.h index 1a18cdf36f..1a18cdf36f 100644..100755 --- a/indra/llcommon/llmetricperformancetester.h +++ b/indra/llcommon/llmetricperformancetester.h diff --git a/indra/llcommon/llmetrics.cpp b/indra/llcommon/llmetrics.cpp index 3078139f43..3078139f43 100644..100755 --- a/indra/llcommon/llmetrics.cpp +++ b/indra/llcommon/llmetrics.cpp diff --git a/indra/llcommon/llmetrics.h b/indra/llcommon/llmetrics.h index 4f0ae56338..4f0ae56338 100644..100755 --- a/indra/llcommon/llmetrics.h +++ b/indra/llcommon/llmetrics.h diff --git a/indra/llcommon/llmortician.cpp b/indra/llcommon/llmortician.cpp index 287f096eae..287f096eae 100644..100755 --- a/indra/llcommon/llmortician.cpp +++ b/indra/llcommon/llmortician.cpp diff --git a/indra/llcommon/llmortician.h b/indra/llcommon/llmortician.h index 319955ef93..319955ef93 100644..100755 --- a/indra/llcommon/llmortician.h +++ b/indra/llcommon/llmortician.h diff --git a/indra/llcommon/llnametable.h b/indra/llcommon/llnametable.h index d3283543f3..d3283543f3 100644..100755 --- a/indra/llcommon/llnametable.h +++ b/indra/llcommon/llnametable.h diff --git a/indra/llcommon/lloptioninterface.cpp b/indra/llcommon/lloptioninterface.cpp index 23fae76dc0..23fae76dc0 100644..100755 --- a/indra/llcommon/lloptioninterface.cpp +++ b/indra/llcommon/lloptioninterface.cpp diff --git a/indra/llcommon/lloptioninterface.h b/indra/llcommon/lloptioninterface.h index 93b465db32..93b465db32 100644..100755 --- a/indra/llcommon/lloptioninterface.h +++ b/indra/llcommon/lloptioninterface.h diff --git a/indra/llcommon/llpointer.h b/indra/llcommon/llpointer.h index 88c09c8dca..88c09c8dca 100644..100755 --- a/indra/llcommon/llpointer.h +++ b/indra/llcommon/llpointer.h diff --git a/indra/llcommon/llpreprocessor.h b/indra/llcommon/llpreprocessor.h index 7fdb537ab5..7fdb537ab5 100644..100755 --- a/indra/llcommon/llpreprocessor.h +++ b/indra/llcommon/llpreprocessor.h diff --git a/indra/llcommon/llpriqueuemap.h b/indra/llcommon/llpriqueuemap.h index da997c7b04..da997c7b04 100644..100755 --- a/indra/llcommon/llpriqueuemap.h +++ b/indra/llcommon/llpriqueuemap.h diff --git a/indra/llcommon/llprocess.cpp b/indra/llcommon/llprocess.cpp index 715df36f39..715df36f39 100644..100755 --- a/indra/llcommon/llprocess.cpp +++ b/indra/llcommon/llprocess.cpp diff --git a/indra/llcommon/llprocess.h b/indra/llcommon/llprocess.h index d711ce2f74..d711ce2f74 100644..100755 --- a/indra/llcommon/llprocess.h +++ b/indra/llcommon/llprocess.h diff --git a/indra/llcommon/llprocessor.cpp b/indra/llcommon/llprocessor.cpp index fd8f603d21..fd8f603d21 100644..100755 --- a/indra/llcommon/llprocessor.cpp +++ b/indra/llcommon/llprocessor.cpp diff --git a/indra/llcommon/llprocessor.h b/indra/llcommon/llprocessor.h index 6364d3c8bb..6364d3c8bb 100644..100755 --- a/indra/llcommon/llprocessor.h +++ b/indra/llcommon/llprocessor.h diff --git a/indra/llcommon/llptrskiplist.h b/indra/llcommon/llptrskiplist.h index 67c7cde352..67c7cde352 100644..100755 --- a/indra/llcommon/llptrskiplist.h +++ b/indra/llcommon/llptrskiplist.h diff --git a/indra/llcommon/llptrskipmap.h b/indra/llcommon/llptrskipmap.h index 94bc71ec55..94bc71ec55 100644..100755 --- a/indra/llcommon/llptrskipmap.h +++ b/indra/llcommon/llptrskipmap.h diff --git a/indra/llcommon/llptrto.cpp b/indra/llcommon/llptrto.cpp index b270291bd6..b270291bd6 100644..100755 --- a/indra/llcommon/llptrto.cpp +++ b/indra/llcommon/llptrto.cpp diff --git a/indra/llcommon/llptrto.h b/indra/llcommon/llptrto.h index 7091d36f6b..7091d36f6b 100644..100755 --- a/indra/llcommon/llptrto.h +++ b/indra/llcommon/llptrto.h diff --git a/indra/llcommon/llqueuedthread.cpp b/indra/llcommon/llqueuedthread.cpp index abf47a0f57..abf47a0f57 100644..100755 --- a/indra/llcommon/llqueuedthread.cpp +++ b/indra/llcommon/llqueuedthread.cpp diff --git a/indra/llcommon/llqueuedthread.h b/indra/llcommon/llqueuedthread.h index d3704b0fe2..d3704b0fe2 100644..100755 --- a/indra/llcommon/llqueuedthread.h +++ b/indra/llcommon/llqueuedthread.h diff --git a/indra/llcommon/llrand.cpp b/indra/llcommon/llrand.cpp index cb28a8f5c3..cb28a8f5c3 100644..100755 --- a/indra/llcommon/llrand.cpp +++ b/indra/llcommon/llrand.cpp diff --git a/indra/llcommon/llrand.h b/indra/llcommon/llrand.h index ad317d5bf7..ad317d5bf7 100644..100755 --- a/indra/llcommon/llrand.h +++ b/indra/llcommon/llrand.h diff --git a/indra/llcommon/llrefcount.cpp b/indra/llcommon/llrefcount.cpp index e1876599fc..e1876599fc 100644..100755 --- a/indra/llcommon/llrefcount.cpp +++ b/indra/llcommon/llrefcount.cpp diff --git a/indra/llcommon/llrefcount.h b/indra/llcommon/llrefcount.h index 8eb5d53f3f..32ae15435a 100644..100755 --- a/indra/llcommon/llrefcount.h +++ b/indra/llcommon/llrefcount.h @@ -27,6 +27,7 @@  #define LLREFCOUNT_H  #include <boost/noncopyable.hpp> +#include <boost/intrusive_ptr.hpp>  #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/llregistry.h b/indra/llcommon/llregistry.h index 853c427a13..bb0d60247e 100644..100755 --- a/indra/llcommon/llregistry.h +++ b/indra/llcommon/llregistry.h @@ -307,6 +307,10 @@ public:  		virtual ~StaticRegistrar() {}  		StaticRegistrar(ref_const_key_t key, ref_const_value_t value)  		{ +			if (singleton_t::instance().exists(key)) +			{ +				llerrs << "Duplicate registry entry under key \"" << key << "\"" << llendl; +			}  			singleton_t::instance().mStaticScope->add(key, value);  		}  	}; diff --git a/indra/llcommon/llrun.cpp b/indra/llcommon/llrun.cpp index f5d3f302fa..f5d3f302fa 100644..100755 --- a/indra/llcommon/llrun.cpp +++ b/indra/llcommon/llrun.cpp diff --git a/indra/llcommon/llrun.h b/indra/llcommon/llrun.h index a117405366..a117405366 100644..100755 --- a/indra/llcommon/llrun.h +++ b/indra/llcommon/llrun.h diff --git a/indra/llcommon/llsafehandle.h b/indra/llcommon/llsafehandle.h index 8d52d9bb15..8d52d9bb15 100644..100755 --- a/indra/llcommon/llsafehandle.h +++ b/indra/llcommon/llsafehandle.h diff --git a/indra/llcommon/llsd.cpp b/indra/llcommon/llsd.cpp index 8276ec836a..8276ec836a 100644..100755 --- a/indra/llcommon/llsd.cpp +++ b/indra/llcommon/llsd.cpp diff --git a/indra/llcommon/llsd.h b/indra/llcommon/llsd.h index 5eb69059ac..5eb69059ac 100644..100755 --- a/indra/llcommon/llsd.h +++ b/indra/llcommon/llsd.h diff --git a/indra/llcommon/llsdparam.cpp b/indra/llcommon/llsdparam.cpp index 0e29873bb0..9f4460a988 100644..100755 --- a/indra/llcommon/llsdparam.cpp +++ b/indra/llcommon/llsdparam.cpp @@ -223,10 +223,14 @@ LLSD& LLParamSDParserUtilities::getSDWriteNode(LLSD& input, LLInitParam::Parser:  	{  		bool new_traversal = it->second; -		LLSD* child_sd = it->first.empty() ? sd_to_write : &(*sd_to_write)[it->first]; - -		if (child_sd->isArray()) +		LLSD* child_sd; +		if (it->first.empty())  		{ +			child_sd = sd_to_write; +			if (child_sd->isUndefined()) +			{ +				*child_sd = LLSD::emptyArray(); +			}  			if (new_traversal)  			{  				// write to new element at end @@ -240,22 +244,7 @@ LLSD& LLParamSDParserUtilities::getSDWriteNode(LLSD& input, LLInitParam::Parser:  		}  		else  		{ -			if (new_traversal  -				&& child_sd->isDefined()  -				&& !child_sd->isArray()) -			{ -				// copy child contents into first element of an array -				LLSD new_array = LLSD::emptyArray(); -				new_array.append(*child_sd); -				// assign array to slot that previously held the single value -				*child_sd = new_array; -				// return next element in that array -				sd_to_write = &((*child_sd)[1]); -			} -			else -			{ -				sd_to_write = child_sd; -			} +			sd_to_write = &(*sd_to_write)[it->first];  		}  		it->second = false;  	} @@ -283,8 +272,9 @@ void LLParamSDParserUtilities::readSDValues(read_sd_cb_t cb, const LLSD& sd, LLI  			it != sd.endArray();  			++it)  		{ -			stack.back().second = true; +			stack.push_back(make_pair(std::string(), true));  			readSDValues(cb, *it, stack); +			stack.pop_back();  		}  	}  	else if (sd.isUndefined()) @@ -313,8 +303,14 @@ namespace LLInitParam  {  	// LLSD specialization  	// block param interface -	bool ParamValue<LLSD, TypeValues<LLSD>, false>::deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack, bool new_name) +	bool ParamValue<LLSD, NOT_BLOCK>::deserializeBlock(Parser& p, Parser::name_stack_range_t& name_stack, bool new_name)  	{ +		if (name_stack.first == name_stack.second +			&& p.readValue<LLSD>(mValue)) +		{ +			return true; +		} +  		LLSD& sd = LLParamSDParserUtilities::getSDWriteNode(mValue, name_stack);  		LLSD::String string; @@ -328,15 +324,18 @@ namespace LLInitParam  	}  	//static -	void ParamValue<LLSD, TypeValues<LLSD>, false>::serializeElement(Parser& p, const LLSD& sd, Parser::name_stack_t& name_stack) +	void ParamValue<LLSD, NOT_BLOCK>::serializeElement(Parser& p, const LLSD& sd, Parser::name_stack_t& name_stack)  	{  		p.writeValue<LLSD::String>(sd.asString(), name_stack);  	} -	void ParamValue<LLSD, TypeValues<LLSD>, false>::serializeBlock(Parser& p, Parser::name_stack_t& name_stack, const BaseBlock* diff_block) const +	void ParamValue<LLSD, NOT_BLOCK>::serializeBlock(Parser& p, Parser::name_stack_t& name_stack, const BaseBlock* diff_block) const  	{ -		// read from LLSD value and serialize out to parser (which could be LLSD, XUI, etc) -		Parser::name_stack_t stack; -		LLParamSDParserUtilities::readSDValues(boost::bind(&serializeElement, boost::ref(p), _1, _2), mValue, stack); +		// attempt to write LLSD out directly +		if (!p.writeValue<LLSD>(mValue, name_stack)) +		{ +			// otherwise read from LLSD value and serialize out to parser (which could be LLSD, XUI, etc) +			LLParamSDParserUtilities::readSDValues(boost::bind(&serializeElement, boost::ref(p), _1, _2), mValue, name_stack); +		}  	}  } diff --git a/indra/llcommon/llsdparam.h b/indra/llcommon/llsdparam.h index 6ef5debd7b..6ef5debd7b 100644..100755 --- a/indra/llcommon/llsdparam.h +++ b/indra/llcommon/llsdparam.h diff --git a/indra/llcommon/llsdserialize.cpp b/indra/llcommon/llsdserialize.cpp index 6b549e4b6f..ad4fce6f35 100644..100755 --- a/indra/llcommon/llsdserialize.cpp +++ b/indra/llcommon/llsdserialize.cpp @@ -1453,8 +1453,8 @@ S32 LLSDBinaryFormatter::format(const LLSD& data, std::ostream& ostr, U32 option  	case LLSD::TypeUUID:  	{  		ostr.put('u'); -		LLSD::UUID value = data.asUUID(); -		ostr.write((const char*)(&value.mData), UUID_BYTES); +		LLUUID temp = data.asUUID(); +		ostr.write((const char*)(&(temp.mData)), UUID_BYTES);  		break;  	} diff --git a/indra/llcommon/llsdserialize.h b/indra/llcommon/llsdserialize.h index 86e3fc864c..e7a5507385 100644..100755 --- 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<LLSDXMLParser> p = new LLSDXMLParser; +		LLPointer<LLSDXMLParser> 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<LLSDXMLParser> p = new LLSDXMLParser(); +		LLPointer<LLSDXMLParser> 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..100755 --- 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))  {  } diff --git a/indra/llcommon/llsdserialize_xml.h b/indra/llcommon/llsdserialize_xml.h index dcc5f3d3c7..dcc5f3d3c7 100644..100755 --- a/indra/llcommon/llsdserialize_xml.h +++ b/indra/llcommon/llsdserialize_xml.h diff --git a/indra/llcommon/llsdutil.cpp b/indra/llcommon/llsdutil.cpp index 803417d368..803417d368 100644..100755 --- a/indra/llcommon/llsdutil.cpp +++ b/indra/llcommon/llsdutil.cpp diff --git a/indra/llcommon/llsdutil.h b/indra/llcommon/llsdutil.h index 532d3f9341..532d3f9341 100644..100755 --- a/indra/llcommon/llsdutil.h +++ b/indra/llcommon/llsdutil.h diff --git a/indra/llcommon/llsecondlifeurls.cpp b/indra/llcommon/llsecondlifeurls.cpp index 9154e05e43..9154e05e43 100644..100755 --- a/indra/llcommon/llsecondlifeurls.cpp +++ b/indra/llcommon/llsecondlifeurls.cpp diff --git a/indra/llcommon/llsecondlifeurls.h b/indra/llcommon/llsecondlifeurls.h index 62f357ffed..62f357ffed 100644..100755 --- a/indra/llcommon/llsecondlifeurls.h +++ b/indra/llcommon/llsecondlifeurls.h diff --git a/indra/llcommon/llsimplehash.h b/indra/llcommon/llsimplehash.h index 727b4568d8..727b4568d8 100644..100755 --- a/indra/llcommon/llsimplehash.h +++ b/indra/llcommon/llsimplehash.h diff --git a/indra/llcommon/llsingleton.cpp b/indra/llcommon/llsingleton.cpp index eb8e2c9456..eb8e2c9456 100644..100755 --- a/indra/llcommon/llsingleton.cpp +++ b/indra/llcommon/llsingleton.cpp diff --git a/indra/llcommon/llsingleton.h b/indra/llcommon/llsingleton.h index 49d99f2cd0..49d99f2cd0 100644..100755 --- a/indra/llcommon/llsingleton.h +++ b/indra/llcommon/llsingleton.h diff --git a/indra/llcommon/llskiplist.h b/indra/llcommon/llskiplist.h index ed132381f9..ed132381f9 100644..100755 --- a/indra/llcommon/llskiplist.h +++ b/indra/llcommon/llskiplist.h diff --git a/indra/llcommon/llskipmap.h b/indra/llcommon/llskipmap.h index 49ff2928d1..49ff2928d1 100644..100755 --- a/indra/llcommon/llskipmap.h +++ b/indra/llcommon/llskipmap.h diff --git a/indra/llcommon/llsmoothstep.h b/indra/llcommon/llsmoothstep.h index 1f97a3ec89..1f97a3ec89 100644..100755 --- a/indra/llcommon/llsmoothstep.h +++ b/indra/llcommon/llsmoothstep.h diff --git a/indra/llcommon/llsortedvector.h b/indra/llcommon/llsortedvector.h index 391b82ee44..391b82ee44 100644..100755 --- a/indra/llcommon/llsortedvector.h +++ b/indra/llcommon/llsortedvector.h diff --git a/indra/llcommon/llstack.h b/indra/llcommon/llstack.h index 315de6ba2d..315de6ba2d 100644..100755 --- a/indra/llcommon/llstack.h +++ b/indra/llcommon/llstack.h diff --git a/indra/llcommon/llstacktrace.cpp b/indra/llcommon/llstacktrace.cpp index ccd7ef91c2..ccd7ef91c2 100644..100755 --- a/indra/llcommon/llstacktrace.cpp +++ b/indra/llcommon/llstacktrace.cpp diff --git a/indra/llcommon/llstacktrace.h b/indra/llcommon/llstacktrace.h index ca72c64c5d..ca72c64c5d 100644..100755 --- a/indra/llcommon/llstacktrace.h +++ b/indra/llcommon/llstacktrace.h diff --git a/indra/llcommon/llstat.cpp b/indra/llcommon/llstat.cpp index 3678c8e1c1..3678c8e1c1 100644..100755 --- a/indra/llcommon/llstat.cpp +++ b/indra/llcommon/llstat.cpp diff --git a/indra/llcommon/llstat.h b/indra/llcommon/llstat.h index 38377a010b..38377a010b 100644..100755 --- a/indra/llcommon/llstat.h +++ b/indra/llcommon/llstat.h diff --git a/indra/llcommon/llstatenums.h b/indra/llcommon/llstatenums.h index 81c4085d16..81c4085d16 100644..100755 --- a/indra/llcommon/llstatenums.h +++ b/indra/llcommon/llstatenums.h diff --git a/indra/llcommon/llstl.h b/indra/llcommon/llstl.h index d3941e1bc9..d3941e1bc9 100644..100755 --- a/indra/llcommon/llstl.h +++ b/indra/llcommon/llstl.h diff --git a/indra/llcommon/llstreamqueue.cpp b/indra/llcommon/llstreamqueue.cpp index 1116a2b6a2..1116a2b6a2 100644..100755 --- a/indra/llcommon/llstreamqueue.cpp +++ b/indra/llcommon/llstreamqueue.cpp diff --git a/indra/llcommon/llstreamqueue.h b/indra/llcommon/llstreamqueue.h index 0726bad175..0726bad175 100644..100755 --- a/indra/llcommon/llstreamqueue.h +++ b/indra/llcommon/llstreamqueue.h diff --git a/indra/llcommon/llstreamtools.cpp b/indra/llcommon/llstreamtools.cpp index d7a6f47932..d7a6f47932 100644..100755 --- a/indra/llcommon/llstreamtools.cpp +++ b/indra/llcommon/llstreamtools.cpp diff --git a/indra/llcommon/llstreamtools.h b/indra/llcommon/llstreamtools.h index 1b04bf91d7..1b04bf91d7 100644..100755 --- a/indra/llcommon/llstreamtools.h +++ b/indra/llcommon/llstreamtools.h diff --git a/indra/llcommon/llstrider.h b/indra/llcommon/llstrider.h index ed9284d2c5..ed9284d2c5 100644..100755 --- a/indra/llcommon/llstrider.h +++ b/indra/llcommon/llstrider.h diff --git a/indra/llcommon/llstring.cpp b/indra/llcommon/llstring.cpp index 0c32679744..0c32679744 100644..100755 --- a/indra/llcommon/llstring.cpp +++ b/indra/llcommon/llstring.cpp diff --git a/indra/llcommon/llstring.h b/indra/llcommon/llstring.h index 119efc7957..119efc7957 100644..100755 --- a/indra/llcommon/llstring.h +++ b/indra/llcommon/llstring.h diff --git a/indra/llcommon/llstringtable.cpp b/indra/llcommon/llstringtable.cpp index 7ad3805351..7ad3805351 100644..100755 --- a/indra/llcommon/llstringtable.cpp +++ b/indra/llcommon/llstringtable.cpp diff --git a/indra/llcommon/llstringtable.h b/indra/llcommon/llstringtable.h index 59d7372ed4..59d7372ed4 100644..100755 --- a/indra/llcommon/llstringtable.h +++ b/indra/llcommon/llstringtable.h diff --git a/indra/llcommon/llsys.cpp b/indra/llcommon/llsys.cpp index c96f2191f3..57a6de9060 100644..100755 --- a/indra/llcommon/llsys.cpp +++ b/indra/llcommon/llsys.cpp @@ -80,6 +80,7 @@ using namespace llsd;  #	include <sys/sysinfo.h>  #   include <stdexcept>  const char MEMINFO_FILE[] = "/proc/meminfo"; +#   include <gnu/libc-version.h>  #elif LL_SOLARIS  #	include <stdio.h>  #	include <unistd.h> @@ -175,8 +176,41 @@ bool get_shell32_dll_version(DWORD& major, DWORD& minor, DWORD& build_number)  }  #endif // LL_WINDOWS +// Wrap boost::regex_match() with a function that doesn't throw. +template <typename S, typename M, typename R> +static bool regex_match_no_exc(const S& string, M& match, const R& regex) +{ +    try +    { +        return boost::regex_match(string, match, regex); +    } +    catch (const std::runtime_error& e) +    { +        LL_WARNS("LLMemoryInfo") << "error matching with '" << regex.str() << "': " +                                 << e.what() << ":\n'" << string << "'" << LL_ENDL; +        return false; +    } +} + +// Wrap boost::regex_search() with a function that doesn't throw. +template <typename S, typename M, typename R> +static bool regex_search_no_exc(const S& string, M& match, const R& regex) +{ +    try +    { +        return boost::regex_search(string, match, regex); +    } +    catch (const std::runtime_error& e) +    { +        LL_WARNS("LLMemoryInfo") << "error searching with '" << regex.str() << "': " +                                 << e.what() << ":\n'" << string << "'" << LL_ENDL; +        return false; +    } +} + +  LLOSInfo::LLOSInfo() : -	mMajorVer(0), mMinorVer(0), mBuild(0) +	mMajorVer(0), mMinorVer(0), mBuild(0), mOSVersionString("")	   {  #if LL_WINDOWS @@ -412,6 +446,102 @@ LLOSInfo::LLOSInfo() :  		mOSString = mOSStringSimple;  	} +#elif LL_LINUX +	 +	struct utsname un; +	if(uname(&un) != -1) +	{ +		mOSStringSimple.append(un.sysname); +		mOSStringSimple.append(" "); +		mOSStringSimple.append(un.release); + +		mOSString = mOSStringSimple; +		mOSString.append(" "); +		mOSString.append(un.version); +		mOSString.append(" "); +		mOSString.append(un.machine); + +		// Simplify 'Simple' +		std::string ostype = mOSStringSimple.substr(0, mOSStringSimple.find_first_of(" ", 0)); +		if (ostype == "Linux") +		{ +			// Only care about major and minor Linux versions, truncate at second '.' +			std::string::size_type idx1 = mOSStringSimple.find_first_of(".", 0); +			std::string::size_type idx2 = (idx1 != std::string::npos) ? mOSStringSimple.find_first_of(".", idx1+1) : std::string::npos; +			std::string simple = mOSStringSimple.substr(0, idx2); +			if (simple.length() > 0) +				mOSStringSimple = simple; +		} +	} +	else +	{ +		mOSStringSimple.append("Unable to collect OS info"); +		mOSString = mOSStringSimple; +	} + +	const char OS_VERSION_MATCH_EXPRESSION[] = "([0-9]+)\\.([0-9]+)(\\.([0-9]+))?"; +	boost::regex os_version_parse(OS_VERSION_MATCH_EXPRESSION); +	boost::smatch matched; + +	std::string glibc_version(gnu_get_libc_version()); +	if ( regex_match_no_exc(glibc_version, matched, os_version_parse) ) +	{ +		LL_INFOS("AppInit") << "Using glibc version '" << glibc_version << "' as OS version" << LL_ENDL; +	 +		std::string version_value; + +		if ( matched[1].matched ) // Major version +		{ +			version_value.assign(matched[1].first, matched[1].second); +			if (sscanf(version_value.c_str(), "%d", &mMajorVer) != 1) +			{ +			  LL_WARNS("AppInit") << "failed to parse major version '" << version_value << "' as a number" << LL_ENDL; +			} +		} +		else +		{ +			LL_ERRS("AppInit") +				<< "OS version regex '" << OS_VERSION_MATCH_EXPRESSION  +				<< "' returned true, but major version [1] did not match" +				<< LL_ENDL; +		} + +		if ( matched[2].matched ) // Minor version +		{ +			version_value.assign(matched[2].first, matched[2].second); +			if (sscanf(version_value.c_str(), "%d", &mMinorVer) != 1) +			{ +			  LL_ERRS("AppInit") << "failed to parse minor version '" << version_value << "' as a number" << LL_ENDL; +			} +		} +		else +		{ +			LL_ERRS("AppInit") +				<< "OS version regex '" << OS_VERSION_MATCH_EXPRESSION  +				<< "' returned true, but minor version [1] did not match" +				<< LL_ENDL; +		} + +		if ( matched[4].matched ) // Build version (optional) - note that [3] includes the '.' +		{ +			version_value.assign(matched[4].first, matched[4].second); +			if (sscanf(version_value.c_str(), "%d", &mBuild) != 1) +			{ +			  LL_ERRS("AppInit") << "failed to parse build version '" << version_value << "' as a number" << LL_ENDL; +			} +		} +		else +		{ +			LL_INFOS("AppInit") +				<< "OS build version not provided; using zero" +				<< LL_ENDL; +		} +	} +	else +	{ +		LL_WARNS("AppInit") << "glibc version '" << glibc_version << "' cannot be parsed to three numbers; using all zeros" << LL_ENDL; +	} +  #else  	struct utsname un; @@ -444,8 +574,13 @@ LLOSInfo::LLOSInfo() :  		mOSStringSimple.append("Unable to collect OS info");  		mOSString = mOSStringSimple;  	} +  #endif +	std::stringstream dotted_version_string; +	dotted_version_string << mMajorVer << "." << mMinorVer << "." << mBuild; +	mOSVersionString.append(dotted_version_string.str()); +  }  #ifndef LL_WINDOWS @@ -496,6 +631,11 @@ const std::string& LLOSInfo::getOSStringSimple() const  	return mOSStringSimple;  } +const std::string& LLOSInfo::getOSVersionString() const +{ +	return mOSVersionString; +} +  const S32 STATUS_SIZE = 8192;  //static @@ -687,38 +827,6 @@ private:  	LLSD mStats;  }; -// Wrap boost::regex_match() with a function that doesn't throw. -template <typename S, typename M, typename R> -static bool regex_match_no_exc(const S& string, M& match, const R& regex) -{ -    try -    { -        return boost::regex_match(string, match, regex); -    } -    catch (const std::runtime_error& e) -    { -        LL_WARNS("LLMemoryInfo") << "error matching with '" << regex.str() << "': " -                                 << e.what() << ":\n'" << string << "'" << LL_ENDL; -        return false; -    } -} - -// Wrap boost::regex_search() with a function that doesn't throw. -template <typename S, typename M, typename R> -static bool regex_search_no_exc(const S& string, M& match, const R& regex) -{ -    try -    { -        return boost::regex_search(string, match, regex); -    } -    catch (const std::runtime_error& e) -    { -        LL_WARNS("LLMemoryInfo") << "error searching with '" << regex.str() << "': " -                                 << e.what() << ":\n'" << string << "'" << LL_ENDL; -        return false; -    } -} -  LLMemoryInfo::LLMemoryInfo()  {  	refresh(); diff --git a/indra/llcommon/llsys.h b/indra/llcommon/llsys.h index 739e795d3a..cfed0fff17 100644..100755 --- a/indra/llcommon/llsys.h +++ b/indra/llcommon/llsys.h @@ -49,6 +49,8 @@ public:  	const std::string& getOSString() const;  	const std::string& getOSStringSimple() const; +	const std::string& getOSVersionString() const; +	  	S32 mMajorVer;  	S32 mMinorVer;  	S32 mBuild; @@ -62,6 +64,7 @@ public:  private:  	std::string mOSString;  	std::string mOSStringSimple; +	std::string mOSVersionString;  }; diff --git a/indra/llcommon/llthread.cpp b/indra/llcommon/llthread.cpp index 1d56a52c32..1d56a52c32 100644..100755 --- a/indra/llcommon/llthread.cpp +++ b/indra/llcommon/llthread.cpp diff --git a/indra/llcommon/llthread.h b/indra/llcommon/llthread.h index 5c8bbca2ca..0fb89c5613 100644..100755 --- 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; @@ -284,6 +285,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 diff --git a/indra/llcommon/llthreadsafequeue.cpp b/indra/llcommon/llthreadsafequeue.cpp index 8a73e632a9..8a73e632a9 100644..100755 --- a/indra/llcommon/llthreadsafequeue.cpp +++ b/indra/llcommon/llthreadsafequeue.cpp diff --git a/indra/llcommon/llthreadsafequeue.h b/indra/llcommon/llthreadsafequeue.h index 58cac38769..58cac38769 100644..100755 --- a/indra/llcommon/llthreadsafequeue.h +++ b/indra/llcommon/llthreadsafequeue.h diff --git a/indra/llcommon/lltimer.cpp b/indra/llcommon/lltimer.cpp index 9ebc6de7f4..9ebc6de7f4 100644..100755 --- a/indra/llcommon/lltimer.cpp +++ b/indra/llcommon/lltimer.cpp diff --git a/indra/llcommon/lltimer.h b/indra/llcommon/lltimer.h index 513de0605d..513de0605d 100644..100755 --- a/indra/llcommon/lltimer.h +++ b/indra/llcommon/lltimer.h diff --git a/indra/llcommon/lltreeiterators.h b/indra/llcommon/lltreeiterators.h index ba861ae70b..ba861ae70b 100644..100755 --- a/indra/llcommon/lltreeiterators.h +++ b/indra/llcommon/lltreeiterators.h diff --git a/indra/llcommon/lltypeinfolookup.h b/indra/llcommon/lltypeinfolookup.h index 0b6862444e..0b6862444e 100644..100755 --- a/indra/llcommon/lltypeinfolookup.h +++ b/indra/llcommon/lltypeinfolookup.h diff --git a/indra/llcommon/lluri.cpp b/indra/llcommon/lluri.cpp index 21456a599b..21456a599b 100644..100755 --- a/indra/llcommon/lluri.cpp +++ b/indra/llcommon/lluri.cpp diff --git a/indra/llcommon/lluri.h b/indra/llcommon/lluri.h index c82a666e48..c82a666e48 100644..100755 --- a/indra/llcommon/lluri.h +++ b/indra/llcommon/lluri.h diff --git a/indra/llcommon/lluuid.cpp b/indra/llcommon/lluuid.cpp index 0aaa50d231..0aaa50d231 100644..100755 --- a/indra/llcommon/lluuid.cpp +++ b/indra/llcommon/lluuid.cpp diff --git a/indra/llcommon/lluuid.h b/indra/llcommon/lluuid.h index 7889828c85..7889828c85 100644..100755 --- a/indra/llcommon/lluuid.h +++ b/indra/llcommon/lluuid.h diff --git a/indra/llcommon/lluuidhashmap.h b/indra/llcommon/lluuidhashmap.h index e294670030..e294670030 100644..100755 --- a/indra/llcommon/lluuidhashmap.h +++ b/indra/llcommon/lluuidhashmap.h diff --git a/indra/llcommon/llversionserver.h b/indra/llcommon/llversionserver.h index b19ba3bf74..ef68a0eaf5 100644..100755 --- 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 deleted file mode 100644 index 39f9de3bc2..0000000000 --- a/indra/llcommon/llversionviewer.h +++ /dev/null @@ -1,41 +0,0 @@ -/**  - * @file llversionviewer.h - * @brief - * - * $LicenseInfo:firstyear=2002&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. - *  - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - *  - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU - * Lesser General Public License for more details. - *  - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA - *  - * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA - * $/LicenseInfo$ - */ - -#ifndef LL_LLVERSIONVIEWER_H -#define LL_LLVERSIONVIEWER_H - -const S32 LL_VERSION_MAJOR = 3; -const S32 LL_VERSION_MINOR = 4; -const S32 LL_VERSION_PATCH = 5; -const S32 LL_VERSION_BUILD = 0; - -const char * const LL_CHANNEL = "Second Life Developer"; - -#if LL_DARWIN -const char * const LL_VERSION_BUNDLE_ID = "com.secondlife.indra.viewer"; -#endif - -#endif diff --git a/indra/llcommon/llworkerthread.cpp b/indra/llcommon/llworkerthread.cpp index 3d05a30ac2..3d05a30ac2 100644..100755 --- a/indra/llcommon/llworkerthread.cpp +++ b/indra/llcommon/llworkerthread.cpp diff --git a/indra/llcommon/llworkerthread.h b/indra/llcommon/llworkerthread.h index be46394d6e..be46394d6e 100644..100755 --- a/indra/llcommon/llworkerthread.h +++ b/indra/llcommon/llworkerthread.h diff --git a/indra/llcommon/metaclass.cpp b/indra/llcommon/metaclass.cpp index 5e403511cf..5e403511cf 100644..100755 --- a/indra/llcommon/metaclass.cpp +++ b/indra/llcommon/metaclass.cpp diff --git a/indra/llcommon/metaclass.h b/indra/llcommon/metaclass.h index 626757d58d..626757d58d 100644..100755 --- a/indra/llcommon/metaclass.h +++ b/indra/llcommon/metaclass.h diff --git a/indra/llcommon/metaclasst.h b/indra/llcommon/metaclasst.h index b9a7ae219d..b9a7ae219d 100644..100755 --- a/indra/llcommon/metaclasst.h +++ b/indra/llcommon/metaclasst.h diff --git a/indra/llcommon/metaproperty.cpp b/indra/llcommon/metaproperty.cpp index 98d850bf1e..98d850bf1e 100644..100755 --- a/indra/llcommon/metaproperty.cpp +++ b/indra/llcommon/metaproperty.cpp diff --git a/indra/llcommon/metaproperty.h b/indra/llcommon/metaproperty.h index bd5bb1a30f..bd5bb1a30f 100644..100755 --- a/indra/llcommon/metaproperty.h +++ b/indra/llcommon/metaproperty.h diff --git a/indra/llcommon/metapropertyt.h b/indra/llcommon/metapropertyt.h index 7a36c161da..7a36c161da 100644..100755 --- a/indra/llcommon/metapropertyt.h +++ b/indra/llcommon/metapropertyt.h diff --git a/indra/llcommon/reflective.cpp b/indra/llcommon/reflective.cpp index 2cc0e7e1f2..2cc0e7e1f2 100644..100755 --- a/indra/llcommon/reflective.cpp +++ b/indra/llcommon/reflective.cpp diff --git a/indra/llcommon/reflective.h b/indra/llcommon/reflective.h index da5c5a2630..da5c5a2630 100644..100755 --- a/indra/llcommon/reflective.h +++ b/indra/llcommon/reflective.h diff --git a/indra/llcommon/reflectivet.h b/indra/llcommon/reflectivet.h index 958921f23e..958921f23e 100644..100755 --- a/indra/llcommon/reflectivet.h +++ b/indra/llcommon/reflectivet.h diff --git a/indra/llcommon/roles_constants.h b/indra/llcommon/roles_constants.h index effd15ea72..effd15ea72 100644..100755 --- a/indra/llcommon/roles_constants.h +++ b/indra/llcommon/roles_constants.h diff --git a/indra/llcommon/stdenums.h b/indra/llcommon/stdenums.h index 40b3364b36..efcbe76795 100644..100755 --- 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. diff --git a/indra/llcommon/stdtypes.h b/indra/llcommon/stdtypes.h index bf3f3f9ee8..bf3f3f9ee8 100644..100755 --- a/indra/llcommon/stdtypes.h +++ b/indra/llcommon/stdtypes.h diff --git a/indra/llcommon/string_table.h b/indra/llcommon/string_table.h index fe6416fb50..fe6416fb50 100644..100755 --- a/indra/llcommon/string_table.h +++ b/indra/llcommon/string_table.h diff --git a/indra/llcommon/stringize.h b/indra/llcommon/stringize.h index 72f2e58ce1..72f2e58ce1 100644..100755 --- a/indra/llcommon/stringize.h +++ b/indra/llcommon/stringize.h diff --git a/indra/llcommon/tests/StringVec.h b/indra/llcommon/tests/StringVec.h index a380b00a05..a380b00a05 100644..100755 --- a/indra/llcommon/tests/StringVec.h +++ b/indra/llcommon/tests/StringVec.h diff --git a/indra/llcommon/tests/bitpack_test.cpp b/indra/llcommon/tests/bitpack_test.cpp index 4c3bc674af..afc0c18cd0 100644..100755 --- 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,21 +80,20 @@ 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); -		ensure("keep compiler quiet", unpack_bufsize == unpack_bufsize);  	}  	// U32 packing diff --git a/indra/llcommon/tests/commonmisc_test.cpp b/indra/llcommon/tests/commonmisc_test.cpp index b115c153c1..b115c153c1 100644..100755 --- a/indra/llcommon/tests/commonmisc_test.cpp +++ b/indra/llcommon/tests/commonmisc_test.cpp diff --git a/indra/llcommon/tests/listener.h b/indra/llcommon/tests/listener.h index 9c5c18a150..9c5c18a150 100644..100755 --- a/indra/llcommon/tests/listener.h +++ b/indra/llcommon/tests/listener.h diff --git a/indra/llcommon/tests/llallocator_heap_profile_test.cpp b/indra/llcommon/tests/llallocator_heap_profile_test.cpp index 44a9705803..44a9705803 100644..100755 --- a/indra/llcommon/tests/llallocator_heap_profile_test.cpp +++ b/indra/llcommon/tests/llallocator_heap_profile_test.cpp diff --git a/indra/llcommon/tests/llallocator_test.cpp b/indra/llcommon/tests/llallocator_test.cpp index 4e62eaee67..4e62eaee67 100644..100755 --- a/indra/llcommon/tests/llallocator_test.cpp +++ b/indra/llcommon/tests/llallocator_test.cpp diff --git a/indra/llcommon/tests/llbase64_test.cpp b/indra/llcommon/tests/llbase64_test.cpp index d0394150fa..d0394150fa 100644..100755 --- a/indra/llcommon/tests/llbase64_test.cpp +++ b/indra/llcommon/tests/llbase64_test.cpp diff --git a/indra/llcommon/tests/lldate_test.cpp b/indra/llcommon/tests/lldate_test.cpp index 7c95ccb91f..7c95ccb91f 100644..100755 --- a/indra/llcommon/tests/lldate_test.cpp +++ b/indra/llcommon/tests/lldate_test.cpp diff --git a/indra/llcommon/tests/lldependencies_test.cpp b/indra/llcommon/tests/lldependencies_test.cpp index 5395d785b6..5395d785b6 100644..100755 --- a/indra/llcommon/tests/lldependencies_test.cpp +++ b/indra/llcommon/tests/lldependencies_test.cpp diff --git a/indra/llcommon/tests/llerror_test.cpp b/indra/llcommon/tests/llerror_test.cpp index 279a90e51b..279a90e51b 100644..100755 --- a/indra/llcommon/tests/llerror_test.cpp +++ b/indra/llcommon/tests/llerror_test.cpp diff --git a/indra/llcommon/tests/lleventcoro_test.cpp b/indra/llcommon/tests/lleventcoro_test.cpp index 8d12529613..8d12529613 100644..100755 --- a/indra/llcommon/tests/lleventcoro_test.cpp +++ b/indra/llcommon/tests/lleventcoro_test.cpp diff --git a/indra/llcommon/tests/lleventdispatcher_test.cpp b/indra/llcommon/tests/lleventdispatcher_test.cpp index 263c9b171f..263c9b171f 100644..100755 --- a/indra/llcommon/tests/lleventdispatcher_test.cpp +++ b/indra/llcommon/tests/lleventdispatcher_test.cpp diff --git a/indra/llcommon/tests/lleventfilter_test.cpp b/indra/llcommon/tests/lleventfilter_test.cpp index ca05ef62a9..ca05ef62a9 100644..100755 --- a/indra/llcommon/tests/lleventfilter_test.cpp +++ b/indra/llcommon/tests/lleventfilter_test.cpp diff --git a/indra/llcommon/tests/llframetimer_test.cpp b/indra/llcommon/tests/llframetimer_test.cpp index 8ac1c91a3a..8ac1c91a3a 100644..100755 --- a/indra/llcommon/tests/llframetimer_test.cpp +++ b/indra/llcommon/tests/llframetimer_test.cpp diff --git a/indra/llcommon/tests/llinstancetracker_test.cpp b/indra/llcommon/tests/llinstancetracker_test.cpp index 454695ff9f..e769c3e22c 100644..100755 --- 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/lllazy_test.cpp b/indra/llcommon/tests/lllazy_test.cpp index 32a717f4fc..32a717f4fc 100644..100755 --- a/indra/llcommon/tests/lllazy_test.cpp +++ b/indra/llcommon/tests/lllazy_test.cpp diff --git a/indra/llcommon/tests/llleap_test.cpp b/indra/llcommon/tests/llleap_test.cpp index 9b755e9ca5..29060d4ef5 100644..100755 --- a/indra/llcommon/tests/llleap_test.cpp +++ b/indra/llcommon/tests/llleap_test.cpp @@ -122,13 +122,10 @@ namespace tut                     // finding indra/lib/python. Use our __FILE__, with                     // raw-string syntax to deal with Windows pathnames.                     "mydir = os.path.dirname(r'" << __FILE__ << "')\n" -                   "try:\n" -                   "    from llbase import llsd\n" -                   "except ImportError:\n"                     // We expect mydir to be .../indra/llcommon/tests. -                   "    sys.path.insert(0,\n" -                   "        os.path.join(mydir, os.pardir, os.pardir, 'lib', 'python'))\n" -                   "    from indra.base import llsd\n" +                   "sys.path.insert(0,\n" +                   "    os.path.join(mydir, os.pardir, os.pardir, 'lib', 'python'))\n" +                   "from indra.base import llsd\n"                     "\n"                     "class ProtocolError(Exception):\n"                     "    def __init__(self, msg, data):\n" diff --git a/indra/llcommon/tests/llmemtype_test.cpp b/indra/llcommon/tests/llmemtype_test.cpp index 1f050d6dc7..1f050d6dc7 100644..100755 --- a/indra/llcommon/tests/llmemtype_test.cpp +++ b/indra/llcommon/tests/llmemtype_test.cpp diff --git a/indra/llcommon/tests/llprocess_test.cpp b/indra/llcommon/tests/llprocess_test.cpp index 99186ed434..6f1e7d46b8 100644..100755 --- a/indra/llcommon/tests/llprocess_test.cpp +++ b/indra/llcommon/tests/llprocess_test.cpp @@ -608,6 +608,9 @@ namespace tut      void object::test<5>()      {          set_test_name("exit(2)"); +#if LL_WINDOWS +		skip("MAINT-2302: This frequently (though not always) fails on Windows."); +#endif          PythonProcessLauncher py(get_test_name(),                                   "import sys\n"                                   "sys.exit(2)\n"); @@ -620,6 +623,9 @@ namespace tut      void object::test<6>()      {          set_test_name("syntax_error:"); +#if LL_WINDOWS +		skip("MAINT-2302: This frequently (though not always) fails on Windows."); +#endif          PythonProcessLauncher py(get_test_name(),                                   "syntax_error:\n");          py.mParams.files.add(LLProcess::FileParam()); // inherit stdin @@ -641,6 +647,9 @@ namespace tut      void object::test<7>()      {          set_test_name("explicit kill()"); +#if LL_WINDOWS +		skip("MAINT-2302: This frequently (though not always) fails on Windows."); +#endif          PythonProcessLauncher py(get_test_name(),                                   "from __future__ import with_statement\n"                                   "import sys, time\n" @@ -685,6 +694,9 @@ namespace tut      void object::test<8>()      {          set_test_name("implicit kill()"); +#if LL_WINDOWS +		skip("MAINT-2302: This frequently (though not always) fails on Windows."); +#endif          NamedTempFile out("out", "not started");          LLProcess::handle phandle(0);          { diff --git a/indra/llcommon/tests/llprocessor_test.cpp b/indra/llcommon/tests/llprocessor_test.cpp index 884e1b5e5b..884e1b5e5b 100644..100755 --- a/indra/llcommon/tests/llprocessor_test.cpp +++ b/indra/llcommon/tests/llprocessor_test.cpp diff --git a/indra/llcommon/tests/llrand_test.cpp b/indra/llcommon/tests/llrand_test.cpp index 383e6f9e0a..383e6f9e0a 100644..100755 --- a/indra/llcommon/tests/llrand_test.cpp +++ b/indra/llcommon/tests/llrand_test.cpp diff --git a/indra/llcommon/tests/llsdserialize_test.cpp b/indra/llcommon/tests/llsdserialize_test.cpp index e625545763..4d436e8897 100644..100755 --- a/indra/llcommon/tests/llsdserialize_test.cpp +++ b/indra/llcommon/tests/llsdserialize_test.cpp @@ -1523,10 +1523,7 @@ namespace tut                          "sys.path.insert(0,\n"                          "    os.path.join(os.path.dirname(r'" __FILE__ "'),\n"                          "                 os.pardir, os.pardir, 'lib', 'python'))\n" -                        "try:\n" -                        "    from llbase import llsd\n" -                        "except ImportError:\n" -                        "    from indra.base import llsd\n") +                        "from indra.base import llsd\n")          {}          ~TestPythonCompatible() {} diff --git a/indra/llcommon/tests/llsingleton_test.cpp b/indra/llcommon/tests/llsingleton_test.cpp index 385289aefe..385289aefe 100644..100755 --- a/indra/llcommon/tests/llsingleton_test.cpp +++ b/indra/llcommon/tests/llsingleton_test.cpp diff --git a/indra/llcommon/tests/llstreamqueue_test.cpp b/indra/llcommon/tests/llstreamqueue_test.cpp index 050ad5c5bf..050ad5c5bf 100644..100755 --- a/indra/llcommon/tests/llstreamqueue_test.cpp +++ b/indra/llcommon/tests/llstreamqueue_test.cpp diff --git a/indra/llcommon/tests/llstring_test.cpp b/indra/llcommon/tests/llstring_test.cpp index 93d3968dbf..93d3968dbf 100644..100755 --- a/indra/llcommon/tests/llstring_test.cpp +++ b/indra/llcommon/tests/llstring_test.cpp diff --git a/indra/llcommon/tests/lltreeiterators_test.cpp b/indra/llcommon/tests/lltreeiterators_test.cpp index 1d619867d4..1d619867d4 100644..100755 --- a/indra/llcommon/tests/lltreeiterators_test.cpp +++ b/indra/llcommon/tests/lltreeiterators_test.cpp diff --git a/indra/llcommon/tests/lluri_test.cpp b/indra/llcommon/tests/lluri_test.cpp index 4c64f15ca7..4c64f15ca7 100644..100755 --- a/indra/llcommon/tests/lluri_test.cpp +++ b/indra/llcommon/tests/lluri_test.cpp diff --git a/indra/llcommon/tests/reflection_test.cpp b/indra/llcommon/tests/reflection_test.cpp index 8980ebb1f1..8980ebb1f1 100644..100755 --- a/indra/llcommon/tests/reflection_test.cpp +++ b/indra/llcommon/tests/reflection_test.cpp diff --git a/indra/llcommon/tests/stringize_test.cpp b/indra/llcommon/tests/stringize_test.cpp index 3d34f23998..3d34f23998 100644..100755 --- a/indra/llcommon/tests/stringize_test.cpp +++ b/indra/llcommon/tests/stringize_test.cpp diff --git a/indra/llcommon/tests/wrapllerrs.h b/indra/llcommon/tests/wrapllerrs.h index a4d3a4e026..a4d3a4e026 100644..100755 --- a/indra/llcommon/tests/wrapllerrs.h +++ b/indra/llcommon/tests/wrapllerrs.h diff --git a/indra/llcommon/timer.h b/indra/llcommon/timer.h index 82d19c2d32..82d19c2d32 100644..100755 --- a/indra/llcommon/timer.h +++ b/indra/llcommon/timer.h diff --git a/indra/llcommon/timing.cpp b/indra/llcommon/timing.cpp index c2dc695ef3..c2dc695ef3 100644..100755 --- a/indra/llcommon/timing.cpp +++ b/indra/llcommon/timing.cpp diff --git a/indra/llcommon/timing.h b/indra/llcommon/timing.h index c408d4c446..c408d4c446 100644..100755 --- a/indra/llcommon/timing.h +++ b/indra/llcommon/timing.h diff --git a/indra/llcommon/u64.cpp b/indra/llcommon/u64.cpp index eea16c5036..eea16c5036 100644..100755 --- a/indra/llcommon/u64.cpp +++ b/indra/llcommon/u64.cpp diff --git a/indra/llcommon/u64.h b/indra/llcommon/u64.h index 75c8a59136..75c8a59136 100644..100755 --- a/indra/llcommon/u64.h +++ b/indra/llcommon/u64.h | 
