diff options
Diffstat (limited to 'indra/llcommon')
| -rwxr-xr-x | indra/llcommon/CMakeLists.txt | 1 | ||||
| -rwxr-xr-x | indra/llcommon/llerror.cpp | 444 | ||||
| -rwxr-xr-x | indra/llcommon/llerror.h | 4 | ||||
| -rwxr-xr-x | indra/llcommon/llerrorcontrol.h | 23 | ||||
| -rwxr-xr-x | indra/llcommon/llhttpstatuscodes.h | 89 | ||||
| -rwxr-xr-x | indra/llcommon/llinitparam.h | 3 | ||||
| -rwxr-xr-x | indra/llcommon/llpointer.h | 126 | ||||
| -rwxr-xr-x | indra/llcommon/llsd.cpp | 11 | ||||
| -rwxr-xr-x | indra/llcommon/llsd.h | 5 | ||||
| -rwxr-xr-x | indra/llcommon/llsdserialize.cpp | 65 | ||||
| -rwxr-xr-x | indra/llcommon/llsdserialize.h | 28 | ||||
| -rwxr-xr-x | indra/llcommon/llsdserialize_xml.cpp | 15 | ||||
| -rwxr-xr-x | indra/llcommon/llsdutil.cpp | 2 | ||||
| -rwxr-xr-x | indra/llcommon/lluuid.h | 13 | ||||
| -rwxr-xr-x | indra/llcommon/tests/llerror_test.cpp | 78 | ||||
| -rwxr-xr-x | indra/llcommon/tests/stringize_test.cpp | 2 | ||||
| -rwxr-xr-x | indra/llcommon/tests/wrapllerrs.h | 117 | 
17 files changed, 587 insertions, 439 deletions
| diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt index 81ccb756e0..763f5a3521 100755 --- a/indra/llcommon/CMakeLists.txt +++ b/indra/llcommon/CMakeLists.txt @@ -158,7 +158,6 @@ set(llcommon_HEADER_FILES      llhandle.h      llhash.h      llheartbeat.h -    llhttpstatuscodes.h      llindexedvector.h      llinitparam.h      llinstancetracker.h diff --git a/indra/llcommon/llerror.cpp b/indra/llcommon/llerror.cpp index a7963174ad..22cd861c72 100755 --- a/indra/llcommon/llerror.cpp +++ b/indra/llcommon/llerror.cpp @@ -47,6 +47,7 @@  #include "lllivefile.h"  #include "llsd.h"  #include "llsdserialize.h" +#include "llsingleton.h"  #include "llstl.h"  #include "lltimer.h" @@ -356,30 +357,31 @@ namespace  	typedef std::map<std::string, LLError::ELevel> LevelMap; -	typedef std::vector<LLError::Recorder*> Recorders; +	typedef std::vector<LLError::RecorderPtr> Recorders;  	typedef std::vector<LLError::CallSite*> CallSiteVector; -	class Globals +	class Globals : public LLSingleton<Globals>  	{  	public: +		Globals(); +  		std::ostringstream messageStream;  		bool messageStreamInUse;  		void addCallSite(LLError::CallSite&);  		void invalidateCallSites(); -		 -		static Globals& get(); -			// return the one instance of the globals  	private:  		CallSiteVector callSites; - -		Globals() -			:	messageStreamInUse(false) -			{ } -		  	}; +	Globals::Globals() +		: messageStream(), +		messageStreamInUse(false), +		callSites() +	{ +	} +  	void Globals::addCallSite(LLError::CallSite& site)  	{  		callSites.push_back(&site); @@ -396,25 +398,17 @@ namespace  		callSites.clear();  	} - -	Globals& Globals::get() -	{ -		/* This pattern, of returning a reference to a static function -		   variable, is to ensure that this global is constructed before -		   it is used, no matter what the global initialization sequence -		   is. -		   See C++ FAQ Lite, sections 10.12 through 10.14 -		*/ -		static Globals* globals = new Globals;		 -		return *globals; -	}  }  namespace LLError  { -	class Settings +	class SettingsConfig : public LLRefCount  	{ +		friend class Settings; +  	public: +		virtual ~SettingsConfig(); +  		bool                                mPrintLocation;  		LLError::ELevel                     mDefaultLevel; @@ -429,81 +423,86 @@ namespace LLError  		LLError::TimeFunction               mTimeFunction;  		Recorders                           mRecorders; -		Recorder*                           mFileRecorder; -		Recorder*                           mFixedBufferRecorder; +		RecorderPtr                         mFileRecorder; +		RecorderPtr                         mFixedBufferRecorder;  		std::string                         mFileRecorderFileName;  		int									mShouldLogCallCounter; -		static Settings& get(); +	private: +		SettingsConfig(); +	}; + +	typedef LLPointer<SettingsConfig> SettingsConfigPtr; + +	class Settings : public LLSingleton<Settings> +	{ +	public: +		Settings(); + +		SettingsConfigPtr getSettingsConfig(); -		static void reset(); -		static Settings* saveAndReset(); -		static void restore(Settings*); +		void reset(); +		SettingsStoragePtr saveAndReset(); +		void restore(SettingsStoragePtr pSettingsStorage);  	private: -		Settings() -		:	mPrintLocation(false), -			mDefaultLevel(LLError::LEVEL_DEBUG), -			mCrashFunction(), -			mTimeFunction(NULL), -			mFileRecorder(NULL), -			mFixedBufferRecorder(NULL), -			mShouldLogCallCounter(0) -			{ } -		 -		~Settings() -		{ -			for_each(mRecorders.begin(), mRecorders.end(), DeletePointer()); -			mRecorders.clear(); -		} -		 -		static Settings*& getPtr(); +		SettingsConfigPtr mSettingsConfig;  	}; -	Settings& Settings::get() +	SettingsConfig::SettingsConfig() +		: LLRefCount(), +		mPrintLocation(false), +		mDefaultLevel(LLError::LEVEL_DEBUG), +		mFunctionLevelMap(), +		mClassLevelMap(), +		mFileLevelMap(), +		mTagLevelMap(), +		mUniqueLogMessages(), +		mCrashFunction(NULL), +		mTimeFunction(NULL), +		mRecorders(), +		mFileRecorder(), +		mFixedBufferRecorder(), +		mFileRecorderFileName(), +		mShouldLogCallCounter(0)  	{ -		Settings* p = getPtr(); -		if (!p) -		{ -			reset(); -			p = getPtr(); -		} -		return *p;  	} -	 -	void Settings::reset() + +	SettingsConfig::~SettingsConfig()  	{ -		Globals::get().invalidateCallSites(); -		 -		Settings*& p = getPtr(); -		delete p; -		p = new Settings(); +		mRecorders.clear(); +	} + +	Settings::Settings() +		: LLSingleton<Settings>(), +		mSettingsConfig(new SettingsConfig()) +	{ +	} + +	SettingsConfigPtr Settings::getSettingsConfig() +	{ +		return mSettingsConfig;  	} -	Settings* Settings::saveAndReset() +	void Settings::reset()  	{ -		Globals::get().invalidateCallSites(); -		 -		Settings*& p = getPtr(); -		Settings* originalSettings = p; -		p = new Settings(); -		return originalSettings; +		Globals::getInstance()->invalidateCallSites(); +		mSettingsConfig = new SettingsConfig();  	} -	void Settings::restore(Settings* originalSettings) +	SettingsStoragePtr Settings::saveAndReset()  	{ -		Globals::get().invalidateCallSites(); -		 -		Settings*& p = getPtr(); -		delete p; -		p = originalSettings; +		SettingsStoragePtr oldSettingsConfig(mSettingsConfig.get()); +		reset(); +		return oldSettingsConfig;  	} -	Settings*& Settings::getPtr() +	void Settings::restore(SettingsStoragePtr pSettingsStorage)  	{ -		static Settings* currentSettings = NULL; -		return currentSettings; +		Globals::getInstance()->invalidateCallSites(); +		SettingsConfigPtr newSettingsConfig(dynamic_cast<SettingsConfig *>(pSettingsStorage.get())); +		mSettingsConfig = newSettingsConfig;  	}  } @@ -604,7 +603,7 @@ namespace  	void commonInit(const std::string& dir, bool log_to_stderr = true)  	{ -		LLError::Settings::reset(); +		LLError::Settings::getInstance()->reset();  		LLError::setDefaultLevel(LLError::LEVEL_INFO);  		LLError::setFatalFunction(LLError::crashAndLoop); @@ -613,11 +612,13 @@ namespace  		// log_to_stderr is only false in the unit and integration tests to keep builds quieter  		if (log_to_stderr && shouldLogToStderr())  		{ -			LLError::addRecorder(new RecordToStderr(stderrLogWantsTime())); +			LLError::RecorderPtr recordToStdErr(new RecordToStderr(stderrLogWantsTime())); +			LLError::addRecorder(recordToStdErr);  		}  #if LL_WINDOWS -		LLError::addRecorder(new RecordToWinDebug); +		LLError::RecorderPtr recordToWinDebug(new RecordToWinDebug()); +		LLError::addRecorder(recordToWinDebug);  #endif  		LogControlFile& e = LogControlFile::fromDirectory(dir); @@ -645,7 +646,8 @@ namespace LLError  		}  		commonInit(dir);  #if !LL_WINDOWS -		addRecorder(new RecordToSyslog(identity)); +		LLError::RecorderPtr recordToSyslog(new RecordToSyslog(identity)); +		addRecorder(recordToSyslog);  #endif  	} @@ -656,72 +658,67 @@ namespace LLError  	void setPrintLocation(bool print)  	{ -		Settings& s = Settings::get(); -		s.mPrintLocation = print; +		SettingsConfigPtr s = Settings::getInstance()->getSettingsConfig(); +		s->mPrintLocation = print;  	}  	void setFatalFunction(const FatalFunction& f)  	{ -		Settings& s = Settings::get(); -		s.mCrashFunction = f; +		SettingsConfigPtr s = Settings::getInstance()->getSettingsConfig(); +		s->mCrashFunction = f;  	}      FatalFunction getFatalFunction()      { -        Settings& s = Settings::get(); -        return s.mCrashFunction; +		SettingsConfigPtr s = Settings::getInstance()->getSettingsConfig(); +        return s->mCrashFunction;      }  	void setTimeFunction(TimeFunction f)  	{ -		Settings& s = Settings::get(); -		s.mTimeFunction = f; +		SettingsConfigPtr s = Settings::getInstance()->getSettingsConfig(); +		s->mTimeFunction = f;  	}  	void setDefaultLevel(ELevel level)  	{ -		Globals& g = Globals::get(); -		Settings& s = Settings::get(); -		g.invalidateCallSites(); -		s.mDefaultLevel = level; +		Globals::getInstance()->invalidateCallSites(); +		SettingsConfigPtr s = Settings::getInstance()->getSettingsConfig(); +		s->mDefaultLevel = level;  	}  	ELevel getDefaultLevel()  	{ -		Settings& s = Settings::get(); -		return s.mDefaultLevel; +		SettingsConfigPtr s = Settings::getInstance()->getSettingsConfig(); +		return s->mDefaultLevel;  	}  	void setFunctionLevel(const std::string& function_name, ELevel level)  	{ -		Globals& g = Globals::get(); -		Settings& s = Settings::get(); -		g.invalidateCallSites(); -		s.mFunctionLevelMap[function_name] = level; +		Globals::getInstance()->invalidateCallSites(); +		SettingsConfigPtr s = Settings::getInstance()->getSettingsConfig(); +		s->mFunctionLevelMap[function_name] = level;  	}  	void setClassLevel(const std::string& class_name, ELevel level)  	{ -		Globals& g = Globals::get(); -		Settings& s = Settings::get(); -		g.invalidateCallSites(); -		s.mClassLevelMap[class_name] = level; +		Globals::getInstance()->invalidateCallSites(); +		SettingsConfigPtr s = Settings::getInstance()->getSettingsConfig(); +		s->mClassLevelMap[class_name] = level;  	}  	void setFileLevel(const std::string& file_name, ELevel level)  	{ -		Globals& g = Globals::get(); -		Settings& s = Settings::get(); -		g.invalidateCallSites(); -		s.mFileLevelMap[file_name] = level; +		Globals::getInstance()->invalidateCallSites(); +		SettingsConfigPtr s = Settings::getInstance()->getSettingsConfig(); +		s->mFileLevelMap[file_name] = level;  	}  	void setTagLevel(const std::string& tag_name, ELevel level)  	{ -		Globals& g = Globals::get(); -		Settings& s = Settings::get(); -		g.invalidateCallSites(); -		s.mTagLevelMap[tag_name] = level; +		Globals::getInstance()->invalidateCallSites(); +		SettingsConfigPtr s = Settings::getInstance()->getSettingsConfig(); +		s->mTagLevelMap[tag_name] = level;  	}  	LLError::ELevel decodeLevel(std::string name) @@ -765,15 +762,14 @@ namespace LLError  {  	void configure(const LLSD& config)  	{ -		Globals& g = Globals::get(); -		Settings& s = Settings::get(); +		Globals::getInstance()->invalidateCallSites(); +		SettingsConfigPtr s = Settings::getInstance()->getSettingsConfig(); -		g.invalidateCallSites(); -		s.mFunctionLevelMap.clear(); -		s.mClassLevelMap.clear(); -		s.mFileLevelMap.clear(); -		s.mTagLevelMap.clear(); -		s.mUniqueLogMessages.clear(); +		s->mFunctionLevelMap.clear(); +		s->mClassLevelMap.clear(); +		s->mFileLevelMap.clear(); +		s->mTagLevelMap.clear(); +		s->mUniqueLogMessages.clear();  		setPrintLocation(config["print-location"]);  		setDefaultLevel(decodeLevel(config["default-level"])); @@ -786,10 +782,10 @@ namespace LLError  			ELevel level = decodeLevel(entry["level"]); -			setLevels(s.mFunctionLevelMap,	entry["functions"],	level); -			setLevels(s.mClassLevelMap,		entry["classes"],	level); -			setLevels(s.mFileLevelMap,		entry["files"],		level); -			setLevels(s.mTagLevelMap,		entry["tags"],		level); +			setLevels(s->mFunctionLevelMap,	entry["functions"],	level); +			setLevels(s->mClassLevelMap,	entry["classes"],	level); +			setLevels(s->mFileLevelMap,		entry["files"],		level); +			setLevels(s->mTagLevelMap,		entry["tags"],		level);  		}  	}  } @@ -803,10 +799,12 @@ namespace LLError  		mWantsLevel(true),  		mWantsLocation(false),  		mWantsFunctionName(true) -	{} +	{ +	}  	Recorder::~Recorder() -		{ } +	{ +	}  	bool Recorder::wantsTime()  	{  @@ -837,25 +835,25 @@ namespace LLError  		return mWantsFunctionName;  	} -	void addRecorder(Recorder* recorder) +	void addRecorder(RecorderPtr recorder)  	{ -		if (recorder == NULL) +		if (!recorder)  		{  			return;  		} -		Settings& s = Settings::get(); -		s.mRecorders.push_back(recorder); +		SettingsConfigPtr s = Settings::getInstance()->getSettingsConfig(); +		s->mRecorders.push_back(recorder);  	} -	void removeRecorder(Recorder* recorder) +	void removeRecorder(RecorderPtr recorder)  	{ -		if (recorder == NULL) +		if (!recorder)  		{  			return;  		} -		Settings& s = Settings::get(); -		s.mRecorders.erase(std::remove(s.mRecorders.begin(), s.mRecorders.end(), recorder), -							s.mRecorders.end()); +		SettingsConfigPtr s = Settings::getInstance()->getSettingsConfig(); +		s->mRecorders.erase(std::remove(s->mRecorders.begin(), s->mRecorders.end(), recorder), +							s->mRecorders.end());  	}  } @@ -863,51 +861,47 @@ namespace LLError  {  	void logToFile(const std::string& file_name)  	{ -		LLError::Settings& s = LLError::Settings::get(); +		SettingsConfigPtr s = Settings::getInstance()->getSettingsConfig(); -		removeRecorder(s.mFileRecorder); -		delete s.mFileRecorder; -		s.mFileRecorder = NULL; -		s.mFileRecorderFileName.clear(); +		removeRecorder(s->mFileRecorder); +		s->mFileRecorder.reset(); +		s->mFileRecorderFileName.clear();  		if (file_name.empty())  		{  			return;  		} -		RecordToFile* f = new RecordToFile(file_name); -		if (!f->okay()) +		RecorderPtr recordToFile(new RecordToFile(file_name)); +		if (boost::dynamic_pointer_cast<RecordToFile>(recordToFile)->okay())  		{ -			delete f; -			return; +			s->mFileRecorderFileName = file_name; +			s->mFileRecorder = recordToFile; +			addRecorder(recordToFile);  		} - -		s.mFileRecorderFileName = file_name; -		s.mFileRecorder = f; -		addRecorder(f);  	}  	void logToFixedBuffer(LLLineBuffer* fixedBuffer)  	{ -		LLError::Settings& s = LLError::Settings::get(); +		SettingsConfigPtr s = Settings::getInstance()->getSettingsConfig(); -		removeRecorder(s.mFixedBufferRecorder); -		delete s.mFixedBufferRecorder; -		s.mFixedBufferRecorder = NULL; +		removeRecorder(s->mFixedBufferRecorder); +		s->mFixedBufferRecorder.reset();  		if (!fixedBuffer)  		{  			return;  		} -		s.mFixedBufferRecorder = new RecordToFixedBuffer(fixedBuffer); -		addRecorder(s.mFixedBufferRecorder); +		RecorderPtr recordToFixedBuffer(new RecordToFixedBuffer(fixedBuffer)); +		s->mFixedBufferRecorder = recordToFixedBuffer; +		addRecorder(recordToFixedBuffer);  	}  	std::string logFileName()  	{ -		LLError::Settings& s = LLError::Settings::get(); -		return s.mFileRecorderFileName; +		SettingsConfigPtr s = Settings::getInstance()->getSettingsConfig(); +		return s->mFileRecorderFileName;  	}  } @@ -916,24 +910,24 @@ namespace  	void writeToRecorders(const LLError::CallSite& site, const std::string& message, bool show_location = true, bool show_time = true, bool show_tags = true, bool show_level = true, bool show_function = true)  	{  		LLError::ELevel level = site.mLevel; -		LLError::Settings& s = LLError::Settings::get(); +		LLError::SettingsConfigPtr s = LLError::Settings::getInstance()->getSettingsConfig(); -		for (Recorders::const_iterator i = s.mRecorders.begin(); -			i != s.mRecorders.end(); +		for (Recorders::const_iterator i = s->mRecorders.begin(); +			i != s->mRecorders.end();  			++i)  		{ -			LLError::Recorder* r = *i; +			LLError::RecorderPtr r = *i;  			std::ostringstream message_stream; -			if (show_location && (r->wantsLocation() || level == LLError::LEVEL_ERROR || s.mPrintLocation)) +			if (show_location && (r->wantsLocation() || level == LLError::LEVEL_ERROR || s->mPrintLocation))  			{  				message_stream << site.mLocationString << " ";  			} -			if (show_time && r->wantsTime() && s.mTimeFunction != NULL) +			if (show_time && r->wantsTime() && s->mTimeFunction != NULL)  			{ -				message_stream << s.mTimeFunction() << " "; +				message_stream << s->mTimeFunction() << " ";  			}  			if (show_level && r->wantsLevel()) @@ -1060,10 +1054,9 @@ namespace LLError  			return false;  		} -		Globals& g = Globals::get(); -		Settings& s = Settings::get(); +		SettingsConfigPtr s = Settings::getInstance()->getSettingsConfig(); -		s.mShouldLogCallCounter++; +		s->mShouldLogCallCounter++;  		const std::string& class_name = className(site.mClassInfo);  		std::string function_name = functionName(site.mFunction); @@ -1077,21 +1070,21 @@ namespace LLError  			function_name = class_name + "::" + function_name;  		} -		ELevel compareLevel = s.mDefaultLevel; +		ELevel compareLevel = s->mDefaultLevel;  		// The most specific match found will be used as the log level,  		// since the computation short circuits.  		// So, in increasing order of importance:  		// Default < Tags < File < Class < Function -		checkLevelMap(s.mFunctionLevelMap, function_name, compareLevel) -		|| checkLevelMap(s.mClassLevelMap, class_name, compareLevel) -		|| checkLevelMap(s.mFileLevelMap, abbreviateFile(site.mFile), compareLevel) +		checkLevelMap(s->mFunctionLevelMap, function_name, compareLevel) +		|| checkLevelMap(s->mClassLevelMap, class_name, compareLevel) +		|| checkLevelMap(s->mFileLevelMap, abbreviateFile(site.mFile), compareLevel)  		|| (site.mTagCount > 0 -			? checkLevelMap(s.mTagLevelMap, site.mTags, site.mTagCount, compareLevel)  +			? checkLevelMap(s->mTagLevelMap, site.mTags, site.mTagCount, compareLevel)   			: false);  		site.mCached = true; -		g.addCallSite(site); +		Globals::getInstance()->addCallSite(site);  		return site.mShouldLog = site.mLevel >= compareLevel;  	} @@ -1101,12 +1094,12 @@ namespace LLError  		LogLock lock;  		if (lock.ok())  		{ -			Globals& g = Globals::get(); +			Globals* g = Globals::getInstance(); -			if (!g.messageStreamInUse) +			if (!g->messageStreamInUse)  			{ -				g.messageStreamInUse = true; -				return &g.messageStream; +				g->messageStreamInUse = true; +				return &g->messageStream;  			}  		} @@ -1131,13 +1124,12 @@ namespace LLError  		   message[127] = '\0' ;  	   } -	   Globals& g = Globals::get(); - -       if (out == &g.messageStream) +	   Globals* g = Globals::getInstance(); +       if (out == &g->messageStream)         { -           g.messageStream.clear(); -           g.messageStream.str(""); -           g.messageStreamInUse = false; +           g->messageStream.clear(); +           g->messageStream.str(""); +           g->messageStreamInUse = false;         }         else         { @@ -1154,15 +1146,15 @@ namespace LLError  			return;  		} -		Globals& g = Globals::get(); -		Settings& s = Settings::get(); +		Globals* g = Globals::getInstance(); +		SettingsConfigPtr s = Settings::getInstance()->getSettingsConfig();  		std::string message = out->str(); -		if (out == &g.messageStream) +		if (out == &g->messageStream)  		{ -			g.messageStream.clear(); -			g.messageStream.str(""); -			g.messageStreamInUse = false; +			g->messageStream.clear(); +			g->messageStream.str(""); +			g->messageStreamInUse = false;  		}  		else  		{ @@ -1178,8 +1170,8 @@ namespace LLError  		if (site.mPrintOnce)  		{ -			std::map<std::string, unsigned int>::iterator messageIter = s.mUniqueLogMessages.find(message); -			if (messageIter != s.mUniqueLogMessages.end()) +			std::map<std::string, unsigned int>::iterator messageIter = s->mUniqueLogMessages.find(message); +			if (messageIter != s->mUniqueLogMessages.end())  			{  				messageIter->second++;  				unsigned int num_messages = messageIter->second; @@ -1195,7 +1187,7 @@ namespace LLError  			else   			{  				message_stream << "ONCE: "; -				s.mUniqueLogMessages[message] = 1; +				s->mUniqueLogMessages[message] = 1;  			}  		} @@ -1203,23 +1195,23 @@ namespace LLError  		writeToRecorders(site, message_stream.str()); -		if (site.mLevel == LEVEL_ERROR  &&  s.mCrashFunction) +		if (site.mLevel == LEVEL_ERROR  &&  s->mCrashFunction)  		{ -			s.mCrashFunction(message_stream.str()); +			s->mCrashFunction(message_stream.str());  		}  	}  }  namespace LLError  { -	Settings* saveAndResetSettings() +	SettingsStoragePtr saveAndResetSettings()  	{ -		return Settings::saveAndReset(); +		return Settings::getInstance()->saveAndReset();  	} -	void restoreSettings(Settings* s) +	void restoreSettings(SettingsStoragePtr pSettingsStorage)  	{ -		return Settings::restore(s); +		return Settings::getInstance()->restore(pSettingsStorage);  	}  	std::string removePrefix(std::string& s, const std::string& p) @@ -1265,8 +1257,8 @@ namespace LLError  	int shouldLogCallCount()  	{ -		Settings& s = Settings::get(); -		return s.mShouldLogCallCounter; +		SettingsConfigPtr s = Settings::getInstance()->getSettingsConfig(); +		return s->mShouldLogCallCounter;  	}  #if LL_WINDOWS @@ -1375,15 +1367,9 @@ namespace LLError  #endif  	//static -   void LLCallStacks::push(const char* function, const int line) +   void LLCallStacks::allocateStackBuffer()     { -	   CallStacksLogLock lock; -       if (!lock.ok()) -       { -           return; -       } - -	   if(!sBuffer) +	   if(sBuffer == NULL)  	   {  		   sBuffer = new char*[512] ;  		   sBuffer[0] = new char[512 * 128] ; @@ -1393,6 +1379,31 @@ namespace LLError  		   }  		   sIndex = 0 ;  	   } +   } + +   void LLCallStacks::freeStackBuffer() +   { +	   if(sBuffer != NULL) +	   { +		   delete [] sBuffer[0] ; +		   delete [] sBuffer ; +		   sBuffer = NULL ; +	   } +   } + +   //static +   void LLCallStacks::push(const char* function, const int line) +   { +	   CallStacksLogLock lock; +       if (!lock.ok()) +       { +           return; +       } + +	   if(sBuffer == NULL) +	   { +		   allocateStackBuffer(); +	   }  	   if(sIndex > 511)  	   { @@ -1424,15 +1435,9 @@ namespace LLError             return;         } -	   if(!sBuffer) +	   if(sBuffer == NULL)  	   { -		   sBuffer = new char*[512] ; -		   sBuffer[0] = new char[512 * 128] ; -		   for(S32 i = 1 ; i < 512 ; i++) -		   { -			   sBuffer[i] = sBuffer[i-1] + 128 ; -		   } -		   sIndex = 0 ; +		   allocateStackBuffer();  	   }  	   if(sIndex > 511) @@ -1463,11 +1468,9 @@ namespace LLError             LL_INFOS() << " *************** END OF LL CALL STACKS *************** " << LL_ENDL;         } -	   if(sBuffer) +	   if(sBuffer != NULL)  	   { -		   delete[] sBuffer[0] ; -		   delete[] sBuffer ; -		   sBuffer = NULL ; +		   freeStackBuffer();  	   }     } @@ -1477,5 +1480,10 @@ namespace LLError         sIndex = 0 ;     } +   //static +   void LLCallStacks::cleanup() +   { +	   freeStackBuffer(); +   }  } diff --git a/indra/llcommon/llerror.h b/indra/llcommon/llerror.h index bc80e64423..63040e1772 100755 --- a/indra/llcommon/llerror.h +++ b/indra/llcommon/llerror.h @@ -261,6 +261,9 @@ namespace LLError     private:         static char**  sBuffer ;  	   static S32     sIndex ; + +	   static void allocateStackBuffer(); +	   static void freeStackBuffer();     public:     	   static void push(const char* function, const int line) ; @@ -268,6 +271,7 @@ namespace LLError         static void print() ;         static void clear() ;  	   static void end(std::ostringstream* _out) ; +	   static void cleanup();     };   } diff --git a/indra/llcommon/llerrorcontrol.h b/indra/llcommon/llerrorcontrol.h index aab695094c..56ac52e5de 100755 --- a/indra/llcommon/llerrorcontrol.h +++ b/indra/llcommon/llerrorcontrol.h @@ -29,7 +29,10 @@  #define LL_LLERRORCONTROL_H  #include "llerror.h" +#include "llpointer.h" +#include "llrefcount.h"  #include "boost/function.hpp" +#include "boost/shared_ptr.hpp"  #include <string>  class LLSD; @@ -156,16 +159,14 @@ namespace LLError  				mWantsFunctionName;  	}; +	typedef boost::shared_ptr<Recorder> RecorderPtr; +  	/** -	 * @NOTE: addRecorder() conveys ownership to the underlying Settings -	 * object -- when destroyed, it will @em delete the passed Recorder*! -	 */ -	LL_COMMON_API void addRecorder(Recorder*); -	/** -	 * @NOTE: removeRecorder() reclaims ownership of the Recorder*: its -	 * lifespan becomes the caller's problem. +	 * @NOTE: addRecorder() and removeRecorder() uses the boost::shared_ptr to allow for shared ownership +	 * while still ensuring that the allocated memory is eventually freed  	 */ -	LL_COMMON_API void removeRecorder(Recorder*); +	LL_COMMON_API void addRecorder(RecorderPtr); +	LL_COMMON_API void removeRecorder(RecorderPtr);  		// each error message is passed to each recorder via recordMessage()  	LL_COMMON_API void logToFile(const std::string& filename); @@ -182,9 +183,9 @@ namespace LLError  		Utilities for use by the unit tests of LLError itself.  	*/ -	class Settings; -	LL_COMMON_API Settings* saveAndResetSettings(); -	LL_COMMON_API void restoreSettings(Settings *); +	typedef LLPointer<LLRefCount> SettingsStoragePtr; +	LL_COMMON_API SettingsStoragePtr saveAndResetSettings(); +	LL_COMMON_API void restoreSettings(SettingsStoragePtr pSettingsStorage);  	LL_COMMON_API std::string abbreviateFile(const std::string& filePath);  	LL_COMMON_API int shouldLogCallCount(); diff --git a/indra/llcommon/llhttpstatuscodes.h b/indra/llcommon/llhttpstatuscodes.h deleted file mode 100755 index 0173461dad..0000000000 --- a/indra/llcommon/llhttpstatuscodes.h +++ /dev/null @@ -1,89 +0,0 @@ -/**  - * @file llhttpstatuscodes.h - * @brief Constants for HTTP status codes - * - * $LicenseInfo:firstyear=2001&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_HTTP_STATUS_CODES_H -#define LL_HTTP_STATUS_CODES_H - -#include "stdtypes.h" - -// Standard errors from HTTP spec: -// http://www.w3.org/Protocols/rfc2616/rfc2616-sec6.html#sec6.1 -const S32 HTTP_CONTINUE = 100; -const S32 HTTP_SWITCHING_PROTOCOLS = 101; - -// Success -const S32 HTTP_OK = 200; -const S32 HTTP_CREATED = 201; -const S32 HTTP_ACCEPTED = 202; -const S32 HTTP_NON_AUTHORITATIVE_INFORMATION = 203; -const S32 HTTP_NO_CONTENT = 204; -const S32 HTTP_RESET_CONTENT = 205; -const S32 HTTP_PARTIAL_CONTENT = 206; - -// Redirection -const S32 HTTP_MULTIPLE_CHOICES = 300; -const S32 HTTP_MOVED_PERMANENTLY = 301; -const S32 HTTP_FOUND = 302; -const S32 HTTP_SEE_OTHER = 303; -const S32 HTTP_NOT_MODIFIED = 304; -const S32 HTTP_USE_PROXY = 305; -const S32 HTTP_TEMPORARY_REDIRECT = 307; - -// Client Error -const S32 HTTP_BAD_REQUEST = 400; -const S32 HTTP_UNAUTHORIZED = 401; -const S32 HTTP_PAYMENT_REQUIRED = 402; -const S32 HTTP_FORBIDDEN = 403; -const S32 HTTP_NOT_FOUND = 404; -const S32 HTTP_METHOD_NOT_ALLOWED = 405; -const S32 HTTP_NOT_ACCEPTABLE = 406; -const S32 HTTP_PROXY_AUTHENTICATION_REQUIRED = 407; -const S32 HTTP_REQUEST_TIME_OUT = 408; -const S32 HTTP_CONFLICT = 409; -const S32 HTTP_GONE = 410; -const S32 HTTP_LENGTH_REQUIRED = 411; -const S32 HTTP_PRECONDITION_FAILED = 412; -const S32 HTTP_REQUEST_ENTITY_TOO_LARGE = 413; -const S32 HTTP_REQUEST_URI_TOO_LARGE = 414; -const S32 HTTP_UNSUPPORTED_MEDIA_TYPE = 415; -const S32 HTTP_REQUESTED_RANGE_NOT_SATISFIABLE = 416; -const S32 HTTP_EXPECTATION_FAILED = 417; - -// Server Error -const S32 HTTP_INTERNAL_SERVER_ERROR = 500; -const S32 HTTP_NOT_IMPLEMENTED = 501; -const S32 HTTP_BAD_GATEWAY = 502; -const S32 HTTP_SERVICE_UNAVAILABLE = 503; -const S32 HTTP_GATEWAY_TIME_OUT = 504; -const S32 HTTP_VERSION_NOT_SUPPORTED = 505; - -// We combine internal process errors with status codes -// These status codes should not be sent over the wire -//   and indicate something went wrong internally. -// If you get these they are not normal. -const S32 HTTP_INTERNAL_ERROR = 499; - -#endif diff --git a/indra/llcommon/llinitparam.h b/indra/llcommon/llinitparam.h index 2532566319..7aa87fcd0e 100755 --- a/indra/llcommon/llinitparam.h +++ b/indra/llcommon/llinitparam.h @@ -31,6 +31,7 @@  #include <vector>  #include <list>  #include <boost/function.hpp> +#include <boost/shared_ptr.hpp>  #include <boost/type_traits/is_convertible.hpp>  #include <boost/type_traits/is_enum.hpp>  #include <boost/unordered_map.hpp> @@ -629,7 +630,7 @@ namespace LLInitParam  		UserData*			mUserData;  	}; -	typedef ParamDescriptor* ParamDescriptorPtr; +	typedef boost::shared_ptr<ParamDescriptor> ParamDescriptorPtr;  	// each derived Block class keeps a static data structure maintaining offsets to various params  	class LL_COMMON_API BlockDescriptor diff --git a/indra/llcommon/llpointer.h b/indra/llcommon/llpointer.h index c9ebc70d19..9a6453ea48 100755 --- a/indra/llcommon/llpointer.h +++ b/indra/llcommon/llpointer.h @@ -166,6 +166,132 @@ protected:  	Type*	mPointer;  }; +template <class Type> class LLConstPointer +{ +public: +	LLConstPointer() :  +		mPointer(NULL) +	{ +	} + +	LLConstPointer(const Type* ptr) :  +		mPointer(ptr) +	{ +		ref(); +	} + +	LLConstPointer(const LLConstPointer<Type>& ptr) :  +		mPointer(ptr.mPointer) +	{ +		ref(); +	} + +	// support conversion up the type hierarchy.  See Item 45 in Effective C++, 3rd Ed. +	template<typename Subclass> +	LLConstPointer(const LLConstPointer<Subclass>& ptr) :  +		mPointer(ptr.get()) +	{ +		ref(); +	} + +	~LLConstPointer() +	{ +		unref(); +	} + +	const Type*	get() const						{ return mPointer; } +	const Type*	operator->() const				{ return mPointer; } +	const Type&	operator*() const				{ return *mPointer; } + +	operator BOOL()  const						{ return (mPointer != NULL); } +	operator bool()  const						{ return (mPointer != NULL); } +	bool operator!() const						{ return (mPointer == NULL); } +	bool isNull() const							{ return (mPointer == NULL); } +	bool notNull() const						{ return (mPointer != NULL); } + +	operator const Type*()       const			{ return mPointer; } +	bool operator !=(const Type* ptr) const     { return (mPointer != ptr); 	} +	bool operator ==(const Type* ptr) const     { return (mPointer == ptr); 	} +	bool operator ==(const LLConstPointer<Type>& ptr) const           { return (mPointer == ptr.mPointer); 	} +	bool operator < (const LLConstPointer<Type>& ptr) const           { return (mPointer < ptr.mPointer); 	} +	bool operator > (const LLConstPointer<Type>& ptr) const           { return (mPointer > ptr.mPointer); 	} + +	LLConstPointer<Type>& operator =(const Type* ptr)                    +	{ +		if( mPointer != ptr ) +		{ +			unref();  +			mPointer = ptr;  +			ref(); +		} + +		return *this;  +	} + +	LLConstPointer<Type>& operator =(const LLConstPointer<Type>& ptr)   +	{  +		if( mPointer != ptr.mPointer ) +		{ +			unref();  +			mPointer = ptr.mPointer; +			ref(); +		} +		return *this;  +	} + +	// support assignment up the type hierarchy. See Item 45 in Effective C++, 3rd Ed. +	template<typename Subclass> +	LLConstPointer<Type>& operator =(const LLConstPointer<Subclass>& ptr)   +	{  +		if( mPointer != ptr.get() ) +		{ +			unref();  +			mPointer = ptr.get(); +			ref(); +		} +		return *this;  +	} +	 +	// Just exchange the pointers, which will not change the reference counts. +	static void swap(LLConstPointer<Type>& a, LLConstPointer<Type>& b) +	{ +		const Type* temp = a.mPointer; +		a.mPointer = b.mPointer; +		b.mPointer = temp; +	} + +protected: +#ifdef LL_LIBRARY_INCLUDE +	void ref();                              +	void unref(); +#else +	void ref()                              +	{  +		if (mPointer) +		{ +			mPointer->ref(); +		} +	} + +	void unref() +	{ +		if (mPointer) +		{ +			const Type *tempp = mPointer; +			mPointer = NULL; +			tempp->unref(); +			if (mPointer != NULL) +			{ +				LL_WARNS() << "Unreference did assignment to non-NULL because of destructor" << LL_ENDL; +				unref(); +			} +		} +	} +#endif +protected: +	const Type*	mPointer; +}; +  template<typename Type>  class LLCopyOnWritePointer : public LLPointer<Type>  { diff --git a/indra/llcommon/llsd.cpp b/indra/llcommon/llsd.cpp index f962485284..d8bbb3a74f 100755 --- a/indra/llcommon/llsd.cpp +++ b/indra/llcommon/llsd.cpp @@ -126,7 +126,9 @@ public:  	virtual UUID	asUUID() const				{ return LLUUID(); }  	virtual Date	asDate() const				{ return LLDate(); }  	virtual URI		asURI() const				{ return LLURI(); } -	virtual Binary	asBinary() const			{ return std::vector<U8>(); } +	virtual const Binary&	asBinary() const	{ static const std::vector<U8> empty; return empty; } + +	virtual const String& asStringRef() const { static const std::string empty; return empty; }   	virtual bool has(const String&) const		{ return false; }  	virtual LLSD get(const String&) const		{ return LLSD(); } @@ -270,6 +272,7 @@ namespace  		virtual LLSD::Date		asDate() const	{ return LLDate(mValue); }  		virtual LLSD::URI		asURI() const	{ return LLURI(mValue); }  		virtual int				size() const	{ return mValue.size(); } +		virtual const LLSD::String&	asStringRef() const { return mValue; }  	};  	LLSD::Integer	ImplString::asInteger() const @@ -348,7 +351,7 @@ namespace  	public:  		ImplBinary(const LLSD::Binary& v) : Base(v) { } -		virtual LLSD::Binary	asBinary() const{ return mValue; } +		virtual const LLSD::Binary&	asBinary() const{ return mValue; }  	}; @@ -840,7 +843,9 @@ LLSD::String	LLSD::asString() const	{ return safe(impl).asString(); }  LLSD::UUID		LLSD::asUUID() const	{ return safe(impl).asUUID(); }  LLSD::Date		LLSD::asDate() const	{ return safe(impl).asDate(); }  LLSD::URI		LLSD::asURI() const		{ return safe(impl).asURI(); } -LLSD::Binary	LLSD::asBinary() const	{ return safe(impl).asBinary(); } +const LLSD::Binary&	LLSD::asBinary() const	{ return safe(impl).asBinary(); } + +const LLSD::String& LLSD::asStringRef() const { return safe(impl).asStringRef(); }  // const char * helpers  LLSD::LLSD(const char* v) : impl(0)		{ ALLOC_LLSD_OBJECT;	assign(v); } diff --git a/indra/llcommon/llsd.h b/indra/llcommon/llsd.h index deb87d7497..7b9b1285f5 100755 --- a/indra/llcommon/llsd.h +++ b/indra/llcommon/llsd.h @@ -249,7 +249,10 @@ public:  		UUID	asUUID() const;  		Date	asDate() const;  		URI		asURI() const; -		Binary	asBinary() const; +		const Binary&	asBinary() const; + +		// asStringRef on any non-string type will return a ref to an empty string. +		const String&	asStringRef() const;  		operator Boolean() const	{ return asBoolean(); }  		operator Integer() const	{ return asInteger(); } diff --git a/indra/llcommon/llsdserialize.cpp b/indra/llcommon/llsdserialize.cpp index 04d7a6ed56..b2add301f9 100755 --- a/indra/llcommon/llsdserialize.cpp +++ b/indra/llcommon/llsdserialize.cpp @@ -873,7 +873,7 @@ S32 LLSDBinaryParser::doParse(std::istream& istr, LLSD& data) const  {  /**   * Undefined: '!'<br> - * Boolean: 't' for true 'f' for false<br> + * Boolean: '1' for true '0' for false<br>   * Integer: 'i' + 4 bytes network byte order<br>   * Real: 'r' + 8 bytes IEEE double<br>   * UUID: 'u' + 16 byte unsigned integer<br> @@ -1261,12 +1261,37 @@ std::string LLSDNotationFormatter::escapeString(const std::string& in)  // virtual  S32 LLSDNotationFormatter::format(const LLSD& data, std::ostream& ostr, U32 options) const  { +	S32 rv = format_impl(data, ostr, options, 0); +	return rv; +} + +S32 LLSDNotationFormatter::format_impl(const LLSD& data, std::ostream& ostr, U32 options, U32 level) const +{  	S32 format_count = 1; +	std::string pre; +	std::string post; + +	if (options & LLSDFormatter::OPTIONS_PRETTY) +	{ +		for (U32 i = 0; i < level; i++) +		{ +			pre += "    "; +		} +		post = "\n"; +	} +  	switch(data.type())  	{  	case LLSD::TypeMap:  	{ +		if (0 != level) ostr << post << pre;  		ostr << "{"; +		std::string inner_pre; +		if (options & LLSDFormatter::OPTIONS_PRETTY) +		{ +			inner_pre = pre + "    "; +		} +  		bool need_comma = false;  		LLSD::map_const_iterator iter = data.beginMap();  		LLSD::map_const_iterator end = data.endMap(); @@ -1274,18 +1299,18 @@ S32 LLSDNotationFormatter::format(const LLSD& data, std::ostream& ostr, U32 opti  		{  			if(need_comma) ostr << ",";  			need_comma = true; -			ostr << '\''; +			ostr << post << inner_pre << '\'';  			serialize_string((*iter).first, ostr);  			ostr << "':"; -			format_count += format((*iter).second, ostr); +			format_count += format_impl((*iter).second, ostr, options, level + 2);  		} -		ostr << "}"; +		ostr << post << pre << "}";  		break;  	}  	case LLSD::TypeArray:  	{ -		ostr << "["; +		ostr << post << pre << "[";  		bool need_comma = false;  		LLSD::array_const_iterator iter = data.beginArray();  		LLSD::array_const_iterator end = data.endArray(); @@ -1293,7 +1318,7 @@ S32 LLSDNotationFormatter::format(const LLSD& data, std::ostream& ostr, U32 opti  		{  			if(need_comma) ostr << ",";  			need_comma = true; -			format_count += format(*iter, ostr); +			format_count += format_impl(*iter, ostr, options, level + 1);  		}  		ostr << "]";  		break; @@ -1343,7 +1368,7 @@ S32 LLSDNotationFormatter::format(const LLSD& data, std::ostream& ostr, U32 opti  	case LLSD::TypeString:  		ostr << '\''; -		serialize_string(data.asString(), ostr); +		serialize_string(data.asStringRef(), ostr);  		ostr << '\'';  		break; @@ -1360,9 +1385,26 @@ S32 LLSDNotationFormatter::format(const LLSD& data, std::ostream& ostr, U32 opti  	case LLSD::TypeBinary:  	{  		// *FIX: memory inefficient. -		std::vector<U8> buffer = data.asBinary(); +		const std::vector<U8>& buffer = data.asBinary();  		ostr << "b(" << buffer.size() << ")\""; -		if(buffer.size()) ostr.write((const char*)&buffer[0], buffer.size()); +		if(buffer.size()) +		{ +			if (options & LLSDFormatter::OPTIONS_PRETTY_BINARY) +			{ +				std::ios_base::fmtflags old_flags = ostr.flags(); +				ostr.setf( std::ios::hex, std::ios::basefield ); +				ostr << "0x"; +				for (int i = 0; i < buffer.size(); i++) +				{ +					ostr << (int) buffer[i]; +				} +				ostr.flags(old_flags); +			} +			else +			{ +				ostr.write((const char*)&buffer[0], buffer.size()); +			} +		}  		ostr << "\"";  		break;  	} @@ -1460,7 +1502,7 @@ S32 LLSDBinaryFormatter::format(const LLSD& data, std::ostream& ostr, U32 option  	case LLSD::TypeString:  		ostr.put('s'); -		formatString(data.asString(), ostr); +		formatString(data.asStringRef(), ostr);  		break;  	case LLSD::TypeDate: @@ -1478,9 +1520,8 @@ S32 LLSDBinaryFormatter::format(const LLSD& data, std::ostream& ostr, U32 option  	case LLSD::TypeBinary:  	{ -		// *FIX: memory inefficient.  		ostr.put('b'); -		std::vector<U8> buffer = data.asBinary(); +		const std::vector<U8>& buffer = data.asBinary();  		U32 size_nbo = htonl(buffer.size());  		ostr.write((const char*)(&size_nbo), sizeof(U32));  		if(buffer.size()) ostr.write((const char*)&buffer[0], buffer.size()); diff --git a/indra/llcommon/llsdserialize.h b/indra/llcommon/llsdserialize.h index e7a5507385..23a0c8cfb1 100755 --- a/indra/llcommon/llsdserialize.h +++ b/indra/llcommon/llsdserialize.h @@ -416,7 +416,8 @@ public:  	typedef enum e_formatter_options_type  	{  		OPTIONS_NONE = 0, -		OPTIONS_PRETTY = 1 +		OPTIONS_PRETTY = 1, +		OPTIONS_PRETTY_BINARY = 2  	} EFormatterOptions;  	/**  @@ -507,6 +508,17 @@ public:  	 * @return Returns The number of LLSD objects fomatted out  	 */  	virtual S32 format(const LLSD& data, std::ostream& ostr, U32 options = LLSDFormatter::OPTIONS_NONE) const; + +protected: + +	/**  +	 * @brief Implementation to format the data. This is called recursively. +	 * +	 * @param data The data to write. +	 * @param ostr The destination stream for the data. +	 * @return Returns The number of LLSD objects fomatted out +	 */ +	S32 format_impl(const LLSD& data, std::ostream& ostr, U32 options, U32 level) const;  }; @@ -634,7 +646,7 @@ protected:   *  </code>   *   * *NOTE - formerly this class inherited from its template parameter Formatter, - * but all insnatiations passed in LLRefCount subclasses.  This conflicted with + * but all instantiations passed in LLRefCount subclasses.  This conflicted with   * the auto allocation intended for this class template (demonstrated in the   * example above).  -brad   */ @@ -720,6 +732,18 @@ public:  		LLPointer<LLSDNotationFormatter> f = new LLSDNotationFormatter;  		return f->format(sd, str, LLSDFormatter::OPTIONS_NONE);  	} +	static S32 toPrettyNotation(const LLSD& sd, std::ostream& str) +	{ +		LLPointer<LLSDNotationFormatter> f = new LLSDNotationFormatter; +		return f->format(sd, str, LLSDFormatter::OPTIONS_PRETTY); +	} +	static S32 toPrettyBinaryNotation(const LLSD& sd, std::ostream& str) +	{ +		LLPointer<LLSDNotationFormatter> f = new LLSDNotationFormatter; +		return f->format(sd, str,  +				LLSDFormatter::OPTIONS_PRETTY |  +				LLSDFormatter::OPTIONS_PRETTY_BINARY); +	}  	static S32 fromNotation(LLSD& sd, std::istream& str, S32 max_bytes)  	{  		LLPointer<LLSDNotationParser> p = new LLSDNotationParser; diff --git a/indra/llcommon/llsdserialize_xml.cpp b/indra/llcommon/llsdserialize_xml.cpp index 4e2af0e589..e1a91f1367 100755 --- a/indra/llcommon/llsdserialize_xml.cpp +++ b/indra/llcommon/llsdserialize_xml.cpp @@ -168,8 +168,8 @@ S32 LLSDXMLFormatter::format_impl(const LLSD& data, std::ostream& ostr, U32 opti  		break;  	case LLSD::TypeString: -		if(data.asString().empty()) ostr << pre << "<string />" << post; -		else ostr << pre << "<string>" << escapeString(data.asString()) <<"</string>" << post; +		if(data.asStringRef().empty()) ostr << pre << "<string />" << post; +		else ostr << pre << "<string>" << escapeString(data.asStringRef()) <<"</string>" << post;  		break;  	case LLSD::TypeDate: @@ -182,7 +182,7 @@ S32 LLSDXMLFormatter::format_impl(const LLSD& data, std::ostream& ostr, U32 opti  	case LLSD::TypeBinary:  	{ -		LLSD::Binary buffer = data.asBinary(); +		const LLSD::Binary& buffer = data.asBinary();  		if(buffer.empty())  		{  			ostr << pre << "<binary />" << post; @@ -375,13 +375,10 @@ S32 LLSDXMLParser::Impl::parse(std::istream& input, LLSD& data)  		{  			break;  		} +		count = get_till_eol(input, (char *)buffer, BUFFER_SIZE); +		if (!count)  		{ -		 -			count = get_till_eol(input, (char *)buffer, BUFFER_SIZE); -			if (!count) -			{ -				break; -			} +			break;  		}  		status = XML_ParseBuffer(mParser, count, false); diff --git a/indra/llcommon/llsdutil.cpp b/indra/llcommon/llsdutil.cpp index 803417d368..562fd26658 100755 --- a/indra/llcommon/llsdutil.cpp +++ b/indra/llcommon/llsdutil.cpp @@ -182,7 +182,7 @@ char* ll_pretty_print_sd_ptr(const LLSD* sd)  char* ll_pretty_print_sd(const LLSD& sd)  { -	const U32 bufferSize = 10 * 1024; +	const U32 bufferSize = 100 * 1024;  	static char buffer[bufferSize];  	std::ostringstream stream;  	//stream.rdbuf()->pubsetbuf(buffer, bufferSize); diff --git a/indra/llcommon/lluuid.h b/indra/llcommon/lluuid.h index 0699dcda83..dd8660a3c8 100755 --- a/indra/llcommon/lluuid.h +++ b/indra/llcommon/lluuid.h @@ -132,10 +132,14 @@ public:  };  typedef std::vector<LLUUID> uuid_vec_t; - - -// Helper structure for ordering lluuids in stl containers. -// eg: 	std::map<LLUUID, LLWidget*, lluuid_less> widget_map; +typedef std::set<LLUUID> uuid_set_t; + +// Helper structure for ordering lluuids in stl containers.  eg: +// std::map<LLUUID, LLWidget*, lluuid_less> widget_map; +// +// (isn't this the default behavior anyway? I think we could +// everywhere replace these with uuid_set_t, but someone should +// verify.)  struct lluuid_less  {  	bool operator()(const LLUUID& lhs, const LLUUID& rhs) const @@ -145,7 +149,6 @@ struct lluuid_less  };  typedef std::set<LLUUID, lluuid_less> uuid_list_t; -  /*   * Sub-classes for keeping transaction IDs and asset IDs   * straight. diff --git a/indra/llcommon/tests/llerror_test.cpp b/indra/llcommon/tests/llerror_test.cpp index b28c5ba4b3..a5aaff10c5 100755 --- a/indra/llcommon/tests/llerror_test.cpp +++ b/indra/llcommon/tests/llerror_test.cpp @@ -56,9 +56,9 @@ namespace tut  	{  	public:  		TestRecorder() { mWantsTime = false; } -		~TestRecorder() { LLError::removeRecorder(this); } +		virtual ~TestRecorder() {  } -		void recordMessage(LLError::ELevel level, +		virtual void recordMessage(LLError::ELevel level,  						   const std::string& message)  		{  			mMessages.push_back(message); @@ -85,15 +85,11 @@ namespace tut  	struct ErrorTestData  	{ -		// addRecorder() expects to be able to later delete the passed -		// Recorder*. Even though removeRecorder() reclaims ownership, passing -		// a pointer to a data member rather than a heap Recorder subclass -		// instance would just be Wrong. -		TestRecorder* mRecorder; -		LLError::Settings* mPriorErrorSettings; +		LLError::RecorderPtr mRecorder; +		LLError::SettingsStoragePtr mPriorErrorSettings;  		ErrorTestData(): -			mRecorder(new TestRecorder) +			mRecorder(new TestRecorder())  		{  			fatalWasCalled = false; @@ -106,13 +102,32 @@ namespace tut  		~ErrorTestData()  		{  			LLError::removeRecorder(mRecorder); -			delete mRecorder;  			LLError::restoreSettings(mPriorErrorSettings);  		} +		int countMessages() +		{ +			return boost::dynamic_pointer_cast<TestRecorder>(mRecorder)->countMessages(); +		} + +		void clearMessages() +		{ +			boost::dynamic_pointer_cast<TestRecorder>(mRecorder)->clearMessages(); +		} + +		void setWantsTime(bool t) +		{ +			boost::dynamic_pointer_cast<TestRecorder>(mRecorder)->setWantsTime(t); +		} + +		std::string message(int n) +		{ +			return boost::dynamic_pointer_cast<TestRecorder>(mRecorder)->message(n); +		} +  		void ensure_message_count(int expectedCount)  		{ -			ensure_equals("message count", mRecorder->countMessages(), expectedCount); +			ensure_equals("message count", countMessages(), expectedCount);  		}  		void ensure_message_contains(int n, const std::string& expectedText) @@ -120,7 +135,7 @@ namespace tut  			std::ostringstream test_name;  			test_name << "testing message " << n; -			ensure_contains(test_name.str(), mRecorder->message(n), expectedText); +			ensure_contains(test_name.str(), message(n), expectedText);  		}  		void ensure_message_does_not_contain(int n, const std::string& expectedText) @@ -128,7 +143,7 @@ namespace tut  			std::ostringstream test_name;  			test_name << "testing message " << n; -			ensure_does_not_contain(test_name.str(), mRecorder->message(n), expectedText); +			ensure_does_not_contain(test_name.str(), message(n), expectedText);  		}  	}; @@ -385,15 +400,15 @@ namespace  	}  	typedef std::string (*LogFromFunction)(bool); -	void testLogName(tut::TestRecorder* recorder, LogFromFunction f, +	void testLogName(LLError::RecorderPtr recorder, LogFromFunction f,  		const std::string& class_name = "")  	{ -		recorder->clearMessages(); +		boost::dynamic_pointer_cast<tut::TestRecorder>(recorder)->clearMessages();  		std::string name = f(false);  		f(true); -		std::string messageWithoutName = recorder->message(0); -		std::string messageWithName = recorder->message(1); +		std::string messageWithoutName = boost::dynamic_pointer_cast<tut::TestRecorder>(recorder)->message(0); +		std::string messageWithName = boost::dynamic_pointer_cast<tut::TestRecorder>(recorder)->message(1);  		ensure_has(name + " logged without name",  			messageWithoutName, name); @@ -528,12 +543,12 @@ namespace tut  	{  		LLError::setTimeFunction(roswell); -		mRecorder->setWantsTime(false); +		setWantsTime(false);  		ufoSighting();  		ensure_message_contains(0, "ufo");  		ensure_message_does_not_contain(0, roswell()); -		mRecorder->setWantsTime(true); +		setWantsTime(true);  		ufoSighting();  		ensure_message_contains(1, "ufo");  		ensure_message_contains(1, roswell()); @@ -545,13 +560,13 @@ namespace tut  	{  		LLError::setPrintLocation(true);  		LLError::setTimeFunction(roswell); -		mRecorder->setWantsTime(true); +		setWantsTime(true);  		std::string location,  					function;  		writeReturningLocationAndFunction(location, function);  		ensure_equals("order is location time type function message", -			mRecorder->message(0), +			message(0),  			location + roswell() + " INFO: " + function + ": apple");  	} @@ -559,19 +574,19 @@ namespace tut  		// multiple recorders  	void ErrorTestObject::test<11>()  	{ -		TestRecorder* altRecorder(new TestRecorder); +		LLError::RecorderPtr altRecorder(new TestRecorder());  		LLError::addRecorder(altRecorder);  		LL_INFOS() << "boo" << LL_ENDL;  		ensure_message_contains(0, "boo"); -		ensure_equals("alt recorder count", altRecorder->countMessages(), 1); -		ensure_contains("alt recorder message 0", altRecorder->message(0), "boo"); +		ensure_equals("alt recorder count", boost::dynamic_pointer_cast<TestRecorder>(altRecorder)->countMessages(), 1); +		ensure_contains("alt recorder message 0", boost::dynamic_pointer_cast<TestRecorder>(altRecorder)->message(0), "boo");  		LLError::setTimeFunction(roswell); -		TestRecorder* anotherRecorder(new TestRecorder); -		anotherRecorder->setWantsTime(true); +		LLError::RecorderPtr anotherRecorder(new TestRecorder()); +		boost::dynamic_pointer_cast<TestRecorder>(anotherRecorder)->setWantsTime(true);  		LLError::addRecorder(anotherRecorder);  		LL_INFOS() << "baz" << LL_ENDL; @@ -579,10 +594,13 @@ namespace tut  		std::string when = roswell();  		ensure_message_does_not_contain(1, when); -		ensure_equals("alt recorder count", altRecorder->countMessages(), 2); -		ensure_does_not_contain("alt recorder message 1", altRecorder->message(1), when); -		ensure_equals("another recorder count", anotherRecorder->countMessages(), 1); -		ensure_contains("another recorder message 0", anotherRecorder->message(0), when); +		ensure_equals("alt recorder count", boost::dynamic_pointer_cast<TestRecorder>(altRecorder)->countMessages(), 2); +		ensure_does_not_contain("alt recorder message 1", boost::dynamic_pointer_cast<TestRecorder>(altRecorder)->message(1), when); +		ensure_equals("another recorder count", boost::dynamic_pointer_cast<TestRecorder>(anotherRecorder)->countMessages(), 1); +		ensure_contains("another recorder message 0", boost::dynamic_pointer_cast<TestRecorder>(anotherRecorder)->message(0), when); + +		LLError::removeRecorder(altRecorder); +		LLError::removeRecorder(anotherRecorder);  	}  } diff --git a/indra/llcommon/tests/stringize_test.cpp b/indra/llcommon/tests/stringize_test.cpp index 3e4ca548e5..2a4ed44a67 100755 --- a/indra/llcommon/tests/stringize_test.cpp +++ b/indra/llcommon/tests/stringize_test.cpp @@ -95,7 +95,7 @@ namespace tut          ensure_equals(stringize(f),    "3.14159");          ensure_equals(stringize(d),    "3.14159");          ensure_equals(stringize(abc),  "abc def"); -        ensure_equals(stringize(def),  "def ghi"); //Will generate llwarns due to narrowing. +        ensure_equals(stringize(def),  "def ghi"); //Will generate LL_WARNS() due to narrowing.          ensure_equals(stringize(llsd), "{'abc':'abc def','d':r3.14159,'i':i34}");      } diff --git a/indra/llcommon/tests/wrapllerrs.h b/indra/llcommon/tests/wrapllerrs.h index 3137bd8fea..785197ba11 100755 --- a/indra/llcommon/tests/wrapllerrs.h +++ b/indra/llcommon/tests/wrapllerrs.h @@ -38,6 +38,7 @@  #include "stringize.h"  #include <boost/bind.hpp>  #include <boost/noncopyable.hpp> +#include <boost/shared_ptr.hpp>  #include <list>  #include <string>  #include <stdexcept> @@ -81,72 +82,29 @@ struct WrapLLErrs      }      std::string error; -    LLError::Settings* mPriorErrorSettings; +    LLError::SettingsStoragePtr mPriorErrorSettings;      LLError::FatalFunction mPriorFatal;  };  /** - * LLError::addRecorder() accepts ownership of the passed Recorder* -- it - * expects to be able to delete it later. CaptureLog isa Recorder whose - * pointer we want to be able to pass without any ownership implications. - * For such cases, instantiate a new RecorderProxy(yourRecorder) and pass - * that. Your heap RecorderProxy might later be deleted, but not yourRecorder. - */ -class RecorderProxy: public LLError::Recorder -{ -public: -    RecorderProxy(LLError::Recorder* recorder): -        mRecorder(recorder) -    {} - -    virtual void recordMessage(LLError::ELevel level, const std::string& message) -    { -        mRecorder->recordMessage(level, message); -    } - -    virtual bool wantsTime() -    { -        return mRecorder->wantsTime(); -    } - -private: -    LLError::Recorder* mRecorder; -}; - -/**   * Capture log messages. This is adapted (simplified) from the one in   * llerror_test.cpp.   */ -class CaptureLog : public LLError::Recorder, public boost::noncopyable +class CaptureLogRecorder : public LLError::Recorder, public boost::noncopyable  {  public: -    CaptureLog(LLError::ELevel level=LLError::LEVEL_DEBUG): -        // Mostly what we're trying to accomplish by saving and resetting -        // LLError::Settings is to bypass the default RecordToStderr and -        // RecordToWinDebug Recorders. As these are visible only inside -        // llerror.cpp, we can't just call LLError::removeRecorder() with -        // each. For certain tests we need to produce, capture and examine -        // DEBUG log messages -- but we don't want to spam the user's console -        // with that output. If it turns out that saveAndResetSettings() has -        // some bad effect, give up and just let the DEBUG level log messages -        // display. -        mOldSettings(LLError::saveAndResetSettings()), -        mProxy(new RecorderProxy(this)) +    CaptureLogRecorder() +		: LLError::Recorder(), +		boost::noncopyable(), +		mMessages()      { -        LLError::setFatalFunction(wouldHaveCrashed); -        LLError::setDefaultLevel(level); -        LLError::addRecorder(mProxy);      } -    ~CaptureLog() +    virtual ~CaptureLogRecorder()      { -        LLError::removeRecorder(mProxy); -        delete mProxy; -        LLError::restoreSettings(mOldSettings);      } -    void recordMessage(LLError::ELevel level, -                       const std::string& message) +    virtual void recordMessage(LLError::ELevel level, const std::string& message)      {          mMessages.push_back(message);      } @@ -154,7 +112,7 @@ public:      /// Don't assume the message we want is necessarily the LAST log message      /// emitted by the underlying code; search backwards through all messages      /// for the sought string. -    std::string messageWith(const std::string& search, bool required=true) +    std::string messageWith(const std::string& search, bool required)      {          for (MessageList::const_reverse_iterator rmi(mMessages.rbegin()), rmend(mMessages.rend());               rmi != rmend; ++rmi) @@ -187,14 +145,63 @@ public:          return out;      } +private:      typedef std::list<std::string> MessageList;      MessageList mMessages; -    LLError::Settings* mOldSettings; -    LLError::Recorder* mProxy; +}; + +/** + * Capture log messages. This is adapted (simplified) from the one in + * llerror_test.cpp. + */ +class CaptureLog : public boost::noncopyable +{ +public: +    CaptureLog(LLError::ELevel level=LLError::LEVEL_DEBUG) +        // Mostly what we're trying to accomplish by saving and resetting +        // LLError::Settings is to bypass the default RecordToStderr and +        // RecordToWinDebug Recorders. As these are visible only inside +        // llerror.cpp, we can't just call LLError::removeRecorder() with +        // each. For certain tests we need to produce, capture and examine +        // DEBUG log messages -- but we don't want to spam the user's console +        // with that output. If it turns out that saveAndResetSettings() has +        // some bad effect, give up and just let the DEBUG level log messages +        // display. +		: boost::noncopyable(), +        mOldSettings(LLError::saveAndResetSettings()), +		mRecorder(new CaptureLogRecorder()) +    { +        LLError::setFatalFunction(wouldHaveCrashed); +        LLError::setDefaultLevel(level); +        LLError::addRecorder(mRecorder); +    } + +    ~CaptureLog() +    { +        LLError::removeRecorder(mRecorder); +        LLError::restoreSettings(mOldSettings); +    } + +    /// Don't assume the message we want is necessarily the LAST log message +    /// emitted by the underlying code; search backwards through all messages +    /// for the sought string. +    std::string messageWith(const std::string& search, bool required=true) +    { +		return boost::dynamic_pointer_cast<CaptureLogRecorder>(mRecorder)->messageWith(search, required); +    } + +    std::ostream& streamto(std::ostream& out) const +    { +		return boost::dynamic_pointer_cast<CaptureLogRecorder>(mRecorder)->streamto(out); +    } + +private: +    LLError::SettingsStoragePtr mOldSettings; +	LLError::RecorderPtr mRecorder;  };  inline -std::ostream& operator<<(std::ostream& out, const CaptureLog& log) +std::ostream& operator<<(std::ostream& out, const CaptureLogRecorder& log)  {      return log.streamto(out);  } | 
