From 798d367d54a6c6379ad355bd8345fa40e31e7fe9 Mon Sep 17 00:00:00 2001 From: Jacek Antonelli Date: Sat, 6 Sep 2008 18:24:57 -0500 Subject: Second Life viewer sources 1.21.0-RC --- linden/indra/llcommon/CMakeLists.txt | 188 ++++++ linden/indra/llcommon/files.lst | 49 -- linden/indra/llcommon/indra_constants.h | 14 +- linden/indra/llcommon/linden_common.h | 5 +- linden/indra/llcommon/llapp.cpp | 2 + linden/indra/llcommon/llapr.cpp | 24 +- linden/indra/llcommon/llapr.h | 34 +- linden/indra/llcommon/llares.cpp | 805 ------------------------ linden/indra/llcommon/llares.h | 572 ----------------- linden/indra/llcommon/llassettype.cpp | 20 +- linden/indra/llcommon/llassettype.h | 6 +- linden/indra/llcommon/llbase64.cpp | 2 +- linden/indra/llcommon/llchat.h | 6 +- linden/indra/llcommon/llcommon.vcproj | 608 ------------------ linden/indra/llcommon/llcommon_vc8.vcproj | 847 ------------------------- linden/indra/llcommon/llcommon_vc9.vcproj | 828 ------------------------- linden/indra/llcommon/llcrc.cpp | 224 +++++++ linden/indra/llcommon/llcrc.h | 73 +++ linden/indra/llcommon/lldarray.h | 1 - linden/indra/llcommon/lldate.cpp | 2 +- linden/indra/llcommon/llerror.cpp | 44 +- linden/indra/llcommon/llevent.cpp | 2 +- linden/indra/llcommon/llfile.cpp | 88 ++- linden/indra/llcommon/llfile.h | 81 ++- linden/indra/llcommon/llfixedbuffer.cpp | 2 +- linden/indra/llcommon/llfixedbuffer.h | 2 +- linden/indra/llcommon/llframetimer.cpp | 1 - linden/indra/llcommon/llframetimer.h | 8 +- linden/indra/llcommon/llhash.h | 4 +- linden/indra/llcommon/llheartbeat.cpp | 7 +- linden/indra/llcommon/llindraconfigfile.cpp | 2 +- linden/indra/llcommon/llkeythrottle.h | 110 +++- linden/indra/llcommon/llliveappconfig.cpp | 2 +- linden/indra/llcommon/lllivefile.cpp | 2 +- linden/indra/llcommon/lllslconstants.h | 6 + linden/indra/llcommon/llmd5.cpp | 531 ++++++++++++++++ linden/indra/llcommon/llmd5.h | 133 ++++ linden/indra/llcommon/llmemory.cpp | 1 - linden/indra/llcommon/llmemtype.h | 1 + linden/indra/llcommon/llpreprocessor.h | 7 +- linden/indra/llcommon/llprocessor.cpp | 4 +- linden/indra/llcommon/llprocessor.h | 2 +- linden/indra/llcommon/llptrskiplist.h | 1 + linden/indra/llcommon/llrand.cpp | 176 ++++++ linden/indra/llcommon/llrand.h | 132 ++++ linden/indra/llcommon/llsd.cpp | 28 +- linden/indra/llcommon/llsd.h | 4 +- linden/indra/llcommon/llsdserialize.cpp | 30 +- linden/indra/llcommon/llsdserialize.h | 41 +- linden/indra/llcommon/llsdserialize_xml.cpp | 137 ++++- linden/indra/llcommon/llsdutil.cpp | 132 +--- linden/indra/llcommon/llsdutil.h | 17 +- linden/indra/llcommon/llsecondlifeurls.cpp | 72 +-- linden/indra/llcommon/llsecondlifeurls.h | 32 +- linden/indra/llcommon/llstat.cpp | 5 +- linden/indra/llcommon/llstat.h | 8 +- linden/indra/llcommon/llstatenums.h | 3 +- linden/indra/llcommon/llstl.h | 2 + linden/indra/llcommon/llstring.cpp | 292 ++------- linden/indra/llcommon/llstring.h | 391 +++++------- linden/indra/llcommon/llsys.cpp | 56 +- linden/indra/llcommon/llsys.h | 4 +- linden/indra/llcommon/llthread.cpp | 2 +- linden/indra/llcommon/llthread.h | 2 +- linden/indra/llcommon/lltimer.cpp | 25 +- linden/indra/llcommon/lltimer.h | 37 +- linden/indra/llcommon/lluri.cpp | 2 +- linden/indra/llcommon/lluuid.cpp | 923 ++++++++++++++++++++++++++++ linden/indra/llcommon/lluuid.h | 331 ++++++++++ linden/indra/llcommon/llversionserver.h | 6 +- linden/indra/llcommon/llversionviewer.h | 4 +- linden/indra/llcommon/metapropertyt.h | 13 - linden/indra/llcommon/roles_constants.h | 10 + linden/indra/llcommon/stdtypes.h | 2 + linden/indra/llcommon/u64.cpp | 36 +- linden/indra/llcommon/u64.h | 9 +- 76 files changed, 3641 insertions(+), 4674 deletions(-) create mode 100644 linden/indra/llcommon/CMakeLists.txt delete mode 100644 linden/indra/llcommon/files.lst delete mode 100644 linden/indra/llcommon/llares.cpp delete mode 100644 linden/indra/llcommon/llares.h delete mode 100644 linden/indra/llcommon/llcommon.vcproj delete mode 100644 linden/indra/llcommon/llcommon_vc8.vcproj delete mode 100644 linden/indra/llcommon/llcommon_vc9.vcproj create mode 100644 linden/indra/llcommon/llcrc.cpp create mode 100644 linden/indra/llcommon/llcrc.h create mode 100644 linden/indra/llcommon/llmd5.cpp create mode 100644 linden/indra/llcommon/llmd5.h create mode 100644 linden/indra/llcommon/llrand.cpp create mode 100644 linden/indra/llcommon/llrand.h create mode 100644 linden/indra/llcommon/lluuid.cpp create mode 100644 linden/indra/llcommon/lluuid.h (limited to 'linden/indra/llcommon') diff --git a/linden/indra/llcommon/CMakeLists.txt b/linden/indra/llcommon/CMakeLists.txt new file mode 100644 index 0000000..72d267d --- /dev/null +++ b/linden/indra/llcommon/CMakeLists.txt @@ -0,0 +1,188 @@ +# -*- cmake -*- + +project(llcommon) + +include(00-Common) +include(LLCommon) + +include_directories( + ${EXPAT_INCLUDE_DIRS} + ${LLCOMMON_INCLUDE_DIRS} + ${ZLIB_INCLUDE_DIRS} + ) + +set(llcommon_SOURCE_FILES + llapp.cpp + llapr.cpp + llassettype.cpp + llbase32.cpp + llbase64.cpp + llcommon.cpp + llcrc.cpp + llcriticaldamp.cpp + lldate.cpp + llerror.cpp + llerrorthread.cpp + llevent.cpp + llfasttimer.cpp + llfile.cpp + llfindlocale.cpp + llfixedbuffer.cpp + llformat.cpp + llframetimer.cpp + llheartbeat.cpp + llindraconfigfile.cpp + llliveappconfig.cpp + lllivefile.cpp + lllog.cpp + llmd5.cpp + llmemory.cpp + llmemorystream.cpp + llmetrics.cpp + llmortician.cpp + llprocessor.cpp + llqueuedthread.cpp + llrand.cpp + llrun.cpp + llsd.cpp + llsdserialize.cpp + llsdserialize_xml.cpp + llsdutil.cpp + llsecondlifeurls.cpp + llstat.cpp + llstreamtools.cpp + llstring.cpp + llstringtable.cpp + llsys.cpp + llthread.cpp + lltimer.cpp + lluri.cpp + lluuid.cpp + llworkerthread.cpp + metaclass.cpp + metaproperty.cpp + reflective.cpp + timing.cpp + u64.cpp + ) + +set(llcommon_HEADER_FILES + CMakeLists.txt + + bitpack.h + ctype_workaround.h + doublelinkedlist.h + imageids.h + indra_constants.h + linden_common.h + linked_lists.h + llagentconstants.h + llapp.h + llapr.h + llassettype.h + llassoclist.h + llavatarconstants.h + llbase32.h + llbase64.h + llboost.h + llchat.h + llclickaction.h + llcommon.h + llcrc.h + llcriticaldamp.h + lldarray.h + lldarrayptr.h + lldate.h + lldefs.h + lldepthstack.h + lldlinked.h + lldqueueptr.h + llendianswizzle.h + llenum.h + llerror.h + llerrorcontrol.h + llerrorlegacy.h + llerrorthread.h + llevent.h + lleventemitter.h + llextendedstatus.h + llfasttimer.h + llfile.h + llfindlocale.h + llfixedbuffer.h + llformat.h + llframetimer.h + llhash.h + llheartbeat.h + llindexedqueue.h + llindraconfigfile.h + llkeythrottle.h + lllinkedqueue.h + llliveappconfig.h + lllivefile.h + lllocalidhashmap.h + lllog.h + lllslconstants.h + llmap.h + llmd5.h + llmemory.h + llmemorystream.h + llmemtype.h + llmetrics.h + llmortician.h + llnametable.h + llpreprocessor.h + llpriqueuemap.h + llprocessor.h + llptrskiplist.h + llptrskipmap.h + llqueuedthread.h + llrand.h + llrun.h + llsd.h + llsdserialize.h + llsdserialize_xml.h + llsdutil.h + llsecondlifeurls.h + llsimplehash.h + llskiplist.h + llskipmap.h + llstack.h + llstat.h + llstatenums.h + llstl.h + llstreamtools.h + llstrider.h + llstring.h + llstringtable.h + llsys.h + llthread.h + lltimer.h + lluri.h + lluuid.h + lluuidhashmap.h + llversionserver.h + llversionviewer.h + llworkerthread.h + metaclass.h + metaclasst.h + metaproperty.h + metapropertyt.h + processor.h + reflective.h + reflectivet.h + roles_constants.h + stdenums.h + stdtypes.h + string_table.h + timer.h + timing.h + u64.h + ) + +set_source_files_properties(${llcommon_HEADER_FILES} + PROPERTIES HEADER_FILE_ONLY TRUE) + +list(APPEND llcommon_SOURCE_FILES ${llcommon_HEADER_FILES}) + +add_library (llcommon ${llcommon_SOURCE_FILES}) diff --git a/linden/indra/llcommon/files.lst b/linden/indra/llcommon/files.lst deleted file mode 100644 index d698773..0000000 --- a/linden/indra/llcommon/files.lst +++ /dev/null @@ -1,49 +0,0 @@ -llcommon/llapp.cpp -llcommon/llapr.cpp -llcommon/llares.cpp -llcommon/llassettype.cpp -llcommon/llbase32.cpp -llcommon/llbase64.cpp -llcommon/llcommon.cpp -llcommon/llcriticaldamp.cpp -llcommon/lldate.cpp -llcommon/llerror.cpp -llcommon/llerrorthread.cpp -llcommon/llevent.cpp -llcommon/llfasttimer.cpp -llcommon/llfile.cpp -llcommon/llfindlocale.cpp -llcommon/llfixedbuffer.cpp -llcommon/llformat.cpp -llcommon/llframetimer.cpp -llcommon/llheartbeat.cpp -llcommon/llindraconfigfile.cpp -llcommon/lllog.cpp -llcommon/llliveappconfig.cpp -llcommon/lllivefile.cpp -llcommon/llmemory.cpp -llcommon/llmemorystream.cpp -llcommon/llmetrics.cpp -llcommon/llmortician.cpp -llcommon/llprocessor.cpp -llcommon/llqueuedthread.cpp -llcommon/llrun.cpp -llcommon/llsd.cpp -llcommon/llsdserialize.cpp -llcommon/llsdserialize_xml.cpp -llcommon/llsdutil.cpp -llcommon/llsecondlifeurls.cpp -llcommon/llstat.cpp -llcommon/llstreamtools.cpp -llcommon/llstring.cpp -llcommon/llstringtable.cpp -llcommon/llsys.cpp -llcommon/llthread.cpp -llcommon/lltimer.cpp -llcommon/lluri.cpp -llcommon/llworkerthread.cpp -llcommon/metaclass.cpp -llcommon/metaproperty.cpp -llcommon/reflective.cpp -llcommon/timing.cpp -llcommon/u64.cpp diff --git a/linden/indra/llcommon/indra_constants.h b/linden/indra/llcommon/indra_constants.h index 77f3d8c..1c48a5c 100644 --- a/linden/indra/llcommon/indra_constants.h +++ b/linden/indra/llcommon/indra_constants.h @@ -38,7 +38,11 @@ // At 45 Hz collisions seem stable and objects seem // to settle down at a reasonable rate. // JC 3/18/2003 -const F32 PHYSICS_TIMESTEP = 1.f / 45.f; + +// const F32 PHYSICS_TIMESTEP = 1.f / 45.f; +// This must be a #define due to anal retentive restrictions on const expressions +// CG 2008-06-05 +#define PHYSICS_TIMESTEP (1.f / 45.f) const F32 COLLISION_TOLERANCE = 0.1f; const F32 HALF_COLLISION_TOLERANCE = COLLISION_TOLERANCE * 0.5f; @@ -50,9 +54,9 @@ const U32 DAYS_PER_LINDEN_YEAR = 11; const U32 SEC_PER_LINDEN_DAY = HOURS_PER_LINDEN_DAY * 60 * 60; const U32 SEC_PER_LINDEN_YEAR = DAYS_PER_LINDEN_YEAR * SEC_PER_LINDEN_DAY; -const F32 REGION_WIDTH_METERS = 256.f; -const S32 REGION_WIDTH_UNITS = 256; -const U32 REGION_WIDTH_U32 = 256; +static const F32 REGION_WIDTH_METERS = 256.f; +static const S32 REGION_WIDTH_UNITS = 256; +static const U32 REGION_WIDTH_U32 = 256; const F32 REGION_HEIGHT_METERS = 4096.f; @@ -74,7 +78,7 @@ enum LAND_STAT_REPORT_TYPE const U32 STAT_FILTER_MASK = 0x1FFFFFFF; // Default maximum number of tasks/prims per region. -const U32 MAX_TASKS_PER_REGION = 15000; +const U32 DEFAULT_MAX_REGION_WIDE_PRIM_COUNT = 15000; const F32 MIN_AGENT_DEPTH = 0.30f; const F32 DEFAULT_AGENT_DEPTH = 0.45f; diff --git a/linden/indra/llcommon/linden_common.h b/linden/indra/llcommon/linden_common.h index 547cceb..7d3c82d 100644 --- a/linden/indra/llcommon/linden_common.h +++ b/linden/indra/llcommon/linden_common.h @@ -45,9 +45,10 @@ #include #include -// Work around stupid Microsoft STL warning +// Work Microsoft compiler warnings #ifdef LL_WINDOWS -#pragma warning (disable : 4702) // warning C4702: unreachable code +#pragma warning (disable : 4702) // unreachable code +#pragma warning (disable : 4244) // conversion from time_t to S32 #endif // LL_WINDOWS #include diff --git a/linden/indra/llcommon/llapp.cpp b/linden/indra/llcommon/llapp.cpp index ebace4e..3ca3782 100644 --- a/linden/indra/llcommon/llapp.cpp +++ b/linden/indra/llcommon/llapp.cpp @@ -224,6 +224,7 @@ LLSD LLApp::getOptionData(OptionPriority level) void LLApp::stepFrame() { LLFrameTimer::updateFrameTime(); + LLFrameTimer::updateFrameCount(); LLEventTimer::updateClass(); mRunner.run(); } @@ -492,6 +493,7 @@ void LLApp::setDefaultChildCallback(LLAppChildCallback callback) pid_t LLApp::fork() { + fflush(NULL); // flush all buffers before the child inherits them pid_t pid = ::fork(); if( pid < 0 ) { diff --git a/linden/indra/llcommon/llapr.cpp b/linden/indra/llcommon/llapr.cpp index 78bf876..73e715a 100644 --- a/linden/indra/llcommon/llapr.cpp +++ b/linden/indra/llcommon/llapr.cpp @@ -129,7 +129,7 @@ void ll_apr_assert_status(apr_status_t status) } // File I/O -apr_file_t* ll_apr_file_open(const LLString& filename, apr_int32_t flags, S32* sizep, apr_pool_t* pool) +apr_file_t* ll_apr_file_open(const std::string& filename, apr_int32_t flags, S32* sizep, apr_pool_t* pool) { apr_file_t* apr_file; apr_status_t s; @@ -160,15 +160,15 @@ apr_file_t* ll_apr_file_open(const LLString& filename, apr_int32_t flags, S32* s return apr_file; } -apr_file_t* ll_apr_file_open(const LLString& filename, apr_int32_t flags, S32* sizep) +apr_file_t* ll_apr_file_open(const std::string& filename, apr_int32_t flags, S32* sizep) { return ll_apr_file_open(filename, flags, sizep, NULL); } -apr_file_t* ll_apr_file_open(const LLString& filename, apr_int32_t flags, apr_pool_t* pool) +apr_file_t* ll_apr_file_open(const std::string& filename, apr_int32_t flags, apr_pool_t* pool) { return ll_apr_file_open(filename, flags, NULL, pool); } -apr_file_t* ll_apr_file_open(const LLString& filename, apr_int32_t flags) +apr_file_t* ll_apr_file_open(const std::string& filename, apr_int32_t flags) { return ll_apr_file_open(filename, flags, NULL, NULL); } @@ -188,7 +188,7 @@ S32 ll_apr_file_read(apr_file_t* apr_file, void *buf, S32 nbytes) } } -S32 ll_apr_file_read_ex(const LLString& filename, apr_pool_t* pool, void *buf, S32 offset, S32 nbytes) +S32 ll_apr_file_read_ex(const std::string& filename, apr_pool_t* pool, void *buf, S32 offset, S32 nbytes) { if (pool == NULL) pool = gAPRPoolp; apr_file_t* filep = ll_apr_file_open(filename, APR_READ|APR_BINARY, pool); @@ -230,7 +230,7 @@ S32 ll_apr_file_write(apr_file_t* apr_file, const void *buf, S32 nbytes) } } -S32 ll_apr_file_write_ex(const LLString& filename, apr_pool_t* pool, void *buf, S32 offset, S32 nbytes) +S32 ll_apr_file_write_ex(const std::string& filename, apr_pool_t* pool, void *buf, S32 offset, S32 nbytes) { if (pool == NULL) pool = gAPRPoolp; apr_int32_t flags = APR_CREATE|APR_WRITE|APR_BINARY; @@ -287,7 +287,7 @@ S32 ll_apr_file_seek(apr_file_t* apr_file, apr_seek_where_t where, S32 offset) } } -bool ll_apr_file_remove(const LLString& filename, apr_pool_t* pool) +bool ll_apr_file_remove(const std::string& filename, apr_pool_t* pool) { apr_status_t s; if (pool == NULL) pool = gAPRPoolp; @@ -301,7 +301,7 @@ bool ll_apr_file_remove(const LLString& filename, apr_pool_t* pool) return true; } -bool ll_apr_file_rename(const LLString& filename, const LLString& newname, apr_pool_t* pool) +bool ll_apr_file_rename(const std::string& filename, const std::string& newname, apr_pool_t* pool) { apr_status_t s; if (pool == NULL) pool = gAPRPoolp; @@ -315,7 +315,7 @@ bool ll_apr_file_rename(const LLString& filename, const LLString& newname, apr_p return true; } -bool ll_apr_file_exists(const LLString& filename, apr_pool_t* pool) +bool ll_apr_file_exists(const std::string& filename, apr_pool_t* pool) { apr_file_t* apr_file; apr_status_t s; @@ -332,7 +332,7 @@ bool ll_apr_file_exists(const LLString& filename, apr_pool_t* pool) } } -S32 ll_apr_file_size(const LLString& filename, apr_pool_t* pool) +S32 ll_apr_file_size(const std::string& filename, apr_pool_t* pool) { apr_file_t* apr_file; apr_finfo_t info; @@ -358,7 +358,7 @@ S32 ll_apr_file_size(const LLString& filename, apr_pool_t* pool) } } -bool ll_apr_dir_make(const LLString& dirname, apr_pool_t* pool) +bool ll_apr_dir_make(const std::string& dirname, apr_pool_t* pool) { apr_status_t s; if (pool == NULL) pool = gAPRPoolp; @@ -372,7 +372,7 @@ bool ll_apr_dir_make(const LLString& dirname, apr_pool_t* pool) return true; } -bool ll_apr_dir_remove(const LLString& dirname, apr_pool_t* pool) +bool ll_apr_dir_remove(const std::string& dirname, apr_pool_t* pool) { apr_status_t s; if (pool == NULL) pool = gAPRPoolp; diff --git a/linden/indra/llcommon/llapr.h b/linden/indra/llcommon/llapr.h index 695b93e..323dcb2 100644 --- a/linden/indra/llcommon/llapr.h +++ b/linden/indra/llcommon/llapr.h @@ -40,11 +40,11 @@ #include -#include "apr-1/apr_thread_proc.h" -#include "apr-1/apr_thread_mutex.h" -#include "apr-1/apr_getopt.h" -#include "apr-1/apr_signal.h" -#include "apr-1/apr_atomic.h" +#include "apr_thread_proc.h" +#include "apr_thread_mutex.h" +#include "apr_getopt.h" +#include "apr_signal.h" +#include "apr_atomic.h" #include "llstring.h" extern apr_thread_mutex_t* gLogMutexp; @@ -130,24 +130,24 @@ typedef LLAtomic32 LLAtomicS32; #define LL_APR_WB (APR_CREATE|APR_TRUNCATE|APR_WRITE|APR_BINARY) // "wb" #define LL_APR_RPB (APR_READ|APR_WRITE|APR_BINARY) // "r+b" #define LL_APR_WPB (APR_CREATE|APR_TRUNCATE|APR_READ|APR_WRITE|APR_BINARY) // "w+b" -apr_file_t* ll_apr_file_open(const LLString& filename, apr_int32_t flags, S32* sizep, apr_pool_t* pool); -apr_file_t* ll_apr_file_open(const LLString& filename, apr_int32_t flags, S32* sizep); -apr_file_t* ll_apr_file_open(const LLString& filename, apr_int32_t flags, apr_pool_t* pool); -apr_file_t* ll_apr_file_open(const LLString& filename, apr_int32_t flags); +apr_file_t* ll_apr_file_open(const std::string& filename, apr_int32_t flags, S32* sizep, apr_pool_t* pool); +apr_file_t* ll_apr_file_open(const std::string& filename, apr_int32_t flags, S32* sizep); +apr_file_t* ll_apr_file_open(const std::string& filename, apr_int32_t flags, apr_pool_t* pool); +apr_file_t* ll_apr_file_open(const std::string& filename, apr_int32_t flags); // Returns actual offset, -1 if seek fails S32 ll_apr_file_seek(apr_file_t* apr_file, apr_seek_where_t where, S32 offset); // Returns bytes read/written, 0 if read/write fails: S32 ll_apr_file_read(apr_file_t* apr_file, void* buf, S32 nbytes); -S32 ll_apr_file_read_ex(const LLString& filename, apr_pool_t* pool, void *buf, S32 offset, S32 nbytes); +S32 ll_apr_file_read_ex(const std::string& filename, apr_pool_t* pool, void *buf, S32 offset, S32 nbytes); S32 ll_apr_file_write(apr_file_t* apr_file, const void* buf, S32 nbytes); -S32 ll_apr_file_write_ex(const LLString& filename, apr_pool_t* pool, void *buf, S32 offset, S32 nbytes); +S32 ll_apr_file_write_ex(const std::string& filename, apr_pool_t* pool, void *buf, S32 offset, S32 nbytes); // returns false if failure: -bool ll_apr_file_remove(const LLString& filename, apr_pool_t* pool = NULL); -bool ll_apr_file_rename(const LLString& filename, const LLString& newname, apr_pool_t* pool = NULL); -bool ll_apr_file_exists(const LLString& filename, apr_pool_t* pool = NULL); -S32 ll_apr_file_size(const LLString& filename, apr_pool_t* pool = NULL); -bool ll_apr_dir_make(const LLString& dirname, apr_pool_t* pool = NULL); -bool ll_apr_dir_remove(const LLString& dirname, apr_pool_t* pool = NULL); +bool ll_apr_file_remove(const std::string& filename, apr_pool_t* pool = NULL); +bool ll_apr_file_rename(const std::string& filename, const std::string& newname, apr_pool_t* pool = NULL); +bool ll_apr_file_exists(const std::string& filename, apr_pool_t* pool = NULL); +S32 ll_apr_file_size(const std::string& filename, apr_pool_t* pool = NULL); +bool ll_apr_dir_make(const std::string& dirname, apr_pool_t* pool = NULL); +bool ll_apr_dir_remove(const std::string& dirname, apr_pool_t* pool = NULL); /** * @brief Function which approprately logs error or remains quiet on diff --git a/linden/indra/llcommon/llares.cpp b/linden/indra/llcommon/llares.cpp deleted file mode 100644 index 4d054e4..0000000 --- a/linden/indra/llcommon/llares.cpp +++ /dev/null @@ -1,805 +0,0 @@ -/** - * @file llares.cpp - * @author Bryan O'Sullivan - * @date 2007-08-15 - * @brief Wrapper for asynchronous DNS lookups. - * - * $LicenseInfo:firstyear=2007&license=viewergpl$ - * - * Copyright (c) 2007-2008, Linden Research, Inc. - * - * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 - * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception - * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. - * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. - * $/LicenseInfo$ - */ - -#ifdef LL_STANDALONE -# include -#else -# include -#endif - -#include "apr-1/apr_portable.h" -#include "apr-1/apr_network_io.h" -#include "apr-1/apr_poll.h" - -#include "linden_common.h" -#include "llapr.h" -#include "llares.h" - -#if defined(LL_WINDOWS) -# define ns_c_in 1 -# define NS_HFIXEDSZ 12 /* #/bytes of fixed data in header */ -# define NS_QFIXEDSZ 4 /* #/bytes of fixed data in query */ -# define NS_RRFIXEDSZ 10 /* #/bytes of fixed data in r record */ -#else -# include -#endif - -LLAres::HostResponder::~HostResponder() -{ -} - -void LLAres::HostResponder::hostResult(const hostent *ent) -{ - llinfos << "LLAres::HostResponder::hostResult not implemented" << llendl; -} - -void LLAres::HostResponder::hostError(int code) -{ - llinfos << "LLAres::HostResponder::hostError " << code << ": " - << LLAres::strerror(code) << llendl; -} - -LLAres::NameInfoResponder::~NameInfoResponder() -{ -} - -void LLAres::NameInfoResponder::nameInfoResult(const char *node, - const char *service) -{ - llinfos << "LLAres::NameInfoResponder::nameInfoResult not implemented" - << llendl; -} - -void LLAres::NameInfoResponder::nameInfoError(int code) -{ - llinfos << "LLAres::NameInfoResponder::nameInfoError " << code << ": " - << LLAres::strerror(code) << llendl; -} - -LLAres::QueryResponder::~QueryResponder() -{ -} - -void LLAres::QueryResponder::queryResult(const char *buf, size_t len) -{ - llinfos << "LLAres::QueryResponder::queryResult not implemented" - << llendl; -} - -void LLAres::QueryResponder::queryError(int code) -{ - llinfos << "LLAres::QueryResponder::queryError " << code << ": " - << LLAres::strerror(code) << llendl; -} - -LLAres::LLAres() - : chan_(NULL) -{ - ares_init(&chan_); -} - -LLAres::~LLAres() -{ - if (chan_) - ares_destroy(chan_); -} - -void LLAres::cancel() -{ - if (chan_) - ares_cancel(chan_); -} - -static void host_callback(void *arg, int status, struct hostent *ent) -{ - LLPointer *resp = - (LLPointer *) arg; - - if (status == ARES_SUCCESS) - { - (*resp)->hostResult(ent); - } else { - (*resp)->hostError(status); - } - - delete resp; -} - -void LLAres::getHostByName(const char *name, HostResponder *resp, - int family) -{ - if (!chan_) - { - resp->hostError(ARES_EBADRESP); - return; - } - ares_gethostbyname(chan_, name, family, host_callback, - new LLPointer(resp)); -} - -void LLAres::getSrvRecords(const std::string &name, SrvResponder *resp) -{ - search(name, RES_SRV, resp); -} - -void LLAres::rewriteURI(const std::string &uri, UriRewriteResponder *resp) -{ - LL_DEBUGS2("AppInit","Rewrite") << "Rewriting " << uri << LL_ENDL; - - resp->mUri = LLURI(uri); - search("_" + resp->mUri.scheme() + "._tcp." + resp->mUri.hostName(), - RES_SRV, resp); -} - -LLQueryResponder::LLQueryResponder() - : LLAres::QueryResponder(), - mResult(ARES_ENODATA), - mType(RES_INVALID) -{ -} - -int LLQueryResponder::parseRR(const char *buf, size_t len, const char *&pos, - LLPointer &r) -{ - std::string rrname; - size_t enclen; - int ret; - - // RR name. - - ret = LLAres::expandName(pos, buf, len, rrname, enclen); - if (ret != ARES_SUCCESS) - { - return ret; - } - - pos += enclen; - - if (pos + NS_RRFIXEDSZ > buf + len) - { - return ARES_EBADRESP; - } - - int rrtype = DNS_RR_TYPE(pos); - int rrclass = DNS_RR_CLASS(pos); - int rrttl = DNS_RR_TTL(pos); - int rrlen = DNS_RR_LEN(pos); - - if (rrclass != ns_c_in) - { - return ARES_EBADRESP; - } - - pos += NS_RRFIXEDSZ; - - if (pos + rrlen > buf + len) - { - return ARES_EBADRESP; - } - - switch (rrtype) - { - case RES_A: - r = new LLARecord(rrname, rrttl); - break; - case RES_NS: - r = new LLNsRecord(rrname, rrttl); - break; - case RES_CNAME: - r = new LLCnameRecord(rrname, rrttl); - break; - case RES_PTR: - r = new LLPtrRecord(rrname, rrttl); - break; - case RES_AAAA: - r = new LLAaaaRecord(rrname, rrttl); - break; - case RES_SRV: - r = new LLSrvRecord(rrname, rrttl); - break; - default: - llinfos << "LLQueryResponder::parseRR got unknown RR type " << rrtype - << llendl; - return ARES_EBADRESP; - } - - ret = r->parse(buf, len, pos, rrlen); - - if (ret == ARES_SUCCESS) - { - pos += rrlen; - } else { - r = NULL; - } - - return ret; -} - -int LLQueryResponder::parseSection(const char *buf, size_t len, - size_t count, const char *&pos, - dns_rrs_t &rrs) -{ - int ret = ARES_SUCCESS; - - for (size_t i = 0; i < count; i++) - { - LLPointer r; - ret = parseRR(buf, len, pos, r); - if (ret != ARES_SUCCESS) - { - break; - } - rrs.push_back(r); - } - - return ret; -} - -void LLQueryResponder::queryResult(const char *buf, size_t len) -{ - const char *pos = buf; - int qdcount = DNS_HEADER_QDCOUNT(pos); - int ancount = DNS_HEADER_ANCOUNT(pos); - int nscount = DNS_HEADER_NSCOUNT(pos); - int arcount = DNS_HEADER_ARCOUNT(pos); - int ret; - - if (qdcount == 0 || ancount + nscount + arcount == 0) - { - ret = ARES_ENODATA; - goto bail; - } - - pos += NS_HFIXEDSZ; - - for (int i = 0; i < qdcount; i++) - { - std::string ignore; - size_t enclen; - - ret = LLAres::expandName(pos, buf, len, i == 0 ? mQuery : ignore, - enclen); - if (ret != ARES_SUCCESS) - { - goto bail; - } - - pos += enclen; - - if (i == 0) - { - int t = DNS_QUESTION_TYPE(pos); - switch (t) - { - case RES_A: - case RES_NS: - case RES_CNAME: - case RES_PTR: - case RES_AAAA: - case RES_SRV: - mType = (LLResType) t; - break; - default: - llinfos << "Cannot grok query type " << t << llendl; - ret = ARES_EBADQUERY; - goto bail; - } - } - - pos += NS_QFIXEDSZ; - if (pos > buf + len) - { - ret = ARES_EBADRESP; - goto bail; - } - } - - ret = parseSection(buf, len, ancount, pos, mAnswers); - if (ret != ARES_SUCCESS) - { - goto bail; - } - - ret = parseSection(buf, len, nscount, pos, mAuthorities); - if (ret != ARES_SUCCESS) - { - goto bail; - } - - ret = parseSection(buf, len, arcount, pos, mAdditional); - -bail: - mResult = ret; - if (mResult == ARES_SUCCESS) - { - queryResult(); - } else { - queryError(mResult); - } -} - -void LLQueryResponder::queryResult() -{ - llinfos << "LLQueryResponder::queryResult not implemented" << llendl; -} - -void LLAres::SrvResponder::queryResult() -{ - if (mType == RES_SRV) - { - srvResult(mAnswers); - } else { - srvError(ARES_EBADRESP); - } -} - -void LLAres::SrvResponder::queryError(int code) -{ - srvError(code); -} - -void LLAres::SrvResponder::srvResult(const dns_rrs_t &ents) -{ - llinfos << "LLAres::SrvResponder::srvResult not implemented" << llendl; - - for (size_t i = 0; i < ents.size(); i++) - { - const LLSrvRecord *s = (const LLSrvRecord *) ents[i].get(); - - llinfos << "[" << i << "] " << s->host() << ":" << s->port() - << " priority " << s->priority() - << " weight " << s->weight() - << llendl; - } -} - -void LLAres::SrvResponder::srvError(int code) -{ - llinfos << "LLAres::SrvResponder::srvError " << code << ": " - << LLAres::strerror(code) << llendl; -} - -static void nameinfo_callback(void *arg, int status, char *node, char *service) -{ - LLPointer *resp = - (LLPointer *) arg; - - if (status == ARES_SUCCESS) - { - (*resp)->nameInfoResult(node, service); - } else { - (*resp)->nameInfoError(status); - } - - delete resp; -} - -void LLAres::getNameInfo(const struct sockaddr &sa, socklen_t salen, int flags, - NameInfoResponder *resp) -{ - if (!chan_) - { - resp->nameInfoError(ARES_EBADRESP); - return; - } - ares_getnameinfo(chan_, &sa, salen, flags, nameinfo_callback, - new LLPointer(resp)); -} - -static void search_callback(void *arg, int status, unsigned char *abuf, - int alen) -{ - LLPointer *resp = - (LLPointer *) arg; - - if (status == ARES_SUCCESS) - { - (*resp)->queryResult((const char *) abuf, alen); - } else { - (*resp)->queryError(status); - } - - delete resp; -} - -void LLAres::search(const std::string &query, LLResType type, - QueryResponder *resp) -{ - if (!chan_) - { - resp->queryError(ARES_EBADRESP); - return; - } - ares_search(chan_, query.c_str(), ns_c_in, type, search_callback, - new LLPointer(resp)); -} - -bool LLAres::process(U64 timeout) -{ - if (!gAPRPoolp) - { - ll_init_apr(); - } - - int socks[ARES_GETSOCK_MAXNUM]; - apr_pollfd_t aprFds[ARES_GETSOCK_MAXNUM]; - apr_int32_t nsds = 0; - apr_status_t status; - apr_pool_t *pool; - int nactive = 0; - int bitmask; - - if (!chan_) - { - goto bail; - } - - bitmask = ares_getsock(chan_, socks, ARES_GETSOCK_MAXNUM); - - if (bitmask == 0) - { - goto bail; - } - - status = apr_pool_create(&pool, gAPRPoolp); - ll_apr_assert_status(status); - - for (int i = 0; i < ARES_GETSOCK_MAXNUM; i++) - { - if (ARES_GETSOCK_READABLE(bitmask, i)) - { - aprFds[nactive].reqevents = APR_POLLIN | APR_POLLERR; - } - else if (ARES_GETSOCK_WRITABLE(bitmask, i)) - { - aprFds[nactive].reqevents = APR_POLLOUT | APR_POLLERR; - } else { - continue; - } - - apr_socket_t *aprSock = NULL; - - status = apr_os_sock_put(&aprSock, (apr_os_sock_t *) &socks[i], pool); - if (status != APR_SUCCESS) - { - ll_apr_warn_status(status); - goto bail_pool; - } - - aprFds[nactive].desc.s = aprSock; - aprFds[nactive].desc_type = APR_POLL_SOCKET; - aprFds[nactive].p = pool; - aprFds[nactive].rtnevents = 0; - aprFds[nactive].client_data = &socks[i]; - - nactive++; - } - - if (nactive > 0) - { - status = apr_poll(aprFds, nactive, &nsds, timeout); - - if (status != APR_SUCCESS && status != APR_TIMEUP) - { - ll_apr_warn_status(status); - } - - for (int i = 0; i < nactive; i++) - { - int evts = aprFds[i].rtnevents; - int ifd = (evts & (APR_POLLIN | APR_POLLERR)) - ? *((int *) aprFds[i].client_data) : ARES_SOCKET_BAD; - int ofd = (evts & (APR_POLLOUT | APR_POLLERR)) - ? *((int *) aprFds[i].client_data) : ARES_SOCKET_BAD; - - ares_process_fd(chan_, ifd, ofd); - } - } - -bail_pool: - apr_pool_destroy(pool); - -bail: - return nsds > 0; -} - -bool LLAres::processAll() -{ - if (!chan_) - { - return false; - } - - bool anyProcessed = false, ret; - - do { - timeval tv; - - ret = ares_timeout(chan_, NULL, &tv) != NULL; - - if (ret) - { - ret = process(tv.tv_sec * 1000000LL + tv.tv_usec); - anyProcessed |= ret; - } - } while (ret); - - return anyProcessed; -} - -int LLAres::expandName(const char *encoded, const char *abuf, size_t alen, - std::string &s, size_t &enclen) -{ - char *t; - int ret; - long e; - - ret = ares_expand_name((const unsigned char *) encoded, - (const unsigned char *) abuf, alen, &t, &e); - if (ret == ARES_SUCCESS) - { - s.assign(t); - enclen = e; - ares_free_string(t); - } - return ret; -} - -const char *LLAres::strerror(int code) -{ - return ares_strerror(code); -} - -LLAres *gAres; - -LLAres *ll_init_ares() -{ - if (gAres == NULL) - { - gAres = new LLAres(); - } - return gAres; -} - -LLDnsRecord::LLDnsRecord(LLResType type, const std::string &name, - unsigned ttl) - : LLRefCount(), - mType(type), - mName(name), - mTTL(ttl) -{ -} - -LLHostRecord::LLHostRecord(LLResType type, const std::string &name, - unsigned ttl) - : LLDnsRecord(type, name, ttl) -{ -} - -int LLHostRecord::parse(const char *buf, size_t len, const char *pos, - size_t rrlen) -{ - int ret; - - ret = LLAres::expandName(pos, buf, len, mHost); - if (ret != ARES_SUCCESS) - { - goto bail; - } - - ret = ARES_SUCCESS; - -bail: - return ret; -} - -LLCnameRecord::LLCnameRecord(const std::string &name, unsigned ttl) - : LLHostRecord(RES_CNAME, name, ttl) -{ -} - -LLPtrRecord::LLPtrRecord(const std::string &name, unsigned ttl) - : LLHostRecord(RES_PTR, name, ttl) -{ -} - -LLAddrRecord::LLAddrRecord(LLResType type, const std::string &name, - unsigned ttl) - : LLDnsRecord(type, name, ttl) -{ -} - -LLARecord::LLARecord(const std::string &name, unsigned ttl) - : LLAddrRecord(RES_A, name, ttl) -{ -} - -int LLARecord::parse(const char *buf, size_t len, const char *pos, - size_t rrlen) -{ - int ret; - - if (rrlen != sizeof(mSA.sin.sin_addr.s_addr)) - { - ret = ARES_EBADRESP; - goto bail; - } - - memset(&mSA, 0, sizeof(mSA)); - memcpy(&mSA.sin.sin_addr.s_addr, pos, rrlen); - mSA.sin.sin_family = AF_INET6; - mSize = sizeof(mSA.sin); - - ret = ARES_SUCCESS; - -bail: - return ret; -} - -LLAaaaRecord::LLAaaaRecord(const std::string &name, unsigned ttl) - : LLAddrRecord(RES_AAAA, name, ttl) -{ -} - -int LLAaaaRecord::parse(const char *buf, size_t len, const char *pos, - size_t rrlen) -{ - int ret; - - if (rrlen != sizeof(mSA.sin6.sin6_addr)) - { - ret = ARES_EBADRESP; - goto bail; - } - - memset(&mSA, 0, sizeof(mSA)); - memcpy(&mSA.sin6.sin6_addr.s6_addr, pos, rrlen); - mSA.sin6.sin6_family = AF_INET6; - mSize = sizeof(mSA.sin6); - - ret = ARES_SUCCESS; - -bail: - return ret; -} - -LLSrvRecord::LLSrvRecord(const std::string &name, unsigned ttl) - : LLHostRecord(RES_SRV, name, ttl) -{ -} - -int LLSrvRecord::parse(const char *buf, size_t len, const char *pos, - size_t rrlen) -{ - int ret; - - if (rrlen < 6) - { - ret = ARES_EBADRESP; - goto bail; - } - - memcpy(&mPriority, pos, 2); - memcpy(&mWeight, pos + 2, 2); - memcpy(&mPort, pos + 4, 2); - - mPriority = ntohs(mPriority); - mWeight = ntohs(mWeight); - mPort = ntohs(mPort); - - ret = LLHostRecord::parse(buf, len, pos + 6, rrlen - 6); - -bail: - return ret; -} - -LLNsRecord::LLNsRecord(const std::string &name, unsigned ttl) - : LLHostRecord(RES_NS, name, ttl) -{ -} - -void LLAres::UriRewriteResponder::queryError(int code) -{ - std::vector uris; - uris.push_back(mUri.asString()); - rewriteResult(uris); -} - -void LLAres::UriRewriteResponder::queryResult() -{ - std::vector uris; - - if (mType != RES_SRV) - { - goto bail; - } - - for (size_t i = 0; i < mAnswers.size(); i++) - { - const LLSrvRecord *r = (const LLSrvRecord *) mAnswers[i].get(); - - if (r->type() == RES_SRV) - { - // Check the domain in the response to ensure that it's - // the same as the domain in the request, so that bad guys - // can't forge responses that point to their own login - // servers with their own certificates. - - // Hard-coding the domain to check here is a bit of a - // hack. Hoist it to an outer caller if anyone ever needs - // this functionality on other domains. - - static const std::string domain(".lindenlab.com"); - const std::string &host = r->host(); - - std::string::size_type s = host.find(domain) + domain.length(); - - if (s != host.length() && s != host.length() - 1) - { - continue; - } - - LLURI uri(mUri.scheme(), - mUri.userName(), - mUri.password(), - r->host(), - mUri.defaultPort() ? r->port() : mUri.hostPort(), - mUri.escapedPath(), - mUri.escapedQuery()); - uris.push_back(uri.asString()); - } - } - - if (!uris.empty()) - { - goto done; - } - -bail: - uris.push_back(mUri.asString()); - -done: - rewriteResult(uris); -} - -void LLAres::UriRewriteResponder::rewriteResult( - const std::vector &uris) -{ - llinfos << "LLAres::UriRewriteResponder::rewriteResult not implemented" - << llendl; - - for (size_t i = 0; i < uris.size(); i++) - { - llinfos << "[" << i << "] " << uris[i] << llendl; - } -} diff --git a/linden/indra/llcommon/llares.h b/linden/indra/llcommon/llares.h deleted file mode 100644 index 07957f1..0000000 --- a/linden/indra/llcommon/llares.h +++ /dev/null @@ -1,572 +0,0 @@ -/** - * @file llares.h - * @author Bryan O'Sullivan - * @date 2007-08-15 - * @brief Wrapper for asynchronous DNS lookups. - * - * $LicenseInfo:firstyear=2007&license=viewergpl$ - * - * Copyright (c) 2007-2008, Linden Research, Inc. - * - * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 - * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception - * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. - * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. - * $/LicenseInfo$ - */ - -#ifndef LL_LLARES_H -#define LL_LLARES_H - -#ifdef LL_WINDOWS -# include -#endif - -#ifdef LL_STANDALONE -# include -#else -# include -#endif - -#include "llmemory.h" -#include "lluri.h" - -class LLQueryResponder; - -/** - * @brief Supported DNS RR types. - */ -enum LLResType -{ - RES_INVALID = 0, /**< Cookie. */ - RES_A = 1, /**< "A" record. IPv4 address. */ - RES_NS = 2, /**< "NS" record. Authoritative server. */ - RES_CNAME = 5, /**< "CNAME" record. Canonical name. */ - RES_PTR = 12, /**< "PTR" record. Domain name pointer. */ - RES_AAAA = 28, /**< "AAAA" record. IPv6 Address. */ - RES_SRV = 33, /**< "SRV" record. Server Selection. */ - RES_MAX = 65536 /**< Sentinel; RR types are 16 bits wide. */ -}; - -/** - * @class LLDnsRecord - * @brief Base class for all DNS RR types. - */ -class LLDnsRecord : public LLRefCount -{ -protected: - friend class LLQueryResponder; - - LLResType mType; - std::string mName; - unsigned mTTL; - - virtual int parse(const char *buf, size_t len, const char *pos, - size_t rrlen) = 0; - - LLDnsRecord(LLResType type, const std::string &name, unsigned ttl); - -public: - /** - * @brief Record name. - */ - const std::string &name() const { return mName; } - - /** - * @brief Time-to-live value, in seconds. - */ - unsigned ttl() const { return mTTL; } - - /** - * @brief RR type. - */ - LLResType type() const { return mType; } -}; - -/** - * @class LLAddrRecord - * @brief Base class for address-related RRs. - */ -class LLAddrRecord : public LLDnsRecord -{ -protected: - friend class LLQueryResponder; - - LLAddrRecord(LLResType type, const std::string &name, unsigned ttl); - - union - { - sockaddr sa; - sockaddr_in sin; - sockaddr_in6 sin6; - } mSA; - - socklen_t mSize; - -public: - /** - * @brief Generic socket address. - */ - const sockaddr &addr() const { return mSA.sa; } - - /** - * @brief Size of the socket structure. - */ - socklen_t size() const { return mSize; } -}; - -/** - * @class LLARecord - * @brief A RR, for IPv4 addresses. - */ -class LLARecord : public LLAddrRecord -{ -protected: - friend class LLQueryResponder; - - LLARecord(const std::string &name, unsigned ttl); - - int parse(const char *buf, size_t len, const char *pos, size_t rrlen); - -public: - /** - * @brief Socket address. - */ - const sockaddr_in &addr_in() const { return mSA.sin; } -}; - -/** - * @class LLAaaaRecord - * @brief AAAA RR, for IPv6 addresses. - */ -class LLAaaaRecord : public LLAddrRecord -{ -protected: - friend class LLQueryResponder; - - LLAaaaRecord(const std::string &name, unsigned ttl); - - int parse(const char *buf, size_t len, const char *pos, size_t rrlen); - -public: - /** - * @brief Socket address. - */ - const sockaddr_in6 &addr_in6() const { return mSA.sin6; } -}; - -/** - * @class LLHostRecord - * @brief Base class for host-related RRs. - */ -class LLHostRecord : public LLDnsRecord -{ -protected: - LLHostRecord(LLResType type, const std::string &name, unsigned ttl); - - int parse(const char *buf, size_t len, const char *pos, size_t rrlen); - - std::string mHost; - -public: - /** - * @brief Host name. - */ - const std::string &host() const { return mHost; } -}; - -/** - * @class LLCnameRecord - * @brief CNAME RR. - */ -class LLCnameRecord : public LLHostRecord -{ -protected: - friend class LLQueryResponder; - - LLCnameRecord(const std::string &name, unsigned ttl); -}; - -/** - * @class LLPtrRecord - * @brief PTR RR. - */ -class LLPtrRecord : public LLHostRecord -{ -protected: - friend class LLQueryResponder; - - LLPtrRecord(const std::string &name, unsigned ttl); -}; - -/** - * @class LLSrvRecord - * @brief SRV RR. - */ -class LLSrvRecord : public LLHostRecord -{ -protected: - U16 mPriority; - U16 mWeight; - U16 mPort; - - int parse(const char *buf, size_t len, const char *pos, size_t rrlen); - -public: - LLSrvRecord(const std::string &name, unsigned ttl); - - /** - * @brief Service priority. - */ - U16 priority() const { return mPriority; } - - /** - * @brief Service weight. - */ - U16 weight() const { return mWeight; } - - /** - * @brief Port number of service. - */ - U16 port() const { return mPort; } - - /** - * @brief Functor for sorting SRV records by priority. - */ - struct ComparePriorityLowest - { - bool operator()(const LLSrvRecord& lhs, const LLSrvRecord& rhs) - { - return lhs.mPriority < rhs.mPriority; - } - }; -}; - -/** - * @class LLNsRecord - * @brief NS RR. - */ -class LLNsRecord : public LLHostRecord -{ -public: - LLNsRecord(const std::string &name, unsigned ttl); -}; - -class LLQueryResponder; - -/** - * @class LLAres - * @brief Asynchronous address resolver. - */ -class LLAres -{ -public: - /** - * @class HostResponder - * @brief Base class for responding to hostname lookups. - * @see LLAres::getHostByName - */ - class HostResponder : public LLRefCount - { - public: - virtual ~HostResponder(); - - virtual void hostResult(const hostent *ent); - virtual void hostError(int code); - }; - - /** - * @class NameInfoResponder - * @brief Base class for responding to address lookups. - * @see LLAres::getNameInfo - */ - class NameInfoResponder : public LLRefCount - { - public: - virtual ~NameInfoResponder(); - - virtual void nameInfoResult(const char *node, const char *service); - virtual void nameInfoError(int code); - }; - - /** - * @class QueryResponder - * @brief Base class for responding to custom searches. - * @see LLAres::search - */ - class QueryResponder : public LLRefCount - { - public: - virtual ~QueryResponder(); - - virtual void queryResult(const char *buf, size_t len); - virtual void queryError(int code); - }; - - class SrvResponder; - class UriRewriteResponder; - - LLAres(); - - ~LLAres(); - - /** - * Cancel all outstanding requests. The error methods of the - * corresponding responders will be called, with ARES_ETIMEOUT. - */ - void cancel(); - - /** - * Look up the address of a host. - * - * @param name name of host to look up - * @param resp responder to call with result - * @param family AF_INET for IPv4 addresses, AF_INET6 for IPv6 - */ - void getHostByName(const std::string &name, HostResponder *resp, - int family = AF_INET) { - getHostByName(name.c_str(), resp, family); - } - - /** - * Look up the address of a host. - * - * @param name name of host to look up - * @param resp responder to call with result - * @param family AF_INET for IPv4 addresses, AF_INET6 for IPv6 - */ - void getHostByName(const char *name, HostResponder *resp, - int family = PF_INET); - - /** - * Look up the name associated with a socket address. - * - * @param sa socket address to look up - * @param salen size of socket address - * @param flags flags to use - * @param resp responder to call with result - */ - void getNameInfo(const struct sockaddr &sa, socklen_t salen, int flags, - NameInfoResponder *resp); - - /** - * Look up SRV (service location) records for a service name. - * - * @param name service name (e.g. "_https._tcp.login.agni.lindenlab.com") - * @param resp responder to call with result - */ - void getSrvRecords(const std::string &name, SrvResponder *resp); - - /** - * Rewrite a URI, using SRV (service location) records for its - * protocol if available. If no SRV records are published, the - * existing URI is handed to the responder. - * - * @param uri URI to rewrite - * @param resp responder to call with result - */ - void rewriteURI(const std::string &uri, - UriRewriteResponder *resp); - - /** - * Start a custom search. - * - * @param query query to make - * @param type type of query to perform - * @param resp responder to call with result - */ - void search(const std::string &query, LLResType type, - QueryResponder *resp); - - /** - * Process any outstanding queries. This method takes an optional - * timeout parameter (specified in microseconds). If provided, it - * will block the calling thread for that length of time to await - * possible responses. A timeout of zero will return immediately - * if there are no responses or timeouts to process. - * - * @param timeoutUsecs number of microseconds to block before timing out - * @return whether any responses were processed - */ - bool process(U64 timeoutUsecs = 0); - - /** - * Process all outstanding queries, blocking the calling thread - * until all have either been responded to or timed out. - * - * @return whether any responses were processed - */ - bool processAll(); - - /** - * Expand a DNS-encoded compressed string into a normal string. - * - * @param encoded the encoded name (null-terminated) - * @param abuf the response buffer in which the string is embedded - * @param alen the length of the response buffer - * @param s the string into which to place the result - * @return ARES_SUCCESS on success, otherwise an error indicator - */ - static int expandName(const char *encoded, const char *abuf, size_t alen, - std::string &s) { - size_t ignore; - return expandName(encoded, abuf, alen, s, ignore); - } - - static int expandName(const char *encoded, const char *abuf, size_t alen, - std::string &s, size_t &enclen); - - /** - * Return a string describing an error code. - */ - static const char *strerror(int code); - -protected: - ares_channel chan_; - -}; - -/** - * An ordered collection of DNS resource records. - */ -typedef std::vector > dns_rrs_t; - -/** - * @class LLQueryResponder - * @brief Base class for friendly handling of DNS query responses. - * - * This class parses a DNS response and represents it in a friendly - * manner. - * - * @see LLDnsRecord - * @see LLARecord - * @see LLNsRecord - * @see LLCnameRecord - * @see LLPtrRecord - * @see LLAaaaRecord - * @see LLSrvRecord - */ -class LLQueryResponder : public LLAres::QueryResponder -{ -protected: - int mResult; - std::string mQuery; - LLResType mType; - - dns_rrs_t mAnswers; - dns_rrs_t mAuthorities; - dns_rrs_t mAdditional; - - /** - * Parse a single RR. - */ - int parseRR(const char *buf, size_t len, const char *&pos, - LLPointer &r); - /** - * Parse one section of a response. - */ - int parseSection(const char *buf, size_t len, - size_t count, const char *& pos, dns_rrs_t &rrs); - - void queryResult(const char *buf, size_t len); - virtual void queryResult(); - -public: - LLQueryResponder(); - - /** - * Indicate whether the response could be parsed successfully. - */ - bool valid() const { return mResult == ARES_SUCCESS; } - - /** - * The more detailed result of parsing the response. - */ - int result() const { return mResult; } - - /** - * Return the query embedded in the response. - */ - const std::string &query() const { return mQuery; } - - /** - * Return the contents of the "answers" section of the response. - */ - const dns_rrs_t &answers() const { return mAnswers; } - - /** - * Return the contents of the "authorities" section of the - * response. - */ - const dns_rrs_t &authorities() const { return mAuthorities; } - - /** - * Return the contents of the "additional records" section of the - * response. - */ - const dns_rrs_t &additional() const { return mAdditional; } -}; - -/** - * @class LLAres::SrvResponder - * @brief Class for handling SRV query responses. - */ -class LLAres::SrvResponder : public LLQueryResponder -{ -public: - friend void LLAres::getSrvRecords(const std::string &name, - SrvResponder *resp); - void queryResult(); - void queryError(int code); - - virtual void srvResult(const dns_rrs_t &ents); - virtual void srvError(int code); -}; - -/** - * @class LLAres::UriRewriteResponder - * @brief Class for handling URI rewrites based on SRV records. - */ -class LLAres::UriRewriteResponder : public LLQueryResponder -{ -protected: - LLURI mUri; - -public: - friend void LLAres::rewriteURI(const std::string &uri, - UriRewriteResponder *resp); - void queryResult(); - void queryError(int code); - - virtual void rewriteResult(const std::vector &uris); -}; - -/** - * Singleton responder. - */ -extern LLAres *gAres; - -/** - * Set up the singleton responder. It's safe to call this more than - * once from within a single thread, but this function is not - * thread safe. - */ -extern LLAres *ll_init_ares(); - -#endif // LL_LLARES_H diff --git a/linden/indra/llcommon/llassettype.cpp b/linden/indra/llcommon/llassettype.cpp index 4b2a862..27b8310 100644 --- a/linden/indra/llcommon/llassettype.cpp +++ b/linden/indra/llcommon/llassettype.cpp @@ -75,7 +75,7 @@ asset_info_t asset_types[] = LLAssetType::EType LLAssetType::getType(const std::string& sin) { std::string s = sin; - LLString::toUpper(s); + LLStringUtil::toUpper(s); for (S32 idx = 0; ;idx++) { asset_info_t* info = asset_types + idx; @@ -128,7 +128,7 @@ const char* LLAssetType::mAssetTypeNames[LLAssetType::AT_COUNT] = "jpeg", "animatn", "gesture", - "simstate", + "simstate" }; // This table is meant for decoding to human readable form. Put any @@ -158,7 +158,7 @@ const char* LLAssetType::mAssetTypeHumanNames[LLAssetType::AT_COUNT] = "jpeg image", "animation", "gesture", - "simstate", + "simstate" }; ///---------------------------------------------------------------------------- @@ -181,9 +181,14 @@ const char* LLAssetType::lookup( LLAssetType::EType type ) // static LLAssetType::EType LLAssetType::lookup( const char* name ) { + return lookup(ll_safe_string(name)); +} + +LLAssetType::EType LLAssetType::lookup( const std::string& name ) +{ for( S32 i = 0; i < AT_COUNT; i++ ) { - if( 0 == strcmp(name, mAssetTypeNames[i]) ) + if( name == mAssetTypeNames[i] ) { // match return (EType)i; @@ -208,9 +213,14 @@ const char* LLAssetType::lookupHumanReadable(LLAssetType::EType type) // static LLAssetType::EType LLAssetType::lookupHumanReadable( const char* name ) { + return lookupHumanReadable(ll_safe_string(name)); +} + +LLAssetType::EType LLAssetType::lookupHumanReadable( const std::string& name ) +{ for( S32 i = 0; i < AT_COUNT; i++ ) { - if( 0 == strcmp(name, mAssetTypeHumanNames[i]) ) + if( name == mAssetTypeHumanNames[i] ) { // match return (EType)i; diff --git a/linden/indra/llcommon/llassettype.h b/linden/indra/llcommon/llassettype.h index f5ef05b..f976df4 100644 --- a/linden/indra/llcommon/llassettype.h +++ b/linden/indra/llcommon/llassettype.h @@ -145,11 +145,13 @@ public: }; // machine transation between type and strings - static EType lookup(const char* name); + static EType lookup(const char* name); // safe conversion to std::string, *TODO: deprecate + static EType lookup(const std::string& name); static const char* lookup(EType type); // translation from a type to a human readable form. - static EType lookupHumanReadable( const char* name ); + static EType lookupHumanReadable( const char* name ); // safe conversion to std::string, *TODO: deprecate + static EType lookupHumanReadable( const std::string& name ); static const char* lookupHumanReadable(EType type); static EDragAndDropType lookupDragAndDropType( EType ); diff --git a/linden/indra/llcommon/llbase64.cpp b/linden/indra/llcommon/llbase64.cpp index 950ce6e..c2421d8 100644 --- a/linden/indra/llcommon/llbase64.cpp +++ b/linden/indra/llcommon/llbase64.cpp @@ -36,7 +36,7 @@ #include -#include "apr-1/apr_base64.h" +#include "apr_base64.h" // static diff --git a/linden/indra/llcommon/llchat.h b/linden/indra/llcommon/llchat.h index a46b8aa..ea1a579 100644 --- a/linden/indra/llcommon/llchat.h +++ b/linden/indra/llcommon/llchat.h @@ -68,7 +68,7 @@ typedef enum e_chat_audible_level class LLChat { public: - LLChat(const LLString& text = LLString::null) + LLChat(const std::string& text = LLStringUtil::null) : mText(text), mFromName(), mFromID(), @@ -80,8 +80,8 @@ public: mPosAgent() { } - LLString mText; // UTF-8 line of text - LLString mFromName; // agent or object name + std::string mText; // UTF-8 line of text + std::string mFromName; // agent or object name LLUUID mFromID; // agent id or object id EChatSourceType mSourceType; EChatType mChatType; diff --git a/linden/indra/llcommon/llcommon.vcproj b/linden/indra/llcommon/llcommon.vcproj deleted file mode 100644 index f54ea13..0000000 --- a/linden/indra/llcommon/llcommon.vcproj +++ /dev/null @@ -1,608 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/linden/indra/llcommon/llcommon_vc8.vcproj b/linden/indra/llcommon/llcommon_vc8.vcproj deleted file mode 100644 index a298499..0000000 --- a/linden/indra/llcommon/llcommon_vc8.vcproj +++ /dev/null @@ -1,847 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/linden/indra/llcommon/llcommon_vc9.vcproj b/linden/indra/llcommon/llcommon_vc9.vcproj deleted file mode 100644 index 1ae534d..0000000 --- a/linden/indra/llcommon/llcommon_vc9.vcproj +++ /dev/null @@ -1,828 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/linden/indra/llcommon/llcrc.cpp b/linden/indra/llcommon/llcrc.cpp new file mode 100644 index 0000000..beb76d1 --- /dev/null +++ b/linden/indra/llcommon/llcrc.cpp @@ -0,0 +1,224 @@ +/** + * @file llcrc.cpp + * @brief implementation of the crc class. + * + * $LicenseInfo:firstyear=2002&license=viewergpl$ + * + * Copyright (c) 2002-2008, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "linden_common.h" + +#include "llcrc.h" +#include "llerror.h" + +/* Copyright (C) 1986 Gary S. Brown. You may use this program, or + code or tables extracted from it, as desired without restriction.*/ + +/* First, the polynomial itself and its table of feedback terms. The */ +/* polynomial is */ +/* X^32+X^26+X^23+X^22+X^16+X^12+X^11+X^10+X^8+X^7+X^5+X^4+X^2+X^1+X^0 */ +/* Note that we take it "backwards" and put the highest-order term in */ +/* the lowest-order bit. The X^32 term is "implied"; the LSB is the */ +/* X^31 term, etc. The X^0 term (usually shown as "+1") results in */ +/* the MSB being 1. */ + +/* Note that the usual hardware shift register implementation, which */ +/* is what we're using (we're merely optimizing it by doing eight-bit */ +/* chunks at a time) shifts bits into the lowest-order term. In our */ +/* implementation, that means shifting towards the right. Why do we */ +/* do it this way? Because the calculated CRC must be transmitted in */ +/* order from highest-order term to lowest-order term. UARTs transmit */ +/* characters in order from LSB to MSB. By storing the CRC this way, */ +/* we hand it to the UART in the order low-byte to high-byte; the UART */ +/* sends each low-bit to hight-bit; and the result is transmission bit */ +/* by bit from highest- to lowest-order term without requiring any bit */ +/* shuffling on our part. Reception works similarly. */ + +/* The feedback terms table consists of 256, 32-bit entries. Notes: */ +/* */ +/* 1. The table can be generated at runtime if desired; code to do so */ +/* is shown later. It might not be obvious, but the feedback */ +/* terms simply represent the results of eight shift/xor opera- */ +/* tions for all combinations of data and CRC register values. */ +/* */ +/* 2. The CRC accumulation logic is the same for all CRC polynomials, */ +/* be they sixteen or thirty-two bits wide. You simply choose the */ +/* appropriate table. Alternatively, because the table can be */ +/* generated at runtime, you can start by generating the table for */ +/* the polynomial in question and use exactly the same "updcrc", */ +/* if your application needn't simultaneously handle two CRC */ +/* polynomials. (Note, however, that XMODEM is strange.) */ +/* */ +/* 3. For 16-bit CRCs, the table entries need be only 16 bits wide; */ +/* of course, 32-bit entries work OK if the high 16 bits are zero. */ +/* */ +/* 4. The values must be right-shifted by eight bits by the "updcrc" */ +/* logic; the shift must be unsigned (bring in zeroes). On some */ +/* hardware you could probably optimize the shift in assembler by */ +/* using byte-swap instructions. */ + +///---------------------------------------------------------------------------- +/// Local function declarations, constants, enums, and typedefs +///---------------------------------------------------------------------------- + +#define UPDC32(octet,crc) (crc_32_tab[((crc) \ + ^ ((U8)octet)) & 0xff] ^ ((crc) >> 8)) + + +static U32 crc_32_tab[] = { /* CRC polynomial 0xedb88320 */ +0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, +0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, +0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2, +0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, +0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, +0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, +0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c, +0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, +0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, +0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, +0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106, +0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, +0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, +0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, +0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, +0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, +0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, +0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, +0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, +0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, +0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, +0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, +0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84, +0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, +0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, +0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, +0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e, +0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, +0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, +0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, +0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28, +0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, +0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, +0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, +0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, +0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, +0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, +0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, +0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, +0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, +0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, +0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, +0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d +}; + + +///---------------------------------------------------------------------------- +/// Class llcrc +///---------------------------------------------------------------------------- + +// Default constructor +LLCRC::LLCRC() : mCurrent(0xffffffff) +{ +} + + +U32 LLCRC::getCRC() const +{ + return ~mCurrent; +} + +void LLCRC::update(U8 next_byte) +{ + mCurrent = UPDC32(next_byte, mCurrent); +} + +void LLCRC::update(const U8* buffer, size_t buffer_size) +{ + for (size_t i = 0; i < buffer_size; i++) + { + mCurrent = UPDC32(buffer[i], mCurrent); + } +} + +void LLCRC::update(const std::string& filename) +{ + if (filename.empty()) + { + llerrs << "No filename specified" << llendl; + return; + } + + FILE* fp = LLFile::fopen(filename, "rb"); /* Flawfinder: ignore */ + + if (fp) + { + fseek(fp, 0, SEEK_END); + long size = ftell(fp); + + fseek(fp, 0, SEEK_SET); + + if (size > 0) + { + U8* data = new U8[size]; + size_t nread; + + nread = fread(data, 1, size, fp); + fclose(fp); + + if (nread < (size_t) size) + { + llwarns << "Short read on " << filename << llendl; + } + + update(data, nread); + delete[] data; + } + } +} + + +#ifdef _DEBUG +BOOL LLCRC::testHarness() +{ + const S32 TEST_BUFFER_SIZE = 16; + const char TEST_BUFFER[TEST_BUFFER_SIZE] = "hello &#$)$&Nd0"; /* Flawfinder: ignore */ + LLCRC c1, c2; + c1.update((U8*)TEST_BUFFER, TEST_BUFFER_SIZE - 1); + char* rh = (char*)TEST_BUFFER; + while(*rh != '\0') + { + c2.update(*rh); + ++rh; + } + return(c1.getCRC() == c2.getCRC()); +} +#endif + + + +///---------------------------------------------------------------------------- +/// Local function definitions +///---------------------------------------------------------------------------- diff --git a/linden/indra/llcommon/llcrc.h b/linden/indra/llcommon/llcrc.h new file mode 100644 index 0000000..20f214e --- /dev/null +++ b/linden/indra/llcommon/llcrc.h @@ -0,0 +1,73 @@ +/** + * @file llcrc.h + * @brief LLCRC class header file. + * + * $LicenseInfo:firstyear=2002&license=viewergpl$ + * + * Copyright (c) 2002-2008, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LL_LLCRC_H +#define LL_LLCRC_H + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// Class llcrc +// +// Simple 32 bit crc. To use, instantiate an LLCRC instance and feed +// it the bytes you want to check. It will update the internal crc as +// you go, and you can qery it at the end. As a horribly inefficient +// example (don't try this at work kids): +// +// LLCRC crc; +// FILE* fp = LLFile::fopen(filename,"rb"); +// while(!feof(fp)) { +// crc.update(fgetc(fp)); +// } +// fclose(fp); +// llinfos << "File crc: " << crc.getCRC() << llendl; +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +class LLCRC +{ +protected: + U32 mCurrent; + +public: + LLCRC(); + + U32 getCRC() const; + void update(U8 next_byte); + void update(const U8* buffer, size_t buffer_size); + void update(const std::string& filename); + +#ifdef _DEBUG + // This function runs tests to make sure the crc is + // working. Returns TRUE if it is. + static BOOL testHarness(); +#endif +}; + + +#endif // LL_LLCRC_H diff --git a/linden/indra/llcommon/lldarray.h b/linden/indra/llcommon/lldarray.h index 45e564f..32ece4e 100644 --- a/linden/indra/llcommon/lldarray.h +++ b/linden/indra/llcommon/lldarray.h @@ -32,7 +32,6 @@ #ifndef LL_LLDARRAY_H #define LL_LLDARRAY_H -#include "llmath.h" #include "llerror.h" #include diff --git a/linden/indra/llcommon/lldate.cpp b/linden/indra/llcommon/lldate.cpp index 5d36d2b..a313246 100644 --- a/linden/indra/llcommon/lldate.cpp +++ b/linden/indra/llcommon/lldate.cpp @@ -34,7 +34,7 @@ #include "linden_common.h" #include "lldate.h" -#include "apr-1/apr_time.h" +#include "apr_time.h" #include #include diff --git a/linden/indra/llcommon/llerror.cpp b/linden/indra/llcommon/llerror.cpp index b74b288..5c7c3cd 100644 --- a/linden/indra/llcommon/llerror.cpp +++ b/linden/indra/llcommon/llerror.cpp @@ -102,7 +102,7 @@ namespace { public: RecordToFile(const std::string& filename) { - mFile.open(filename.c_str(), llofstream::out | llofstream::app); + mFile.open(filename, llofstream::out | llofstream::app); if (!mFile) { llinfos << "Error setting log file to " << filename << llendl; @@ -168,7 +168,7 @@ namespace { private: bool mTimestamp; - typedef enum ANSIState {ANSI_PROBE, ANSI_YES, ANSI_NO}; + enum ANSIState {ANSI_PROBE, ANSI_YES, ANSI_NO}; ANSIState mUseANSI; void colorANSI(const std::string color) { @@ -196,7 +196,7 @@ namespace { virtual void recordMessage(LLError::ELevel level, const std::string& message) { - mBuffer.addLine(message.c_str()); + mBuffer.addLine(message); } private: @@ -305,7 +305,7 @@ namespace std::string file = dirBase + "logcontrol-dev.xml"; llstat stat_info; - if (LLFile::stat(file.c_str(), &stat_info)) { + if (LLFile::stat(file, &stat_info)) { // NB: stat returns non-zero if it can't read the file, for example // if it doesn't exist. LLFile has no better abstraction for // testing for file existence. @@ -321,7 +321,7 @@ namespace LLSD configuration; { - llifstream file(filename().c_str()); + llifstream file(filename()); if (file.is_open()) { LLSDSerialize::fromXML(configuration, file); @@ -1040,17 +1040,37 @@ namespace LLError << "(" << site.mLine << ") : "; } - if (message.find(functionName(site.mFunction)) == std::string::npos) - { #if LL_WINDOWS - // DevStudio: __FUNCTION__ already includes the full class name + // DevStudio: __FUNCTION__ already includes the full class name #else - if (site.mClassInfo != typeid(NoClassInfo)) + if (site.mClassInfo != typeid(NoClassInfo)) + { + prefix << className(site.mClassInfo) << "::"; + } + #endif + prefix << site.mFunction << ": "; + + if (site.mPrintOnce) + { + std::map::iterator messageIter = s.uniqueLogMessages.find(message); + if (messageIter != s.uniqueLogMessages.end()) + { + messageIter->second++; + unsigned int num_messages = messageIter->second; + if (num_messages == 10 || num_messages == 50 || (num_messages % 100) == 0) + { + prefix << "ONCE (" << num_messages << "th time seen): "; + } + else + { + return; + } + } + else { - prefix << className(site.mClassInfo) << "::"; + prefix << "ONCE: "; + s.uniqueLogMessages[message] = 1; } - #endif - prefix << site.mFunction << ": "; } if (site.mPrintOnce) diff --git a/linden/indra/llcommon/llevent.cpp b/linden/indra/llcommon/llevent.cpp index 33af028..7d701a1 100644 --- a/linden/indra/llcommon/llevent.cpp +++ b/linden/indra/llcommon/llevent.cpp @@ -219,7 +219,7 @@ std::vector LLSimpleDispatcher::getListeners() const bool LLSimpleDispatcher::fireEvent(LLPointer event, LLSD filter) { std::vector::iterator itor; - LLString filter_string = filter.asString(); + std::string filter_string = filter.asString(); for (itor=mListeners.begin(); itor!=mListeners.end(); ++itor) { LLListenerEntry& entry = *itor; diff --git a/linden/indra/llcommon/llfile.cpp b/linden/indra/llcommon/llfile.cpp index fc0d481..b32437f 100644 --- a/linden/indra/llcommon/llfile.cpp +++ b/linden/indra/llcommon/llfile.cpp @@ -32,6 +32,10 @@ * $/LicenseInfo$ */ +#if LL_WINDOWS +#include +#endif + #include "linden_common.h" #include "llfile.h" #include "llstring.h" @@ -40,7 +44,7 @@ using namespace std; // static -int LLFile::mkdir(const char* dirname, int perms) +int LLFile::mkdir(const std::string& dirname, int perms) { #if LL_WINDOWS // permissions are ignored on Windows @@ -48,12 +52,12 @@ int LLFile::mkdir(const char* dirname, int perms) llutf16string utf16dirname = utf8str_to_utf16str(utf8dirname); return _wmkdir(utf16dirname.c_str()); #else - return ::mkdir(dirname, (mode_t)perms); + return ::mkdir(dirname.c_str(), (mode_t)perms); #endif } // static -int LLFile::rmdir(const char* dirname) +int LLFile::rmdir(const std::string& dirname) { #if LL_WINDOWS // permissions are ignored on Windows @@ -61,29 +65,29 @@ int LLFile::rmdir(const char* dirname) llutf16string utf16dirname = utf8str_to_utf16str(utf8dirname); return _wrmdir(utf16dirname.c_str()); #else - return ::rmdir(dirname); + return ::rmdir(dirname.c_str()); #endif } // static -LLFILE* LLFile::fopen(const char* filename, const char* mode) /* Flawfinder: ignore */ +LLFILE* LLFile::fopen(const std::string& filename, const char* mode) /* Flawfinder: ignore */ { #if LL_WINDOWS std::string utf8filename = filename; - std::string utf8mode = mode; + std::string utf8mode = std::string(mode); llutf16string utf16filename = utf8str_to_utf16str(utf8filename); llutf16string utf16mode = utf8str_to_utf16str(utf8mode); return _wfopen(utf16filename.c_str(),utf16mode.c_str()); #else - return ::fopen(filename,mode); /* Flawfinder: ignore */ + return ::fopen(filename.c_str(),mode); /* Flawfinder: ignore */ #endif } -LLFILE* LLFile::_fsopen(const char* filename, const char* mode, int sharingFlag) +LLFILE* LLFile::_fsopen(const std::string& filename, const char* mode, int sharingFlag) { #if LL_WINDOWS std::string utf8filename = filename; - std::string utf8mode = mode; + std::string utf8mode = std::string(mode); llutf16string utf16filename = utf8str_to_utf16str(utf8filename); llutf16string utf16mode = utf8str_to_utf16str(utf8mode); return _wfsopen(utf16filename.c_str(),utf16mode.c_str(),sharingFlag); @@ -93,18 +97,18 @@ LLFILE* LLFile::_fsopen(const char* filename, const char* mode, int sharingFlag) #endif } -int LLFile::remove(const char* filename) +int LLFile::remove(const std::string& filename) { #if LL_WINDOWS std::string utf8filename = filename; llutf16string utf16filename = utf8str_to_utf16str(utf8filename); return _wremove(utf16filename.c_str()); #else - return ::remove(filename); + return ::remove(filename.c_str()); #endif } -int LLFile::rename(const char* filename, const char* newname) +int LLFile::rename(const std::string& filename, const std::string& newname) { #if LL_WINDOWS std::string utf8filename = filename; @@ -113,19 +117,63 @@ int LLFile::rename(const char* filename, const char* newname) llutf16string utf16newname = utf8str_to_utf16str(utf8newname); return _wrename(utf16filename.c_str(),utf16newname.c_str()); #else - return ::rename(filename,newname); + return ::rename(filename.c_str(),newname.c_str()); #endif } -int LLFile::stat(const char* filename, llstat* filestatus) +int LLFile::stat(const std::string& filename, llstat* filestatus) { #if LL_WINDOWS std::string utf8filename = filename; llutf16string utf16filename = utf8str_to_utf16str(utf8filename); return _wstat(utf16filename.c_str(),filestatus); #else - return ::stat(filename,filestatus); + return ::stat(filename.c_str(),filestatus); +#endif +} + +bool LLFile::isdir(const std::string& filename) +{ + llstat st; + + return stat(filename, &st) == 0 && S_ISDIR(st.st_mode); +} + +bool LLFile::isfile(const std::string& filename) +{ + llstat st; + + return stat(filename, &st) == 0 && S_ISREG(st.st_mode); +} + +const char *LLFile::tmpdir() +{ + static std::string utf8path; + + if (utf8path.empty()) + { + char sep; +#if LL_WINDOWS + sep = '\\'; + + DWORD len = GetTempPathW(0, L""); + llutf16string utf16path; + utf16path.resize(len + 1); + len = GetTempPathW(static_cast(utf16path.size()), &utf16path[0]); + utf8path = utf16str_to_utf8str(utf16path); +#else + sep = '/'; + + char *env = getenv("TMPDIR"); + + utf8path = env ? env : "/tmp/"; #endif + if (utf8path[utf8path.size() - 1] != sep) + { + utf8path += sep; + } + } + return utf8path.c_str(); } @@ -133,7 +181,7 @@ int LLFile::stat(const char* filename, llstat* filestatus) #if USE_LLFILESTREAMS -LLFILE * LLFile::_Fiopen(const char *filename, std::ios::openmode mode,int) // protection currently unused +LLFILE * LLFile::_Fiopen(const std::string& filename, std::ios::openmode mode,int) // protection currently unused { // open a file static const char *mods[] = { // fopen mode strings corresponding to valid[i] @@ -202,7 +250,7 @@ void llifstream::close() } } -void llifstream::open(const char* _Filename, /* Flawfinder: ignore */ +void llifstream::open(const std::string& _Filename, /* Flawfinder: ignore */ ios_base::openmode _Mode, int _Prot) { // open a C stream with specified mode @@ -234,7 +282,7 @@ llifstream::~llifstream() delete _Filebuffer; } -llifstream::llifstream(const char *_Filename, +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) @@ -253,7 +301,7 @@ bool llofstream::is_open() const return false; } -void llofstream::open(const char* _Filename, /* Flawfinder: ignore */ +void llofstream::open(const std::string& _Filename, /* Flawfinder: ignore */ ios_base::openmode _Mode, int _Prot) { // open a C stream with specified mode @@ -279,7 +327,7 @@ void llofstream::close() } } -llofstream::llofstream(const char *_Filename, +llofstream::llofstream(const std::string& _Filename, std::ios_base::openmode _Mode, int _Prot) : std::basic_ostream >(NULL,true),_Filebuffer(NULL),_ShouldClose(false) diff --git a/linden/indra/llcommon/llfile.h b/linden/indra/llcommon/llfile.h index 189edbf..f3e3af5 100644 --- a/linden/indra/llcommon/llfile.h +++ b/linden/indra/llcommon/llfile.h @@ -50,31 +50,45 @@ typedef FILE LLFILE; #define USE_LLFILESTREAMS 0 #endif +#include #if LL_WINDOWS // windows version of stat function and stat data structure are called _stat typedef struct _stat llstat; #else -#include typedef struct stat llstat; #endif +#ifndef S_ISREG +# define S_ISREG(x) (((x) & S_IFMT) == S_IFREG) +#endif + +#ifndef S_ISDIR +# define S_ISDIR(x) (((x) & S_IFMT) == S_IFDIR) +#endif + +#include "llstring.h" // safe char* -> std::string conversion + class LLFile { public: // All these functions take UTF8 path/filenames. - static LLFILE* fopen(const char* filename,const char* accessmode); /* Flawfinder: ignore */ - static LLFILE* _fsopen(const char* filename,const char* accessmode,int sharingFlag); + static LLFILE* fopen(const std::string& filename,const char* accessmode); /* Flawfinder: ignore */ + static LLFILE* _fsopen(const std::string& filename,const char* accessmode,int sharingFlag); // perms is a permissions mask like 0777 or 0700. In most cases it will // be overridden by the user's umask. It is ignored on Windows. - static int mkdir(const char* filename, int perms = 0700); + static int mkdir(const std::string& filename, int perms = 0700); - static int rmdir(const char* filename); - static int remove(const char* filename); - static int rename(const char* filename,const char* newname); - static int stat(const char* filename,llstat* file_status); - static LLFILE * _Fiopen(const char *filename, std::ios::openmode mode,int); // protection currently unused + static int rmdir(const std::string& filename); + static int remove(const std::string& filename); + static int rename(const std::string& filename,const std::string& newname); + 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 const char * tmpdir(); }; @@ -93,7 +107,7 @@ public: { // construct unopened } - explicit llifstream(const char *_Filename, + explicit llifstream(const std::string& _Filename, ios_base::openmode _Mode = ios_base::in, int _Prot = (int)ios_base::_Openprot); @@ -110,7 +124,7 @@ public: return _Filebuffer; } bool is_open() const; - void open(const char* _Filename, /* Flawfinder: ignore */ + void open(const std::string& _Filename, /* Flawfinder: ignore */ ios_base::openmode _Mode = ios_base::in, int _Prot = (int)ios_base::_Openprot); void close(); @@ -133,7 +147,7 @@ public: { // construct unopened } - explicit llofstream(const char *_Filename, + explicit llofstream(const std::string& _Filename, std::ios_base::openmode _Mode = ios_base::out, int _Prot = (int)std::ios_base::_Openprot); @@ -154,7 +168,7 @@ public: bool is_open() const; - void open(const char *_Filename,ios_base::openmode _Mode = ios_base::out,int _Prot = (int)ios_base::_Openprot); /* Flawfinder: ignore */ + void open(const std::string& _Filename,ios_base::openmode _Mode = ios_base::out,int _Prot = (int)ios_base::_Openprot); /* Flawfinder: ignore */ void close(); @@ -167,8 +181,45 @@ private: #else //Use standard file streams on non windows platforms -#define llifstream std::ifstream -#define llofstream std::ofstream +//#define llifstream std::ifstream +//#define llofstream std::ofstream + +class 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); + } +}; + + +class llofstream : public std::ofstream +{ +public: + llofstream() : std::ofstream() + { + } + + explicit llofstream(const std::string& _Filename, std::_Ios_Openmode _Mode = out) + : std::ofstream(_Filename.c_str(), _Mode) + { + } + + void open(const std::string& _Filename, std::_Ios_Openmode _Mode = out) /* Flawfinder: ignore */ + { + std::ofstream::open(_Filename.c_str(), _Mode); + } + +}; #endif diff --git a/linden/indra/llcommon/llfixedbuffer.cpp b/linden/indra/llcommon/llfixedbuffer.cpp index 776de0d..a3ebae1 100644 --- a/linden/indra/llcommon/llfixedbuffer.cpp +++ b/linden/indra/llcommon/llfixedbuffer.cpp @@ -54,7 +54,7 @@ void LLFixedBuffer::clear() } -void LLFixedBuffer::addLine(const LLString& utf8line) +void LLFixedBuffer::addLine(const std::string& utf8line) { LLWString wstring = utf8str_to_wstring(utf8line); LLFixedBuffer::addLine(wstring); diff --git a/linden/indra/llcommon/llfixedbuffer.h b/linden/indra/llcommon/llfixedbuffer.h index 06a7f45..1641bee 100644 --- a/linden/indra/llcommon/llfixedbuffer.h +++ b/linden/indra/llcommon/llfixedbuffer.h @@ -52,7 +52,7 @@ public: std::deque mLineLengths; void clear(); // Clear the buffer, and reset it. - virtual void addLine(const LLString& utf8line); + virtual void addLine(const std::string& utf8line); virtual void addLine(const LLWString& line); // Get lines currently in the buffer, up to max_size chars, max_length lines diff --git a/linden/indra/llcommon/llframetimer.cpp b/linden/indra/llcommon/llframetimer.cpp index 96e5014..e4e8a18 100644 --- a/linden/indra/llcommon/llframetimer.cpp +++ b/linden/indra/llcommon/llframetimer.cpp @@ -53,7 +53,6 @@ void LLFrameTimer::updateFrameTime() sTotalTime = total_time; sTotalSeconds = U64_to_F64(sTotalTime) * USEC_TO_SEC_F64; sFrameTime = U64_to_F64(sTotalTime - sStartTotalTime) * USEC_TO_SEC_F64; - sFrameCount++; } void LLFrameTimer::start() diff --git a/linden/indra/llcommon/llframetimer.h b/linden/indra/llcommon/llframetimer.h index 11c4cfc..d13018f 100644 --- a/linden/indra/llcommon/llframetimer.h +++ b/linden/indra/llcommon/llframetimer.h @@ -67,10 +67,14 @@ public: return sTotalSeconds; } - // Call this method once per frame to update the current frame time. + // Call this method once per frame to update the current frame time. This is actually called + // at some other times as well static void updateFrameTime(); - static S32 getFrameCount() { return sFrameCount; } + // Call this method once, and only once, per frame to update the current frame count. + static void updateFrameCount() { sFrameCount++; } + + static U32 getFrameCount() { return sFrameCount; } static F32 getFrameDeltaTimeF32(); diff --git a/linden/indra/llcommon/llhash.h b/linden/indra/llcommon/llhash.h index 716d9df..e259a11 100644 --- a/linden/indra/llcommon/llhash.h +++ b/linden/indra/llcommon/llhash.h @@ -38,7 +38,9 @@ #include #include #elif LL_DARWIN || LL_LINUX -# if GCC_VERSION >= 30400 // gcc 3.4 and up +# if GCC_VERSION >= 40300 // gcc 4.3 and up +# include +# elif GCC_VERSION >= 30400 // gcc 3.4 and up # include # elif __GNUC__ >= 3 # include diff --git a/linden/indra/llcommon/llheartbeat.cpp b/linden/indra/llcommon/llheartbeat.cpp index 13bcd46..b67d3f2 100644 --- a/linden/indra/llcommon/llheartbeat.cpp +++ b/linden/indra/llcommon/llheartbeat.cpp @@ -72,8 +72,13 @@ LLHeartbeat::rawSend() if (mSuppressed) return 0; // Pretend we succeeded. + int result; +#ifndef LL_DARWIN union sigval dummy; - int result = sigqueue(getppid(), LL_HEARTBEAT_SIGNAL, dummy); + result = sigqueue(getppid(), LL_HEARTBEAT_SIGNAL, dummy); +#else + result = kill(getppid(), LL_HEARTBEAT_SIGNAL); +#endif if (result == 0) return 0; // success diff --git a/linden/indra/llcommon/llindraconfigfile.cpp b/linden/indra/llcommon/llindraconfigfile.cpp index 7ef1a9b..60b498d 100644 --- a/linden/indra/llcommon/llindraconfigfile.cpp +++ b/linden/indra/llcommon/llindraconfigfile.cpp @@ -81,7 +81,7 @@ void LLIndraConfigFile::loadFile() LLSD config; { - llifstream file(filename().c_str()); + llifstream file(filename()); if (file.is_open()) { LLSDSerialize::fromXML(config, file); diff --git a/linden/indra/llcommon/llkeythrottle.h b/linden/indra/llcommon/llkeythrottle.h index 8314269..eb1519a 100644 --- a/linden/indra/llcommon/llkeythrottle.h +++ b/linden/indra/llcommon/llkeythrottle.h @@ -55,33 +55,40 @@ class LLKeyThrottleImpl protected: struct Entry { U32 count; - BOOL blocked; + bool blocked; - Entry() : count(0), blocked(FALSE) { } + Entry() : count(0), blocked(false) { } }; typedef std::map EntryMap; - EntryMap * prevMap; - EntryMap * currMap; + EntryMap* prevMap; + EntryMap* currMap; U32 countLimit; // maximum number of keys allowed per interval - U64 interval_usec; - // each map covers this time period - U64 start_usec; + U64 intervalLength; // each map covers this time period (usec or frame number) + U64 startTime; // start of the time period (usec or frame number) // currMap started counting at this time // prevMap covers the previous interval - LLKeyThrottleImpl() : prevMap(0), currMap(0), - countLimit(0), interval_usec(0), - start_usec(0) { }; + LLKeyThrottleImpl() : + prevMap(NULL), + currMap(NULL), + countLimit(0), + intervalLength(1), + startTime(0) + {} static U64 getTime() { return LLFrameTimer::getTotalTime(); } + static U64 getFrame() // Return the current frame number + { + return (U64) LLFrameTimer::getFrameCount(); + } }; @@ -89,17 +96,12 @@ template< class T > class LLKeyThrottle { public: - LLKeyThrottle(U32 limit, F32 interval) + // @param realtime = FALSE for frame-based throttle, TRUE for usec + // real-time throttle + LLKeyThrottle(U32 limit, F32 interval, BOOL realtime = TRUE) : m(* new LLKeyThrottleImpl) { - // limit is the maximum number of keys - // allowed per interval (in seconds) - m.countLimit = limit; - m.interval_usec = (U64)(interval * USEC_PER_SEC); - m.start_usec = LLKeyThrottleImpl::getTime(); - - m.prevMap = new typename LLKeyThrottleImpl::EntryMap; - m.currMap = new typename LLKeyThrottleImpl::EntryMap; + setParameters( limit, interval, realtime ); } ~LLKeyThrottle() @@ -118,18 +120,26 @@ public: // call each time the key wants use State noteAction(const T& id, S32 weight = 1) { - U64 now = LLKeyThrottleImpl::getTime(); + U64 now = 0; + if ( mIsRealtime ) + { + now = LLKeyThrottleImpl::getTime(); + } + else + { + now = LLKeyThrottleImpl::getFrame(); + } - if (now >= (m.start_usec + m.interval_usec)) + if (now >= (m.startTime + m.intervalLength)) { - if (now < (m.start_usec + 2 * m.interval_usec)) + if (now < (m.startTime + 2 * m.intervalLength)) { // prune old data delete m.prevMap; m.prevMap = m.currMap; m.currMap = new typename LLKeyThrottleImpl::EntryMap; - m.start_usec += m.interval_usec; + m.startTime += m.intervalLength; } else { @@ -139,12 +149,12 @@ public: m.prevMap = new typename LLKeyThrottleImpl::EntryMap; m.currMap = new typename LLKeyThrottleImpl::EntryMap; - m.start_usec = now; + m.startTime = now; } } U32 prevCount = 0; - BOOL prevBlocked = FALSE; + bool prevBlocked = false; typename LLKeyThrottleImpl::EntryMap::const_iterator prev = m.prevMap->find(id); if (prev != m.prevMap->end()) @@ -166,7 +176,7 @@ public: // (now) time. // compute current, windowed rate - F64 timeInCurrent = ((F64)(now - m.start_usec) / m.interval_usec); + F64 timeInCurrent = ((F64)(now - m.startTime) / m.intervalLength); F64 averageCount = curr.count + prevCount * (1.0 - timeInCurrent); curr.blocked |= averageCount > m.countLimit; @@ -193,17 +203,17 @@ public: noteAction(id); typename LLKeyThrottleImpl::Entry& curr = (*m.currMap)[id]; curr.count = llmax(m.countLimit, curr.count); - curr.blocked = TRUE; + curr.blocked = true; } - // returns TRUE if key is blocked - BOOL isThrottled(const T& id) const + // returns true if key is blocked + bool isThrottled(const T& id) const { if (m.currMap->empty() && m.prevMap->empty()) { // most of the time we'll fall in here - return FALSE; + return false; } // NOTE, we ignore the case where id is in the map but the map is stale. @@ -221,11 +231,49 @@ public: { return entry->second.blocked; } - return FALSE; + return false; + } + + // Get the throttling parameters + void getParameters( U32 & out_limit, F32 & out_interval, BOOL & out_realtime ) + { + out_limit = m.countLimit; + out_interval = m.intervalLength; + out_realtime = mIsRealtime; + } + + // Set the throttling behavior + void setParameters( U32 limit, F32 interval, BOOL realtime ) + { + // limit is the maximum number of keys + // allowed per interval (in seconds or frames) + mIsRealtime = realtime; + m.countLimit = limit; + if ( mIsRealtime ) + { + m.intervalLength = (U64)(interval * USEC_PER_SEC); + m.startTime = LLKeyThrottleImpl::getTime(); + } + else + { + m.intervalLength = (U64)interval; + m.startTime = LLKeyThrottleImpl::getFrame(); + } + + if ( m.intervalLength == 0 ) + { // Don't allow zero intervals + m.intervalLength = 1; + } + + delete m.prevMap; + m.prevMap = new typename LLKeyThrottleImpl::EntryMap; + delete m.currMap; + m.currMap = new typename LLKeyThrottleImpl::EntryMap; } protected: LLKeyThrottleImpl& m; + BOOL mIsRealtime; // TRUE to be time based (default), FALSE for frame based }; #endif diff --git a/linden/indra/llcommon/llliveappconfig.cpp b/linden/indra/llcommon/llliveappconfig.cpp index ad11987..a11f5b0 100644 --- a/linden/indra/llcommon/llliveappconfig.cpp +++ b/linden/indra/llcommon/llliveappconfig.cpp @@ -51,7 +51,7 @@ void LLLiveAppConfig::loadFile() { llinfos << "LLLiveAppConfig::loadFile(): reading from " << filename() << llendl; - llifstream file(filename().c_str()); + llifstream file(filename()); LLSD config; if (file.is_open()) { diff --git a/linden/indra/llcommon/lllivefile.cpp b/linden/indra/llcommon/lllivefile.cpp index 6e027ef..8ac6bb4 100644 --- a/linden/indra/llcommon/lllivefile.cpp +++ b/linden/indra/llcommon/lllivefile.cpp @@ -93,7 +93,7 @@ bool LLLiveFile::Impl::check() // Stat the file to see if it exists and when it was last modified. llstat stat_data; - int res = LLFile::stat(mFilename.c_str(), &stat_data); + int res = LLFile::stat(mFilename, &stat_data); if (res) { diff --git a/linden/indra/llcommon/lllslconstants.h b/linden/indra/llcommon/lllslconstants.h index 508fb42..24120a2 100644 --- a/linden/indra/llcommon/lllslconstants.h +++ b/linden/indra/llcommon/lllslconstants.h @@ -126,6 +126,9 @@ const S32 LSL_PRIM_SCULPT_TYPE_SPHERE = 1; const S32 LSL_PRIM_SCULPT_TYPE_TORUS = 2; const S32 LSL_PRIM_SCULPT_TYPE_PLANE = 3; const S32 LSL_PRIM_SCULPT_TYPE_CYLINDER = 4; +const S32 LSL_PRIM_SCULPT_TYPE_MASK = 7; +const S32 LSL_PRIM_SCULPT_FLAG_INVERT = 64; +const S32 LSL_PRIM_SCULPT_FLAG_MIRROR = 128; const S32 LSL_ALL_SIDES = -1; const S32 LSL_LINK_ROOT = 1; @@ -181,4 +184,7 @@ const S32 OBJECT_OWNER = 6; const S32 OBJECT_GROUP = 7; const S32 OBJECT_CREATOR = 8; +// llTextBox() magic token string - yes this is a hack. sue me. +const std::string TEXTBOX_MAGIC_TOKEN = "!!llTextBox!!"; + #endif diff --git a/linden/indra/llcommon/llmd5.cpp b/linden/indra/llcommon/llmd5.cpp new file mode 100644 index 0000000..a0ac92f --- /dev/null +++ b/linden/indra/llcommon/llmd5.cpp @@ -0,0 +1,531 @@ +/** + * @file llmd5.cpp + * + * $LicenseInfo:firstyear=2001&license=viewergpl$ + * + * Copyright (c) 2001-2008, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +// llMD5.CC - source code for the C++/object oriented translation and +// modification of MD5. +// +// Adapted to Linden Lab by Frank Filipanits, 6/25/2002 +// Fixed potential memory leak, James Cook, 6/27/2002 + +// Translation and modification (c) 1995 by Mordechai T. Abzug + +// This translation/ modification is provided "as is," without express or +// implied warranty of any kind. + +// The translator/ modifier does not claim (1) that MD5 will do what you think +// it does; (2) that this translation/ modification is accurate; or (3) that +// this software is "merchantible." (Language for this disclaimer partially +// copied from the disclaimer below). + +/* based on: + + MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm + MDDRIVER.C - test driver for MD2, MD4 and MD5 + + + Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All +rights reserved. + +License to copy and use this software is granted provided that it +is identified as the "RSA Data Security, Inc. MD5 Message-Digest +Algorithm" in all material mentioning or referencing this software +or this function. + +License is also granted to make and use derivative works provided +that such works are identified as "derived from the RSA Data +Security, Inc. MD5 Message-Digest Algorithm" in all material +mentioning or referencing the derived work. + +RSA Data Security, Inc. makes no representations concerning either +the merchantability of this software or the suitability of this +software for any particular purpose. It is provided "as is" +without express or implied warranty of any kind. + +These notices must be retained in any copies of any part of this +documentation and/or software. + + */ + + + + + +#include "linden_common.h" + +#include "llmd5.h" + +#include + +// how many bytes to grab at a time when checking files +const int LLMD5::BLOCK_LEN = 4096; + + +// LLMD5 simple initialization method + +LLMD5::LLMD5() +{ + init(); +} + + + + +// MD5 block update operation. Continues an MD5 message-digest +// operation, processing another message block, and updating the +// context. + +void LLMD5::update (const uint1 *input, const uint4 input_length) { + + uint4 input_index, buffer_index; + uint4 buffer_space; // how much space is left in buffer + + if (finalized){ // so we can't update! + std::cerr << "LLMD5::update: Can't update a finalized digest!" << std::endl; + return; + } + + // Compute number of bytes mod 64 + buffer_index = (unsigned int)((count[0] >> 3) & 0x3F); + + // Update number of bits + if ( (count[0] += ((uint4) input_length << 3))<((uint4) input_length << 3) ) + count[1]++; + + count[1] += ((uint4)input_length >> 29); + + + buffer_space = 64 - buffer_index; // how much space is left in buffer + + // Transform as many times as possible. + if (input_length >= buffer_space) { // ie. we have enough to fill the buffer + // fill the rest of the buffer and transform + memcpy( /* Flawfinder: ignore */ + buffer + buffer_index, + input, + buffer_space); + transform (buffer); + + // now, transform each 64-byte piece of the input, bypassing the buffer + if (input == NULL || input_length == 0){ + std::cerr << "LLMD5::update: Invalid input!" << std::endl; + return; + } + + for (input_index = buffer_space; input_index + 63 < input_length; + input_index += 64) + transform (input+input_index); + + buffer_index = 0; // so we can buffer remaining + } + else + input_index=0; // so we can buffer the whole input + + + // and here we do the buffering: + memcpy(buffer+buffer_index, input+input_index, input_length-input_index); /* Flawfinder: ignore */ +} + + + +// MD5 update for files. +// Like above, except that it works on files (and uses above as a primitive.) + +void LLMD5::update(FILE* file){ + + unsigned char buffer[BLOCK_LEN]; /* Flawfinder: ignore */ + int len; + + while ( (len=(int)fread(buffer, 1, BLOCK_LEN, file)) ) + update(buffer, len); + + fclose (file); + +} + + + + + + +// MD5 update for istreams. +// Like update for files; see above. + +void LLMD5::update(std::istream& stream){ + + unsigned char buffer[BLOCK_LEN]; /* Flawfinder: ignore */ + int len; + + while (stream.good()){ + stream.read( (char*)buffer, BLOCK_LEN); /* Flawfinder: ignore */ // note that return value of read is unusable. + len=stream.gcount(); + update(buffer, len); + } + +} + + + + + +// MD5 finalization. Ends an MD5 message-digest operation, writing the +// the message digest and zeroizing the context. + + +void LLMD5::finalize (){ + + unsigned char bits[8]; /* Flawfinder: ignore */ + unsigned int index, padLen; + static uint1 PADDING[64]={ + 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }; + + if (finalized){ + std::cerr << "LLMD5::finalize: Already finalized this digest!" << std::endl; + return; + } + + // Save number of bits + encode (bits, count, 8); + + // Pad out to 56 mod 64. + index = (uint4) ((count[0] >> 3) & 0x3f); + padLen = (index < 56) ? (56 - index) : (120 - index); + update (PADDING, padLen); + + // Append length (before padding) + update (bits, 8); + + // Store state in digest + encode (digest, state, 16); + + // Zeroize sensitive information + memset (buffer, 0, sizeof(*buffer)); + + finalized=1; + +} + + + + +LLMD5::LLMD5(FILE *file){ + + init(); // must be called be all constructors + update(file); + finalize (); +} + + + + +LLMD5::LLMD5(std::istream& stream){ + + init(); // must called by all constructors + update (stream); + finalize(); +} + +// Digest a string of the format ("%s:%i" % (s, number)) +LLMD5::LLMD5(const unsigned char *string, const unsigned int number) +{ + const char *colon = ":"; + char tbuf[16]; /* Flawfinder: ignore */ + init(); + update(string, (U32)strlen((const char *) string)); /* Flawfinder: ignore */ + update((const unsigned char *) colon, (U32)strlen(colon)); /* Flawfinder: ignore */ + snprintf(tbuf, sizeof(tbuf), "%i", number); /* Flawfinder: ignore */ + update((const unsigned char *) tbuf, (U32)strlen(tbuf)); /* Flawfinder: ignore */ + finalize(); +} + +// Digest a string +LLMD5::LLMD5(const unsigned char *s) +{ + init(); + update(s, (U32)strlen((const char *) s)); /* Flawfinder: ignore */ + finalize(); +} + +void LLMD5::raw_digest(unsigned char *s) +{ + if (!finalized) + { + std::cerr << "LLMD5::raw_digest: Can't get digest if you haven't "<< + "finalized the digest!" << std::endl; + s[0] = '\0'; + return; + } + + memcpy(s, digest, 16); /* Flawfinder: ignore */ + return; +} + + + +void LLMD5::hex_digest(char *s) +{ + int i; + + if (!finalized) + { + std::cerr << "LLMD5::hex_digest: Can't get digest if you haven't "<< + "finalized the digest!" <> (32-(n)))) + +/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4. +Rotation is separate from addition to prevent recomputation. + */ +#define FF(a, b, c, d, x, s, ac) { \ + (a) += F ((b), (c), (d)) + (x) + (U32)(ac); \ + (a) = ROTATE_LEFT ((a), (s)); \ + (a) += (b); \ + } +#define GG(a, b, c, d, x, s, ac) { \ + (a) += G ((b), (c), (d)) + (x) + (U32)(ac); \ + (a) = ROTATE_LEFT ((a), (s)); \ + (a) += (b); \ + } +#define HH(a, b, c, d, x, s, ac) { \ + (a) += H ((b), (c), (d)) + (x) + (U32)(ac); \ + (a) = ROTATE_LEFT ((a), (s)); \ + (a) += (b); \ + } +#define II(a, b, c, d, x, s, ac) { \ + (a) += I ((b), (c), (d)) + (x) + (U32)(ac); \ + (a) = ROTATE_LEFT ((a), (s)); \ + (a) += (b); \ + } + + + +// LLMD5 basic transformation. Transforms state based on block. +void LLMD5::transform (const U8 block[64]){ + + uint4 a = state[0], b = state[1], c = state[2], d = state[3], x[16]; + + decode (x, block, 64); + + assert(!finalized); // not just a user error, since the method is private + + /* Round 1 */ + FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */ + FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */ + FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */ + FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */ + FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */ + FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */ + FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */ + FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */ + FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */ + FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */ + FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */ + FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */ + FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */ + FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */ + FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */ + FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */ + + /* Round 2 */ + GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */ + GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */ + GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */ + GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */ + GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */ + GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */ + GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */ + GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */ + GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */ + GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */ + GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */ + GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */ + GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */ + GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */ + GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */ + GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */ + + /* Round 3 */ + HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */ + HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */ + HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */ + HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */ + HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */ + HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */ + HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */ + HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */ + HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */ + HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */ + HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */ + HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */ + HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */ + HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */ + HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */ + HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */ + + /* Round 4 */ + II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */ + II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */ + II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */ + II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */ + II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */ + II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */ + II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */ + II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */ + II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */ + II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */ + II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */ + II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */ + II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */ + II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */ + II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */ + II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */ + + state[0] += a; + state[1] += b; + state[2] += c; + state[3] += d; + + // Zeroize sensitive information. + memset ( (uint1 *) x, 0, sizeof(x)); + +} + + + +// Encodes input (UINT4) into output (unsigned char). Assumes len is +// a multiple of 4. +void LLMD5::encode (uint1 *output, const uint4 *input, const uint4 len) { + + unsigned int i, j; + + for (i = 0, j = 0; j < len; i++, j += 4) { + output[j] = (uint1) (input[i] & 0xff); + output[j+1] = (uint1) ((input[i] >> 8) & 0xff); + output[j+2] = (uint1) ((input[i] >> 16) & 0xff); + output[j+3] = (uint1) ((input[i] >> 24) & 0xff); + } +} + + + + +// Decodes input (unsigned char) into output (UINT4). Assumes len is +// a multiple of 4. +void LLMD5::decode (uint4 *output, const uint1 *input, const uint4 len){ + + unsigned int i, j; + + for (i = 0, j = 0; j < len; i++, j += 4) + output[i] = ((uint4)input[j]) | (((uint4)input[j+1]) << 8) | + (((uint4)input[j+2]) << 16) | (((uint4)input[j+3]) << 24); +} diff --git a/linden/indra/llcommon/llmd5.h b/linden/indra/llcommon/llmd5.h new file mode 100644 index 0000000..6d21b31 --- /dev/null +++ b/linden/indra/llcommon/llmd5.h @@ -0,0 +1,133 @@ +/** + * @file llmd5.h + * + * $LicenseInfo:firstyear=2001&license=viewergpl$ + * + * Copyright (c) 2001-2008, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LL_LLMD5_H +#define LL_LLMD5_H + +// LLMD5.CC - source code for the C++/object oriented translation and +// modification of MD5. + +// Translation and modification (c) 1995 by Mordechai T. Abzug + +// This translation/ modification is provided "as is," without express or +// implied warranty of any kind. + +// The translator/ modifier does not claim (1) that MD5 will do what you think +// it does; (2) that this translation/ modification is accurate; or (3) that +// this software is "merchantible." (Language for this disclaimer partially +// copied from the disclaimer below). + +/* based on: + + MD5.H - header file for MD5C.C + MDDRIVER.C - test driver for MD2, MD4 and MD5 + + Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All +rights reserved. + +License to copy and use this software is granted provided that it +is identified as the "RSA Data Security, Inc. MD5 Message-Digest +Algorithm" in all material mentioning or referencing this software +or this function. + +License is also granted to make and use derivative works provided +that such works are identified as "derived from the RSA Data +Security, Inc. MD5 Message-Digest Algorithm" in all material +mentioning or referencing the derived work. + +RSA Data Security, Inc. makes no representations concerning either +the merchantability of this software or the suitability of this +software for any particular purpose. It is provided "as is" +without express or implied warranty of any kind. + +These notices must be retained in any copies of any part of this +documentation and/or software. + +*/ + +// use for the raw digest output +const int MD5RAW_BYTES = 16; + +// use for outputting hex digests +const int MD5HEX_STR_SIZE = 33; // char hex[MD5HEX_STR_SIZE]; with null +const int MD5HEX_STR_BYTES = 32; // message system fixed size + +class LLMD5 { +// first, some types: + typedef unsigned int uint4; // assumes integer is 4 words long + typedef unsigned short int uint2; // assumes short integer is 2 words long + typedef unsigned char uint1; // assumes char is 1 word long + +// how many bytes to grab at a time when checking files + static const int BLOCK_LEN; + +public: +// methods for controlled operation: + LLMD5 (); // simple initializer + void update (const uint1 *input, const uint4 input_length); + void update (std::istream& stream); + void update (FILE *file); + void finalize (); + +// constructors for special circumstances. All these constructors finalize +// the MD5 context. + LLMD5 (const unsigned char *string); // digest string, finalize + LLMD5 (std::istream& stream); // digest stream, finalize + LLMD5 (FILE *file); // digest file, close, finalize + LLMD5 (const unsigned char *string, const unsigned int number); + +// methods to acquire finalized result + void raw_digest(unsigned char *array); // provide 16-byte array for binary data + void hex_digest(char *string); // provide 33-byte array for ascii-hex string + friend std::ostream& operator<< (std::ostream&, LLMD5 context); + + + +private: + + +// next, the private data: + uint4 state[4]; + uint4 count[2]; // number of *bits*, mod 2^64 + uint1 buffer[64]; // input buffer + uint1 digest[16]; + uint1 finalized; + +// last, the private methods, mostly static: + void init (); // called by all constructors + void transform (const uint1 *buffer); // does the real update work. Note + // that length is implied to be 64. + + static void encode (uint1 *dest, const uint4 *src, const uint4 length); + static void decode (uint4 *dest, const uint1 *src, const uint4 length); + +}; + +#endif // LL_LLMD5_H diff --git a/linden/indra/llcommon/llmemory.cpp b/linden/indra/llcommon/llmemory.cpp index 9b6f893..3fec50f 100644 --- a/linden/indra/llcommon/llmemory.cpp +++ b/linden/indra/llcommon/llmemory.cpp @@ -335,7 +335,6 @@ U64 getCurrentRSS() U64 getCurrentRSS() { U64 residentSize = 0; - task_basic_info_data_t basicInfo; mach_msg_type_number_t basicInfoCount = TASK_BASIC_INFO_COUNT; if (task_info(mach_task_self(), TASK_BASIC_INFO, (task_info_t)&basicInfo, &basicInfoCount) == KERN_SUCCESS) diff --git a/linden/indra/llcommon/llmemtype.h b/linden/indra/llcommon/llmemtype.h index 4a4702b..bd80930 100644 --- a/linden/indra/llcommon/llmemtype.h +++ b/linden/indra/llcommon/llmemtype.h @@ -80,6 +80,7 @@ public: MTYPE_SPACE_PARTITION, MTYPE_PIPELINE, MTYPE_AVATAR, + MTYPE_AVATAR_MESH, MTYPE_PARTICLES, MTYPE_REGIONS, MTYPE_INVENTORY, diff --git a/linden/indra/llcommon/llpreprocessor.h b/linden/indra/llcommon/llpreprocessor.h index e99b103..4809a2f 100644 --- a/linden/indra/llcommon/llpreprocessor.h +++ b/linden/indra/llcommon/llpreprocessor.h @@ -64,6 +64,9 @@ #ifndef LL_MSVC #define LL_MSVC 1 #endif + #if _MSC_VER < 1400 + #define LL_MSVC7 //Visual C++ 2003 or earlier + #endif #endif // Deal with minor differences on Unixy OSes. @@ -104,9 +107,7 @@ using snprintf_hack::snprintf; #if defined(LL_WINDOWS) #define BOOST_REGEX_NO_LIB 1 #define CURL_STATICLIB 1 - -//#define LL_LCD_COMPILE 0 - +#define XML_STATIC #endif // LL_WINDOWS diff --git a/linden/indra/llcommon/llprocessor.cpp b/linden/indra/llcommon/llprocessor.cpp index 1c0f7e0..f132b86 100644 --- a/linden/indra/llcommon/llprocessor.cpp +++ b/linden/indra/llcommon/llprocessor.cpp @@ -2216,12 +2216,12 @@ bool CProcessor::CPUInfoToText(char *strBuffer, unsigned int uiMaxLen) return true; } -// bool CProcessor::WriteInfoTextFile(const char *strFilename) +// bool CProcessor::WriteInfoTextFile(const std::string& strFilename) // =========================================================== // Takes use of CProcessor::CPUInfoToText and saves the string to a // file /////////////////////////////////////////////////////////////////// -bool CProcessor::WriteInfoTextFile(const char *strFilename) +bool CProcessor::WriteInfoTextFile(const std::string& strFilename) { char buf[16384]; /* Flawfinder: ignore */ diff --git a/linden/indra/llcommon/llprocessor.h b/linden/indra/llcommon/llprocessor.h index a188b1a..6abbd96 100644 --- a/linden/indra/llcommon/llprocessor.h +++ b/linden/indra/llcommon/llprocessor.h @@ -188,7 +188,7 @@ public: F64 GetCPUFrequency(unsigned int uiMeasureMSecs); const ProcessorInfo *GetCPUInfo(); bool CPUInfoToText(char *strBuffer, unsigned int uiMaxLen); - bool WriteInfoTextFile(const char *strFilename); + bool WriteInfoTextFile(const std::string& strFilename); }; diff --git a/linden/indra/llcommon/llptrskiplist.h b/linden/indra/llcommon/llptrskiplist.h index f1df27a..ebd297d 100644 --- a/linden/indra/llcommon/llptrskiplist.h +++ b/linden/indra/llcommon/llptrskiplist.h @@ -33,6 +33,7 @@ #define LL_LLPTRSKIPLIST_H #include "llerror.h" +#include "llrand.h" //#include "vmath.h" #include "llrand.h" diff --git a/linden/indra/llcommon/llrand.cpp b/linden/indra/llcommon/llrand.cpp new file mode 100644 index 0000000..bc8c867 --- /dev/null +++ b/linden/indra/llcommon/llrand.cpp @@ -0,0 +1,176 @@ +/** + * @file llrand.cpp + * @brief Global random generator. + * + * $LicenseInfo:firstyear=2000&license=viewergpl$ + * + * Copyright (c) 2000-2008, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "linden_common.h" + +#include "llrand.h" +#include "lluuid.h" + +/** + * Through analysis, we have decided that we want to take values which + * are close enough to 1.0 to map back to 0.0. We came to this + * conclusion from noting that: + * + * [0.0, 1.0) + * + * when scaled to the integer set: + * + * [0, 4) + * + * there is some value close enough to 1.0 that when multiplying by 4, + * gets truncated to 4. Therefore: + * + * [0,1-eps] => 0 + * [1,2-eps] => 1 + * [2,3-eps] => 2 + * [3,4-eps] => 3 + * + * So 0 gets uneven distribution if we simply clamp. The actual + * clamp utilized in this file is to map values out of range back + * to 0 to restore uniform distribution. + * + * Also, for clamping floats when asking for a distribution from + * [0.0,g) we have determined that for values of g < 0.5, then + * rand*g=g, which is not the desired result. As above, we clamp to 0 + * to restore uniform distribution. + */ + +// *NOTE: The system rand implementation is probably not correct. +#define LL_USE_SYSTEM_RAND 0 + +#if LL_USE_SYSTEM_RAND +#include +#endif + +#if LL_USE_SYSTEM_RAND +class LLSeedRand +{ +public: + LLSeedRand() + { +#if LL_WINDOWS + srand(LLUUID::getRandomSeed()); +#else + srand48(LLUUID::getRandomSeed()); +#endif + } +}; +static LLSeedRand sRandomSeeder; +inline F64 ll_internal_random_double() +{ +#if LL_WINDOWS + return (F64)rand() / (F64)RAND_MAX; +#else + return drand48(); +#endif +} +inline F32 ll_internal_random_float() +{ +#if LL_WINDOWS + return (F32)rand() / (F32)RAND_MAX; +#else + return (F32)drand48(); +#endif +} +#else +static LLRandLagFib2281 gRandomGenerator(LLUUID::getRandomSeed()); +inline F64 ll_internal_random_double() +{ + // *HACK: Through experimentation, we have found that dual core + // CPUs (or at least multi-threaded processes) seem to + // occasionally give an obviously incorrect random number -- like + // 5^15 or something. Sooooo, clamp it as described above. + F64 rv = gRandomGenerator(); + if(!((rv >= 0.0) && (rv < 1.0))) return fmod(rv, 1.0); + return rv; +} + +inline F32 ll_internal_random_float() +{ + // The clamping rules are described above. + F32 rv = (F32)gRandomGenerator(); + if(!((rv >= 0.0f) && (rv < 1.0f))) return fmod(rv, 1.f); + return rv; +} +#endif + +S32 ll_rand() +{ + return ll_rand(RAND_MAX); +} + +S32 ll_rand(S32 val) +{ + // The clamping rules are described above. + S32 rv = (S32)(ll_internal_random_double() * val); + if(rv == val) return 0; + return rv; +} + +F32 ll_frand() +{ + return ll_internal_random_float(); +} + +F32 ll_frand(F32 val) +{ + // The clamping rules are described above. + F32 rv = ll_internal_random_float() * val; + if(val > 0) + { + if(rv >= val) return 0.0f; + } + else + { + if(rv <= val) return 0.0f; + } + return rv; +} + +F64 ll_drand() +{ + return ll_internal_random_double(); +} + +F64 ll_drand(F64 val) +{ + // The clamping rules are described above. + F64 rv = ll_internal_random_double() * val; + if(val > 0) + { + if(rv >= val) return 0.0; + } + else + { + if(rv <= val) return 0.0; + } + return rv; +} diff --git a/linden/indra/llcommon/llrand.h b/linden/indra/llcommon/llrand.h new file mode 100644 index 0000000..0a28213 --- /dev/null +++ b/linden/indra/llcommon/llrand.h @@ -0,0 +1,132 @@ +/** + * @file llrand.h + * @brief Information, functions, and typedefs for randomness. + * + * $LicenseInfo:firstyear=2000&license=viewergpl$ + * + * Copyright (c) 2000-2008, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LL_LLRAND_H +#define LL_LLRAND_H + +#include +#include + +/** + * Use the boost random number generators if you want a stateful + * random numbers. If you want more random numbers, use the + * c-functions since they will generate faster/better randomness + * across the process. + * + * I tested some of the boost random engines, and picked a good double + * generator and a good integer generator. I also took some timings + * for them on linux using gcc 3.3.5. The harness also did some other + * fairly trivial operations to try to limit compiler optimizations, + * so these numbers are only good for relative comparisons. + * + * usec/inter algorithm + * 0.21 boost::minstd_rand0 + * 0.039 boost:lagged_fibonacci19937 + * 0.036 boost:lagged_fibonacci607 + * 0.44 boost::hellekalek1995 + * 0.44 boost::ecuyer1988 + * 0.042 boost::rand48 + * 0.043 boost::mt11213b + * 0.028 stdlib random() + * 0.05 stdlib lrand48() + * 0.034 stdlib rand() + * 0.020 the old & lame LLRand + */ + +/** + *@brief Generate a float from [0, RAND_MAX). + */ +S32 ll_rand(); + +/** + *@brief Generate a float from [0, val) or (val, 0]. + */ +S32 ll_rand(S32 val); + +/** + *@brief Generate a float from [0, 1.0). + */ +F32 ll_frand(); + +/** + *@brief Generate a float from [0, val) or (val, 0]. + */ +F32 ll_frand(F32 val); + +/** + *@brief Generate a double from [0, 1.0). + */ +F64 ll_drand(); + +/** + *@brief Generate a double from [0, val) or (val, 0]. + */ +F64 ll_drand(F64 val); + +/** + * @brief typedefs for good boost lagged fibonacci. + * @see boost::lagged_fibonacci + * + * These generators will quickly generate doubles. Note the memory + * requirements, because they are somewhat high. I chose the smallest + * one, and one comparable in speed but higher periodicity without + * outrageous memory requirements. + * To use: + * LLRandLagFib607 foo((U32)time(NULL)); + * double bar = foo(); + */ + +typedef boost::lagged_fibonacci607 LLRandLagFib607; +/**< + * lengh of cycle: 2^32,000 + * memory: 607*sizeof(double) (about 5K) + */ + +typedef boost::lagged_fibonacci2281 LLRandLagFib2281; +/**< + * lengh of cycle: 2^120,000 + * memory: 2281*sizeof(double) (about 17K) + */ + +/** + * @breif typedefs for a good boost mersenne twister implementation. + * @see boost::mersenne_twister + * + * This fairly quickly generates U32 values + * To use: + * LLRandMT19937 foo((U32)time(NULL)); + * U32 bar = foo(); + * + * lengh of cycle: 2^19,937-1 + * memory: about 2496 bytes + */ +typedef boost::mt11213b LLRandMT19937; +#endif diff --git a/linden/indra/llcommon/llsd.cpp b/linden/indra/llcommon/llsd.cpp index fa0531b..2c32184 100644 --- a/linden/indra/llcommon/llsd.cpp +++ b/linden/indra/llcommon/llsd.cpp @@ -42,10 +42,11 @@ #endif #ifdef NAME_UNNAMED_NAMESPACE -namespace LLSDUnnamedNamespace { +namespace LLSDUnnamedNamespace #else -namespace { +namespace #endif +{ class ImplMap; class ImplArray; } @@ -127,10 +128,10 @@ public: virtual void erase(Integer) { } virtual const LLSD& ref(Integer) const { return undef(); } - virtual LLSD::map_const_iterator beginMap() const { return LLSD::map_const_iterator(); } - virtual LLSD::map_const_iterator endMap() const { return LLSD::map_const_iterator(); } - virtual LLSD::array_const_iterator beginArray() const { return LLSD::array_const_iterator(); } - virtual LLSD::array_const_iterator endArray() const { return LLSD::array_const_iterator(); } + virtual LLSD::map_const_iterator beginMap() const { return endMap(); } + virtual LLSD::map_const_iterator endMap() const { static const std::map empty; return empty.end(); } + virtual LLSD::array_const_iterator beginArray() const { return endArray(); } + virtual LLSD::array_const_iterator endArray() const { static const std::vector empty; return empty.end(); } static const LLSD& undef(); @@ -139,10 +140,11 @@ public: }; #ifdef NAME_UNNAMED_NAMESPACE -namespace LLSDUnnamedNamespace { +namespace LLSDUnnamedNamespace #else -namespace { +namespace #endif +{ template class ImplBase : public LLSD::Impl ///< This class handles most of the work for a subclass of Impl @@ -185,6 +187,11 @@ namespace { }; LLSD::String ImplBoolean::asString() const + // *NOTE: The reason that false is not converted to "false" is + // because that would break roundtripping, + // e.g. LLSD(false).asString().asBoolean(). There are many + // reasons for wanting LLSD("false").asBoolean() == true, such + // as "everything else seems to work that way". { return mValue ? "true" : ""; } @@ -650,10 +657,11 @@ U32 LLSD::Impl::sOutstandingCount = 0; #ifdef NAME_UNNAMED_NAMESPACE -namespace LLSDUnnamedNamespace { +namespace LLSDUnnamedNamespace #else -namespace { +namespace #endif +{ inline LLSD::Impl& safe(LLSD::Impl* impl) { return LLSD::Impl::safe(impl); } diff --git a/linden/indra/llcommon/llsd.h b/linden/indra/llcommon/llsd.h index 3f53735..98a6692 100644 --- a/linden/indra/llcommon/llsd.h +++ b/linden/indra/llcommon/llsd.h @@ -40,7 +40,7 @@ #include "lldate.h" #include "lluri.h" -#include "../llmath/lluuid.h" +#include "lluuid.h" /** LLSD provides a flexible data system similar to the data facilities of @@ -394,7 +394,7 @@ std::ostream& operator<<(std::ostream& s, const LLSD& llsd); - as UTF8 encoded strings (making not like UUID<->String) - as Base64 or Base96 encoded (making like UUID<->String) - Conversions to std::string and LLUUID do not result in easy assignment - to std::string, LLString or LLUUID due to non-unique conversion paths + to std::string, std::string or LLUUID due to non-unique conversion paths */ #endif // LL_LLSD_NEW_H diff --git a/linden/indra/llcommon/llsdserialize.cpp b/linden/indra/llcommon/llsdserialize.cpp index a556d5d..d42842d 100644 --- a/linden/indra/llcommon/llsdserialize.cpp +++ b/linden/indra/llcommon/llsdserialize.cpp @@ -37,7 +37,7 @@ #include "llstreamtools.h" // for fullread #include -#include "apr-1/apr_base64.h" +#include "apr_base64.h" #if !LL_WINDOWS #include // htonl & ntohl @@ -146,12 +146,15 @@ bool LLSDSerialize::deserialize(LLSD& sd, std::istream& str, S32 max_bytes) * Create the parser as appropriate */ if (legacy_no_header) - { - LLSDXMLParser* x = new LLSDXMLParser; - x->parsePart(hdr_buf, inbuf); - p = x; + { // Create a LLSD XML parser, and parse the first chunk read above + LLSDXMLParser* x = new LLSDXMLParser(); + x->parsePart(hdr_buf, inbuf); // Parse the first part that was already read + x->parseLines(str, sd); // Parse the rest of it + delete x; + return true; } - else if (header == LLSD_BINARY_HEADER) + + if (header == LLSD_BINARY_HEADER) { p = new LLSDBinaryParser; } @@ -300,7 +303,8 @@ static const char BINARY_FALSE_SERIAL = '0'; /** * LLSDParser */ -LLSDParser::LLSDParser() : mCheckLimits(true), mMaxBytesLeft(0) +LLSDParser::LLSDParser() + : mCheckLimits(true), mMaxBytesLeft(0), mParseLines(false) { } @@ -316,6 +320,15 @@ S32 LLSDParser::parse(std::istream& istr, LLSD& data, S32 max_bytes) } +// Parse using routine to get() lines, faster than parse() +S32 LLSDParser::parseLines(std::istream& istr, LLSD& data) +{ + mCheckLimits = false; + mParseLines = false; // was true, Emergency fix DEV-17785 parsing newline failure + return doParse(istr, data); +} + + int LLSDParser::get(std::istream& istr) const { if(mCheckLimits) --mMaxBytesLeft; @@ -1217,8 +1230,7 @@ void LLSDFormatter::realFormat(const std::string& format) void LLSDFormatter::formatReal(LLSD::Real real, std::ostream& ostr) const { - char buffer[MAX_STRING]; /* Flawfinder: ignore */ - snprintf(buffer, MAX_STRING, mRealFormat.c_str(), real); /* Flawfinder: ignore */ + std::string buffer = llformat(mRealFormat.c_str(), real); ostr << buffer; } diff --git a/linden/indra/llcommon/llsdserialize.h b/linden/indra/llcommon/llsdserialize.h index f5282b4..94ad824 100644 --- a/linden/indra/llcommon/llsdserialize.h +++ b/linden/indra/llcommon/llsdserialize.h @@ -83,6 +83,18 @@ public: */ S32 parse(std::istream& istr, LLSD& data, S32 max_bytes); + /** Like parse(), but uses a different call (istream.getline()) to read by lines + * This API is better suited for XML, where the parse cannot tell + * where the document actually ends. + */ + S32 parseLines(std::istream& istr, LLSD& data); + + /** + * @brief Resets the parser so parse() or parseLines() can be called again for another chunk. + */ + void reset() { doReset(); }; + + protected: /** * @brief Pure virtual base for doing the parse. @@ -100,6 +112,11 @@ protected: */ virtual S32 doParse(std::istream& istr, LLSD& data) const = 0; + /** + * @brief Virtual default function for resetting the parser + */ + virtual void doReset() {}; + /* @name Simple istream helper methods * * These helper methods exist to help correctly use the @@ -191,6 +208,11 @@ protected: * @brief The maximum number of bytes left to be parsed. */ mutable S32 mMaxBytesLeft; + + /** + * @brief Use line-based reading to get text + */ + bool mParseLines; }; /** @@ -301,6 +323,11 @@ protected: */ virtual S32 doParse(std::istream& istr, LLSD& data) const; + /** + * @brief Virtual default function for resetting the parser + */ + virtual void doReset(); + private: class Impl; Impl& impl; @@ -674,7 +701,7 @@ public: U32 options = LLSDFormatter::OPTIONS_NONE); /** - * @breif Examine a stream, and parse 1 sd object out based on contents. + * @brief Examine a stream, and parse 1 sd object out based on contents. * * @param sd [out] The data found on the stream * @param str The incoming stream @@ -718,13 +745,23 @@ public: return f->format(sd, str, LLSDFormatter::OPTIONS_PRETTY); } - static S32 fromXML(LLSD& sd, std::istream& str) + static S32 fromXMLEmbedded(LLSD& sd, std::istream& str) { // no need for max_bytes since xml formatting is not // subvertable by bad sizes. LLPointer p = new LLSDXMLParser; return p->parse(str, sd, LLSDSerialize::SIZE_UNLIMITED); } + static S32 fromXMLDocument(LLSD& sd, std::istream& str) + { + LLPointer p = new LLSDXMLParser(); + return p->parseLines(str, sd); + } + static S32 fromXML(LLSD& sd, std::istream& str) + { + return fromXMLEmbedded(sd, str); +// return fromXMLDocument(sd, str); + } /* * Binary Methods diff --git a/linden/indra/llcommon/llsdserialize_xml.cpp b/linden/indra/llcommon/llsdserialize_xml.cpp index 7de0c35..690ab67 100644 --- a/linden/indra/llcommon/llsdserialize_xml.cpp +++ b/linden/indra/llcommon/llsdserialize_xml.cpp @@ -35,7 +35,7 @@ #include #include -#include "apr-1/apr_base64.h" +#include "apr_base64.h" extern "C" { @@ -63,7 +63,7 @@ S32 LLSDXMLFormatter::format(const LLSD& data, std::ostream& ostr, U32 options) { std::streamsize old_precision = ostr.precision(25); - LLString post = ""; + std::string post; if (options & LLSDFormatter::OPTIONS_PRETTY) { post = "\n"; @@ -79,8 +79,8 @@ S32 LLSDXMLFormatter::format(const LLSD& data, std::ostream& ostr, U32 options) S32 LLSDXMLFormatter::format_impl(const LLSD& data, std::ostream& ostr, U32 options, U32 level) const { S32 format_count = 1; - LLString pre = ""; - LLString post = ""; + std::string pre; + std::string post; if (options & LLSDFormatter::OPTIONS_PRETTY) { @@ -262,12 +262,13 @@ public: ~Impl(); S32 parse(std::istream& input, LLSD& data); + S32 parseLines(std::istream& input, LLSD& data); void parsePart(const char *buf, int len); -private: void reset(); - + +private: void startElementHandler(const XML_Char* name, const XML_Char** attributes); void endElementHandler(const XML_Char* name); void characterDataHandler(const XML_Char* data, int length); @@ -307,8 +308,8 @@ private: LLSD mResult; S32 mParseCount; - bool mInLLSDElement; - bool mGracefullStop; + bool mInLLSDElement; // true if we're on LLSD + bool mGracefullStop; // true if we found the LLSDRefStack; LLSDRefStack mStack; @@ -319,15 +320,12 @@ private: std::string mCurrentKey; std::ostringstream mCurrentContent; - - bool mPreStaged; }; LLSDXMLParser::Impl::Impl() { mParser = XML_ParserCreate(NULL); - mPreStaged = false; reset(); } @@ -336,7 +334,7 @@ LLSDXMLParser::Impl::~Impl() XML_ParserFree(mParser); } -bool is_eol(char c) +inline bool is_eol(char c) { return (c == '\n' || c == '\r'); } @@ -356,9 +354,9 @@ static unsigned get_till_eol(std::istream& input, char *buf, unsigned bufsize) unsigned count = 0; while (count < bufsize && input.good()) { - input.get(buf[count]); - count++; - if (is_eol(buf[count - 1])) + char c = input.get(); + buf[count++] = c; + if (is_eol(c)) break; } return count; @@ -366,7 +364,6 @@ static unsigned get_till_eol(std::istream& input, char *buf, unsigned bufsize) S32 LLSDXMLParser::Impl::parse(std::istream& input, LLSD& data) { - reset(); XML_Status status; static const int BUFFER_SIZE = 1024; @@ -420,14 +417,86 @@ S32 LLSDXMLParser::Impl::parse(std::istream& input, LLSD& data) return mParseCount; } -void LLSDXMLParser::Impl::reset() + +S32 LLSDXMLParser::Impl::parseLines(std::istream& input, LLSD& data) { - if (mPreStaged) + XML_Status status = XML_STATUS_OK; + + data = LLSD(); + + static const int BUFFER_SIZE = 1024; + + //static char last_buffer[ BUFFER_SIZE ]; + //std::streamsize last_num_read; + + // Must get rid of any leading \n, otherwise the stream gets into an error/eof state + clear_eol(input); + + while( !mGracefullStop + && input.good() + && !input.eof()) { - mPreStaged = false; - return; + void* buffer = XML_GetBuffer(mParser, BUFFER_SIZE); + /* + * If we happened to end our last buffer right at the end of the llsd, but the + * stream is still going we will get a null buffer here. Check for mGracefullStop. + * -- I don't think this is actually true - zero 2008-05-09 + */ + if (!buffer) + { + break; + } + + // Get one line + input.getline((char*)buffer, BUFFER_SIZE); + std::streamsize num_read = input.gcount(); + + //memcpy( last_buffer, buffer, num_read ); + //last_num_read = num_read; + + if ( num_read > 0 ) + { + if (!input.good() ) + { // Clear state that's set when we run out of buffer + input.clear(); + } + + // Don't parse the NULL at the end which might be added if \n was absorbed by getline() + char * text = (char *) buffer; + if ( text[num_read - 1] == 0) + { + num_read--; + } + } + + status = XML_ParseBuffer(mParser, num_read, false); + if (status == XML_STATUS_ERROR) + { + break; + } } + if (status != XML_STATUS_ERROR + && !mGracefullStop) + { // Parse last bit + status = XML_ParseBuffer(mParser, 0, true); + } + + if (status == XML_STATUS_ERROR + && !mGracefullStop) + { + llinfos << "LLSDXMLParser::Impl::parseLines: XML_STATUS_ERROR" << llendl; + return LLSDParser::PARSE_FAILURE; + } + + clear_eol(input); + data = mResult; + return mParseCount; +} + + +void LLSDXMLParser::Impl::reset() +{ mResult.clear(); mParseCount = 0; @@ -476,14 +545,15 @@ LLSDXMLParser::Impl::findAttribute(const XML_Char* name, const XML_Char** pairs) void LLSDXMLParser::Impl::parsePart(const char* buf, int len) { - void * buffer = XML_GetBuffer(mParser, len); - if (buffer != NULL && buf != NULL) + if ( buf != NULL + && len > 0 ) { - memcpy(buffer, buf, len); + XML_Status status = XML_Parse(mParser, buf, len, false); + if (status == XML_STATUS_ERROR) + { + llinfos << "Unexpected XML parsing error at start" << llendl; + } } - XML_ParseBuffer(mParser, len, false); - - mPreStaged = true; } void LLSDXMLParser::Impl::startElementHandler(const XML_Char* name, const XML_Char** attributes) @@ -738,5 +808,18 @@ void LLSDXMLParser::parsePart(const char *buf, int len) // virtual S32 LLSDXMLParser::doParse(std::istream& input, LLSD& data) const { - return impl.parse(input, data); +// Remove code - emergency fix DEV-17785 parsing newline failure +// if (mParseLines) +// { + // Use line-based reading (faster code) +// return impl.parseLines(input, data); +// } + + return impl.parse(input, data); +} + +// virtual +void LLSDXMLParser::doReset() +{ + impl.reset(); } diff --git a/linden/indra/llcommon/llsdutil.cpp b/linden/indra/llcommon/llsdutil.cpp index d1ccce0..b619fb6 100644 --- a/linden/indra/llcommon/llsdutil.cpp +++ b/linden/indra/llcommon/llsdutil.cpp @@ -46,124 +46,6 @@ #include "llsdserialize.h" -// vector3 -LLSD ll_sd_from_vector3(const LLVector3& vec) -{ - LLSD rv; - rv.append((F64)vec.mV[VX]); - rv.append((F64)vec.mV[VY]); - rv.append((F64)vec.mV[VZ]); - return rv; -} - -LLVector3 ll_vector3_from_sd(const LLSD& sd, S32 start_index) -{ - LLVector3 rv; - rv.mV[VX] = (F32)sd[start_index].asReal(); - rv.mV[VY] = (F32)sd[++start_index].asReal(); - rv.mV[VZ] = (F32)sd[++start_index].asReal(); - return rv; -} - -// vector4 -LLSD ll_sd_from_vector4(const LLVector4& vec) -{ - LLSD rv; - rv.append((F64)vec.mV[VX]); - rv.append((F64)vec.mV[VY]); - rv.append((F64)vec.mV[VZ]); - rv.append((F64)vec.mV[VW]); - return rv; -} - -LLVector4 ll_vector4_from_sd(const LLSD& sd, S32 start_index) -{ - LLVector4 rv; - rv.mV[VX] = (F32)sd[start_index].asReal(); - rv.mV[VY] = (F32)sd[++start_index].asReal(); - rv.mV[VZ] = (F32)sd[++start_index].asReal(); - rv.mV[VW] = (F32)sd[++start_index].asReal(); - return rv; -} - -// vector3d -LLSD ll_sd_from_vector3d(const LLVector3d& vec) -{ - LLSD rv; - rv.append(vec.mdV[VX]); - rv.append(vec.mdV[VY]); - rv.append(vec.mdV[VZ]); - return rv; -} - -LLVector3d ll_vector3d_from_sd(const LLSD& sd, S32 start_index) -{ - LLVector3d rv; - rv.mdV[VX] = sd[start_index].asReal(); - rv.mdV[VY] = sd[++start_index].asReal(); - rv.mdV[VZ] = sd[++start_index].asReal(); - return rv; -} - -//vector2 -LLSD ll_sd_from_vector2(const LLVector2& vec) -{ - LLSD rv; - rv.append((F64)vec.mV[VX]); - rv.append((F64)vec.mV[VY]); - return rv; -} - -LLVector2 ll_vector2_from_sd(const LLSD& sd) -{ - LLVector2 rv; - rv.mV[VX] = (F32)sd[0].asReal(); - rv.mV[VY] = (F32)sd[1].asReal(); - return rv; -} - -// Quaternion -LLSD ll_sd_from_quaternion(const LLQuaternion& quat) -{ - LLSD rv; - rv.append((F64)quat.mQ[VX]); - rv.append((F64)quat.mQ[VY]); - rv.append((F64)quat.mQ[VZ]); - rv.append((F64)quat.mQ[VW]); - return rv; -} - -LLQuaternion ll_quaternion_from_sd(const LLSD& sd) -{ - LLQuaternion quat; - quat.mQ[VX] = (F32)sd[0].asReal(); - quat.mQ[VY] = (F32)sd[1].asReal(); - quat.mQ[VZ] = (F32)sd[2].asReal(); - quat.mQ[VW] = (F32)sd[3].asReal(); - return quat; -} - -// color4 -LLSD ll_sd_from_color4(const LLColor4& c) -{ - LLSD rv; - rv.append(c.mV[0]); - rv.append(c.mV[1]); - rv.append(c.mV[2]); - rv.append(c.mV[3]); - return rv; -} - -LLColor4 ll_color4_from_sd(const LLSD& sd) -{ - LLColor4 c; - c.mV[0] = (F32)sd[0].asReal(); - c.mV[1] = (F32)sd[1].asReal(); - c.mV[2] = (F32)sd[2].asReal(); - c.mV[3] = (F32)sd[3].asReal(); - return c; -} - // U32 LLSD ll_sd_from_U32(const U32 val) { @@ -263,12 +145,11 @@ LLSD ll_binary_from_string(const LLSD& sd) { std::vector binary_value; - LLString string_value = sd.asString(); - const char* string_p = string_value.c_str(); - while (*string_p) + std::string string_value = sd.asString(); + for (std::string::iterator iter = string_value.begin(); + iter != string_value.end(); ++iter) { - binary_value.push_back(*string_p); - string_p++; + binary_value.push_back(*iter); } binary_value.push_back('\0'); @@ -303,8 +184,9 @@ char* ll_pretty_print_sd(const LLSD& sd) } //compares the structure of an LLSD to a template LLSD and stores the -//"valid" values in a 3rd LLSD. Default values are stored in the template -// +//"valid" values in a 3rd LLSD. Default values pulled from the template +//if the tested LLSD does not contain the key/value pair. +//Excess values in the test LLSD are ignored in the resultant_llsd. //If the llsd to test has a specific key to a map and the values //are not of the same type, false is returned or if the LLSDs are not //of the same value. Ordering of arrays matters diff --git a/linden/indra/llcommon/llsdutil.h b/linden/indra/llcommon/llsdutil.h index ae6d694..905c031 100644 --- a/linden/indra/llcommon/llsdutil.h +++ b/linden/indra/llcommon/llsdutil.h @@ -35,35 +35,34 @@ #define LL_LLSDUTIL_H #include "llsd.h" -#include "../llmath/v3math.h" -#include "../llmath/v4math.h" -#include "../llmath/v3dmath.h" -#include "../llmath/v2math.h" -#include "../llmath/llquaternion.h" -#include "../llmath/v4color.h" -#include "../llprimitive/lltextureanim.h" // vector3 +class LLVector3; LLSD ll_sd_from_vector3(const LLVector3& vec); LLVector3 ll_vector3_from_sd(const LLSD& sd, S32 start_index = 0); // vector4 +class LLVector4; LLSD ll_sd_from_vector4(const LLVector4& vec); LLVector4 ll_vector4_from_sd(const LLSD& sd, S32 start_index = 0); // vector3d (double) +class LLVector3d; LLSD ll_sd_from_vector3d(const LLVector3d& vec); LLVector3d ll_vector3d_from_sd(const LLSD& sd, S32 start_index = 0); // vector2 +class LLVector2; LLSD ll_sd_from_vector2(const LLVector2& vec); LLVector2 ll_vector2_from_sd(const LLSD& sd); // Quaternion +class LLQuaternion; LLSD ll_sd_from_quaternion(const LLQuaternion& quat); LLQuaternion ll_quaternion_from_sd(const LLSD& sd); // color4 +class LLColor4; LLSD ll_sd_from_color4(const LLColor4& c); LLColor4 ll_color4_from_sd(const LLSD& sd); @@ -93,9 +92,11 @@ char* ll_pretty_print_sd(const LLSD& sd); //compares the structure of an LLSD to a template LLSD and stores the //"valid" values in a 3rd LLSD. Default values -//are pulled from the template. Ordering of arrays matters +//are pulled from the template. Extra keys/values in the test +//are ignored in the resultant LLSD. Ordering of arrays matters //Returns false if the test is of same type but values differ in type //Otherwise, returns true + BOOL compare_llsd_with_template( const LLSD& llsd_to_test, const LLSD& template_llsd, diff --git a/linden/indra/llcommon/llsecondlifeurls.cpp b/linden/indra/llcommon/llsecondlifeurls.cpp index 46b8cde..ee478fe 100644 --- a/linden/indra/llcommon/llsecondlifeurls.cpp +++ b/linden/indra/llcommon/llsecondlifeurls.cpp @@ -32,56 +32,56 @@ #include "linden_common.h" #include "llsecondlifeurls.h" -const char CREATE_ACCOUNT_URL[] = - "http://secondlife.com/registration/"; +const std::string CREATE_ACCOUNT_URL ( + "http://secondlife.com/registration/"); -const char MANAGE_ACCOUNT[] = - "http://secondlife.com/account/"; +const std::string MANAGE_ACCOUNT ( + "http://secondlife.com/account/"); -const char AUCTION_URL[] = - "http://secondlife.com/auctions/auction-detail.php?id="; +const std::string AUCTION_URL ( + "http://secondlife.com/auctions/auction-detail.php?id="); -const char EVENTS_URL[] = - "http://secondlife.com/events/"; +const std::string EVENTS_URL ( + "http://secondlife.com/events/"); -const char TIER_UP_URL[] = - "http://secondlife.com/app/landtier"; +const std::string TIER_UP_URL ( + "http://secondlife.com/app/landtier"); -const char LAND_URL[] = - "http://secondlife.com/app/landtier"; +const std::string LAND_URL ( + "http://secondlife.com/app/landtier"); -const char UPGRADE_TO_PREMIUM_URL[] = - "http://secondlife.com/app/upgrade/"; +const std::string UPGRADE_TO_PREMIUM_URL ( + "http://secondlife.com/app/upgrade/"); -const char DIRECTX_9_URL[] = - "http://secondlife.com/support/"; +const std::string DIRECTX_9_URL ( + "http://secondlife.com/support/"); -const char AMD_AGP_URL[] = - "http://secondlife.com/support/"; +const std::string AMD_AGP_URL ( + "http://secondlife.com/support/"); -const char VIA_URL[] = - "http://secondlife.com/support/"; +const std::string VIA_URL ( + "http://secondlife.com/support/"); -const char SUPPORT_URL[] = - "http://secondlife.com/support/"; +const std::string SUPPORT_URL ( + "http://secondlife.com/support/"); -const char INTEL_CHIPSET_URL[] = - "http://secondlife.com/support/"; +const std::string INTEL_CHIPSET_URL ( + "http://secondlife.com/support/"); -const char SIS_CHIPSET_URL[] = - "http://secondlife.com/support/"; +const std::string SIS_CHIPSET_URL ( + "http://secondlife.com/support/"); -const char BLOGS_URL[] = - "http://blog.secondlife.com/"; +const std::string BLOGS_URL ( + "http://blog.secondlife.com/"); -const char BUY_CURRENCY_URL[] = - "http://secondlife.com/app/currency/"; +const std::string BUY_CURRENCY_URL ( + "http://secondlife.com/app/currency/"); -const char LSL_DOC_URL[] = - "http://secondlife.com/app/lsldoc/"; +const std::string LSL_DOC_URL ( + "http://secondlife.com/app/lsldoc/"); -const char SL_KB_URL[] = - "http://secondlife.com/knowledgebase/"; - -const char RELEASE_NOTES[] = "releasenotes.txt"; +const std::string SL_KB_URL ( + "http://secondlife.com/knowledgebase/"); +const std::string RELEASE_NOTES_BASE_URL ( + "http://secondlife.com/app/releasenotes/"); diff --git a/linden/indra/llcommon/llsecondlifeurls.h b/linden/indra/llcommon/llsecondlifeurls.h index 3fe086a..f612d5e 100644 --- a/linden/indra/llcommon/llsecondlifeurls.h +++ b/linden/indra/llcommon/llsecondlifeurls.h @@ -33,46 +33,46 @@ #define LL_LLSECONDLIFEURLS_H // Account registration web page -extern const char CREATE_ACCOUNT_URL[]; +extern const std::string CREATE_ACCOUNT_URL; // Manage Account -extern const char MANAGE_ACCOUNT[]; +extern const std::string MANAGE_ACCOUNT; -extern const char AUCTION_URL[]; +extern const std::string AUCTION_URL; -extern const char EVENTS_URL[]; +extern const std::string EVENTS_URL; // Tier up to a new land level. -extern const char TIER_UP_URL[]; +extern const std::string TIER_UP_URL; // Tier up to a new land level. -extern const char LAND_URL[]; +extern const std::string LAND_URL; // Upgrade from basic membership to premium membership -extern const char UPGRADE_TO_PREMIUM_URL[]; +extern const std::string UPGRADE_TO_PREMIUM_URL; // How to get DirectX 9 -extern const char DIRECTX_9_URL[]; +extern const std::string DIRECTX_9_URL; // Out of date VIA chipset -extern const char VIA_URL[]; +extern const std::string VIA_URL; // Support URL -extern const char SUPPORT_URL[]; +extern const std::string SUPPORT_URL; // Linden Blogs page -extern const char BLOGS_URL[]; +extern const std::string BLOGS_URL; // Currency page -extern const char BUY_CURRENCY_URL[]; +extern const std::string BUY_CURRENCY_URL; // LSL script wiki -extern const char LSL_DOC_URL[]; +extern const std::string LSL_DOC_URL; // SL KnowledgeBase page -extern const char SL_KB_URL[]; +extern const std::string SL_KB_URL; -// Local Url Release Notes -extern const char RELEASE_NOTES[]; +// Release Notes Redirect URL for Server and Viewer +extern const std::string RELEASE_NOTES_BASE_URL; #endif diff --git a/linden/indra/llcommon/llstat.cpp b/linden/indra/llcommon/llstat.cpp index 11e4c64..4b79fcb 100644 --- a/linden/indra/llcommon/llstat.cpp +++ b/linden/indra/llcommon/llstat.cpp @@ -76,10 +76,11 @@ public: U64 LLStatAccum::impl::sScaleTimes[IMPL_NUM_SCALES] = { + USEC_PER_SEC / 10, // 100 millisec USEC_PER_SEC * 1, // seconds USEC_PER_SEC * 60, // minutes - USEC_PER_SEC * 60 * 2 // minutes -#if 0 + USEC_PER_SEC * 60 * 2 // two minutes +#if ENABLE_LONG_TIME_STATS // enable these when more time scales are desired USEC_PER_SEC * 60*60, // hours USEC_PER_SEC * 24*60*60, // days diff --git a/linden/indra/llcommon/llstat.h b/linden/indra/llcommon/llstat.h index a0a86e6..0a7e014 100644 --- a/linden/indra/llcommon/llstat.h +++ b/linden/indra/llcommon/llstat.h @@ -37,6 +37,9 @@ #include "lltimer.h" #include "llframetimer.h" +// Set this if longer stats are needed +#define ENABLE_LONG_TIME_STATS 0 + // // Accumulates statistics for an arbitrary length of time. // Does this by maintaining a chain of accumulators, each one @@ -52,19 +55,22 @@ protected: public: enum TimeScale { + SCALE_100MS, SCALE_SECOND, SCALE_MINUTE, SCALE_TWO_MINUTE, +#if ENABLE_LONG_TIME_STATS SCALE_HOUR, SCALE_DAY, SCALE_WEEK, - +#endif NUM_SCALES }; F32 meanValue(TimeScale scale) const; // see the subclasses for the specific meaning of value + F32 meanValueOverLast100ms() const { return meanValue(SCALE_100MS); } F32 meanValueOverLastSecond() const { return meanValue(SCALE_SECOND); } F32 meanValueOverLastMinute() const { return meanValue(SCALE_MINUTE); } diff --git a/linden/indra/llcommon/llstatenums.h b/linden/indra/llcommon/llstatenums.h index bde6ade..6866586 100644 --- a/linden/indra/llcommon/llstatenums.h +++ b/linden/indra/llcommon/llstatenums.h @@ -63,7 +63,8 @@ enum LL_SIM_STAT_SIMPHYSICSSTEPMS, LL_SIM_STAT_SIMPHYSICSSHAPEMS, LL_SIM_STAT_SIMPHYSICSOTHERMS, - LL_SIM_STAT_SIMPHYSICSMEMORY + LL_SIM_STAT_SIMPHYSICSMEMORY, + LL_SIM_STAT_SCRIPT_EPS, }; #endif diff --git a/linden/indra/llcommon/llstl.h b/linden/indra/llcommon/llstl.h index 9a24185..4486727 100644 --- a/linden/indra/llcommon/llstl.h +++ b/linden/indra/llcommon/llstl.h @@ -105,6 +105,7 @@ struct DeletePairedPointer template void operator()(T &ptr) const { delete ptr.second; + ptr.second = NULL; } }; struct DeletePairedPointerArray @@ -112,6 +113,7 @@ struct DeletePairedPointerArray template void operator()(T &ptr) const { delete[] ptr.second; + ptr.second = NULL; } }; diff --git a/linden/indra/llcommon/llstring.cpp b/linden/indra/llcommon/llstring.cpp index a1f19ad..6a8efa8 100644 --- a/linden/indra/llcommon/llstring.cpp +++ b/linden/indra/llcommon/llstring.cpp @@ -1,6 +1,6 @@ /** * @file llstring.cpp - * @brief String utility functions and the LLString class. + * @brief String utility functions and the std::string class. * * $LicenseInfo:firstyear=2001&license=viewergpl$ * @@ -47,6 +47,12 @@ std::string ll_safe_string(const char* in) return std::string(); } +std::string ll_safe_string(const char* in, S32 maxlen) +{ + if(in) return std::string(in, maxlen); + return std::string(); +} + U8 hex_as_nybble(char hex) { if((hex >= '0') && (hex <= '9')) @@ -65,12 +71,12 @@ U8 hex_as_nybble(char hex) } -bool _read_file_into_string(std::string& str, const char* filename) +bool _read_file_into_string(std::string& str, const std::string& filename) { llifstream ifs(filename, llifstream::binary); if (!ifs.is_open()) { - llinfos << "Unable to open file" << filename << llendl; + llinfos << "Unable to open file " << filename << llendl; return false; } @@ -174,20 +180,6 @@ S32 utf16chars_to_wchar(const U16* inchars, llwchar* outchar) return inchars - base; } -S32 utf16chars_to_utf8chars(const U16* inchars, char* outchars, S32* nchars8p) -{ - // Get 32 bit char32 - llwchar char32; - S32 nchars16 = utf16chars_to_wchar(inchars, &char32); - // Convert to utf8 - S32 nchars8 = wchar_to_utf8chars(char32, outchars); - if (nchars8p) - { - *nchars8p = nchars8; - } - return nchars16; -} - llutf16string wstring_to_utf16str(const LLWString &utf32str, S32 len) { llutf16string out; @@ -216,7 +208,7 @@ llutf16string wstring_to_utf16str(const LLWString &utf32str) return wstring_to_utf16str(utf32str, len); } -llutf16string utf8str_to_utf16str ( const LLString& utf8str ) +llutf16string utf8str_to_utf16str ( const std::string& utf8str ) { LLWString wstr = utf8str_to_wstring ( utf8str ); return wstring_to_utf16str ( wstr ); @@ -492,210 +484,10 @@ std::string utf16str_to_utf8str(const llutf16string& utf16str, S32 len) return wstring_to_utf8str(utf16str_to_wstring(utf16str, len), len); } - -//LLWString wstring_truncate(const LLWString &wstr, const S32 max_len) -//{ -// return wstr.substr(0, llmin((S32)wstr.length(), max_len)); -//} -// -// -//LLWString wstring_trim(const LLWString &wstr) -//{ -// LLWString outstr; -// outstr = wstring_trimhead(wstr); -// outstr = wstring_trimtail(outstr); -// return outstr; -//} -// -// -//LLWString wstring_trimhead(const LLWString &wstr) -//{ -// if(wstr.empty()) -// { -// return wstr; -// } -// -// S32 i = 0; -// while((i < (S32)wstr.length()) && iswspace(wstr[i])) -// { -// i++; -// } -// return wstr.substr(i, wstr.length() - i); -//} -// -// -//LLWString wstring_trimtail(const LLWString &wstr) -//{ -// if(wstr.empty()) -// { -// return wstr; -// } -// -// S32 len = (S32)wstr.length(); -// -// S32 i = len - 1; -// while (i >= 0 && iswspace(wstr[i])) -// { -// i--; -// } -// -// if (i >= 0) -// { -// return wstr.substr(0, i + 1); -// } -// return wstr; -//} -// -// -//LLWString wstring_copyinto(const LLWString &dest, const LLWString &src, const S32 insert_offset) -//{ -// llassert( insert_offset <= (S32)dest.length() ); -// -// LLWString out_str = dest.substr(0, insert_offset); -// out_str += src; -// LLWString tail = dest.substr(insert_offset); -// out_str += tail; -// -// return out_str; -//} - - -//LLWString wstring_detabify(const LLWString &wstr, const S32 num_spaces) -//{ -// LLWString out_str; -// // Replace tabs with spaces -// for (S32 i = 0; i < (S32)wstr.length(); i++) -// { -// if (wstr[i] == '\t') -// { -// for (S32 j = 0; j < num_spaces; j++) -// out_str += ' '; -// } -// else -// { -// out_str += wstr[i]; -// } -// } -// return out_str; -//} - - -//LLWString wstring_makeASCII(const LLWString &wstr) -//{ -// // Replace non-ASCII chars with replace_char -// LLWString out_str = wstr; -// for (S32 i = 0; i < (S32)out_str.length(); i++) -// { -// if (out_str[i] > 0x7f) -// { -// out_str[i] = LL_UNKNOWN_CHAR; -// } -// } -// return out_str; -//} - - -//LLWString wstring_substChar(const LLWString &wstr, const llwchar target_char, const llwchar replace_char) -//{ -// // Replace all occurences of target_char with replace_char -// LLWString out_str = wstr; -// for (S32 i = 0; i < (S32)out_str.length(); i++) -// { -// if (out_str[i] == target_char) -// { -// out_str[i] = replace_char; -// } -// } -// return out_str; -//} -// -// -//LLWString wstring_tolower(const LLWString &wstr) -//{ -// LLWString out_str = wstr; -// for (S32 i = 0; i < (S32)out_str.length(); i++) -// { -// out_str[i] = towlower(out_str[i]); -// } -// return out_str; -//} -// -// -//LLWString wstring_convert_to_lf(const LLWString &wstr) -//{ -// const llwchar CR = 13; -// // Remove carriage returns from string with CRLF -// LLWString out_str; -// -// for (S32 i = 0; i < (S32)wstr.length(); i++) -// { -// if (wstr[i] != CR) -// { -// out_str += wstr[i]; -// } -// } -// return out_str; -//} -// -// -//LLWString wstring_convert_to_crlf(const LLWString &wstr) -//{ -// const llwchar LF = 10; -// const llwchar CR = 13; -// // Remove carriage returns from string with CRLF -// LLWString out_str; -// -// for (S32 i = 0; i < (S32)wstr.length(); i++) -// { -// if (wstr[i] == LF) -// { -// out_str += CR; -// } -// out_str += wstr[i]; -// } -// return out_str; -//} - - -//S32 wstring_compare_insensitive(const LLWString &lhs, const LLWString &rhs) -//{ -// -// if (lhs == rhs) -// { -// return 0; -// } -// -// if (lhs.empty()) -// { -// return rhs.empty() ? 0 : 1; -// } -// -// if (rhs.empty()) -// { -// return -1; -// } -// -//#ifdef LL_LINUX -// // doesn't work because gcc 2.95 doesn't correctly implement c_str(). Sigh... -// llerrs << "wstring_compare_insensitive doesn't work on Linux!" << llendl; -// return 0; -//#else -// LLWString lhs_lower = lhs; -// LLWString::toLower(lhs_lower); -// std::string lhs_lower = wstring_to_utf8str(lhs_lower); -// LLWString rhs_lower = lhs; -// LLWString::toLower(rhs_lower); -// std::string rhs_lower = wstring_to_utf8str(rhs_lower); -// -// return strcmp(lhs_lower.c_str(), rhs_lower.c_str()); -//#endif -//} - - std::string utf8str_trim(const std::string& utf8str) { LLWString wstr = utf8str_to_wstring(utf8str); - LLWString::trim(wstr); + LLWStringUtil::trim(wstr); return wstring_to_utf8str(wstr); } @@ -703,7 +495,7 @@ std::string utf8str_trim(const std::string& utf8str) std::string utf8str_tolower(const std::string& utf8str) { LLWString out_str = utf8str_to_wstring(utf8str); - LLWString::toLower(out_str); + LLWStringUtil::toLower(out_str); return wstring_to_utf8str(out_str); } @@ -712,7 +504,7 @@ S32 utf8str_compare_insensitive(const std::string& lhs, const std::string& rhs) { LLWString wlhs = utf8str_to_wstring(lhs); LLWString wrhs = utf8str_to_wstring(rhs); - return LLWString::compareInsensitive(wlhs.c_str(), wrhs.c_str()); + return LLWStringUtil::compareInsensitive(wlhs, wrhs); } std::string utf8str_truncate(const std::string& utf8str, const S32 max_len) @@ -756,7 +548,7 @@ std::string utf8str_substChar( const llwchar replace_char) { LLWString wstr = utf8str_to_wstring(utf8str); - LLWString::replaceChar(wstr, target_char, replace_char); + LLWStringUtil::replaceChar(wstr, target_char, replace_char); //wstr = wstring_substChar(wstr, target_char, replace_char); return wstring_to_utf8str(wstr); } @@ -764,7 +556,7 @@ std::string utf8str_substChar( std::string utf8str_makeASCII(const std::string& utf8str) { LLWString wstr = utf8str_to_wstring(utf8str); - LLWString::_makeASCII(wstr); + LLWStringUtil::_makeASCII(wstr); return wstring_to_utf8str(wstr); } @@ -929,6 +721,32 @@ namespace LLStringFn } } } + + // https://wiki.lindenlab.com/wiki/Unicode_Guidelines has details on + // allowable code points for XML. Specifically, they are: + // 0x09, 0x0a, 0x0d, and 0x20 on up. JC + std::string strip_invalid_xml(const std::string& input) + { + std::string output; + output.reserve( input.size() ); + std::string::const_iterator it = input.begin(); + while (it != input.end()) + { + // Must compare as unsigned for >= + // Test most likely match first + const unsigned char c = (unsigned char)*it; + if ( c >= (unsigned char)0x20 // SPACE + || c == (unsigned char)0x09 // TAB + || c == (unsigned char)0x0a // LINE_FEED + || c == (unsigned char)0x0d ) // CARRIAGE_RETURN + { + output.push_back(c); + } + ++it; + } + return output; + } + } @@ -938,19 +756,19 @@ namespace LLStringFn #ifdef _DEBUG template -void LLStringBase::testHarness() +void LLStringUtilBase::testHarness() { - LLString s1; + std::string s1; llassert( s1.c_str() == NULL ); llassert( s1.size() == 0 ); llassert( s1.empty() ); - LLString s2( "hello"); + std::string s2( "hello"); llassert( !strcmp( s2.c_str(), "hello" ) ); llassert( s2.size() == 5 ); llassert( !s2.empty() ); - LLString s3( s2 ); + std::string s3( s2 ); llassert( "hello" == s2 ); llassert( s2 == "hello" ); @@ -959,12 +777,12 @@ void LLStringBase::testHarness() llassert( "gello" != s2 ); llassert( s2 != "gello" ); - LLString s4 = s2; + std::string s4 = s2; llassert( !s4.empty() ); s4.empty(); llassert( s4.empty() ); - LLString s5(""); + std::string s5(""); llassert( s5.empty() ); llassert( isValidIndex(s5, 0) ); @@ -978,8 +796,8 @@ void LLStringBase::testHarness() llassert( s4 == "hello again!hello again!" ); - LLString s6 = s2 + " " + s2; - LLString s7 = s6; + std::string s6 = s2 + " " + s2; + std::string s7 = s6; llassert( s6 == s7 ); llassert( !( s6 != s7) ); llassert( !(s6 < s7) ); @@ -1002,10 +820,10 @@ void LLStringBase::testHarness() s2.insert( 1, "awn, don't yel"); llassert( s2 == "yawn, don't yell"); - LLString s8 = s2.substr( 6, 5 ); + std::string s8 = s2.substr( 6, 5 ); llassert( s8 == "don't" ); - LLString s9 = " \t\ntest \t\t\n "; + std::string s9 = " \t\ntest \t\t\n "; trim(s9); llassert( s9 == "test" ); @@ -1020,17 +838,17 @@ void LLStringBase::testHarness() llassert( s9 == "abc123&*(abc" ); - LLString s10( 10, 'x' ); + std::string s10( 10, 'x' ); llassert( s10 == "xxxxxxxxxx" ); - LLString s11( "monkey in the middle", 7, 2 ); + std::string s11( "monkey in the middle", 7, 2 ); llassert( s11 == "in" ); - LLString s12; //empty + std::string s12; //empty s12 += "foo"; llassert( s12 == "foo" ); - LLString s13; //empty + std::string s13; //empty s13 += 'f'; llassert( s13 == "f" ); } diff --git a/linden/indra/llcommon/llstring.h b/linden/indra/llcommon/llstring.h index 82ebdc9..60a4492 100644 --- a/linden/indra/llcommon/llstring.h +++ b/linden/indra/llcommon/llstring.h @@ -1,6 +1,6 @@ /** * @file llstring.h - * @brief String utility functions and LLString class. + * @brief String utility functions and std::string class. * * $LicenseInfo:firstyear=2001&license=viewergpl$ * @@ -39,15 +39,8 @@ const char LL_UNKNOWN_CHAR = '?'; -class LLVector3; -class LLVector3d; -class LLQuaternion; -class LLUUID; -class LLColor4; -class LLColor4U; - -#if (LL_DARWIN || LL_SOLARIS || (LL_LINUX && __GNUC__ > 2)) -// Template specialization of char_traits for U16s. Only necessary on Mac for now (exists on Windows, unused/broken on Linux/gcc2.95) +#if LL_DARWIN || LL_LINUX || LL_SOLARIS +// Template specialization of char_traits for U16s. Only necessary on Mac and Linux (exists on Windows already) namespace std { template<> @@ -162,79 +155,29 @@ public: static BOOL isDigit(llwchar a) { return iswdigit(a) != 0; } }; -//RN: I used a templated base class instead of a pure interface class to minimize code duplication -// but it might be worthwhile to just go with two implementations (LLString and LLWString) of -// an interface class, unless we can think of a good reason to have a std::basic_string polymorphic base - -//**************************************************************** -// NOTA BENE: do *NOT* dynamically allocate memory inside of LLStringBase as the {*()^#%*)#%W^*)#%*)STL implentation -// of basic_string doesn't provide a virtual destructor. If we need to allocate resources specific to LLString -// then we should either customize std::basic_string to linden::basic_string or change LLString to be a wrapper -// that contains an instance of std::basic_string. Similarly, overriding methods defined in std::basic_string will *not* -// be called in a polymorphic manner (passing an instance of basic_string to a particular function) -//**************************************************************** +// Allowing assignments from non-strings into format_map_t is apparently +// *really* error-prone, so subclass std::string with just basic c'tors. +class FormatMapString : public std::string +{ +public: + FormatMapString() : std::string() {}; + FormatMapString(const char* s) : std::string(s) {}; + FormatMapString(const std::string& s) : std::string(s) {}; +}; template -class LLStringBase : public std::basic_string +class LLStringUtilBase { public: typedef typename std::basic_string::size_type size_type; - // naming convention follows those set for LLUUID -// static LLStringBase null; // deprecated for std::string compliance -// static LLStringBase zero_length; // deprecated for std::string compliance - - - // standard constructors - LLStringBase() : std::basic_string() {} - LLStringBase(const LLStringBase& s): std::basic_string(s) {} - LLStringBase(const std::basic_string& s) : std::basic_string(s) {} - LLStringBase(const std::basic_string& s, size_type pos, size_type n = std::basic_string::npos) - : std::basic_string(s, pos, n) {} - LLStringBase(size_type count, const T& c) : std::basic_string() { assign(count, c);} - // custom constructors - LLStringBase(const T* s); - LLStringBase(const T* s, size_type n); - LLStringBase(const T* s, size_type pos, size_type n ); - -#if LL_LINUX || LL_SOLARIS - void clear() { assign(null); } - - LLStringBase& assign(const T* s); - LLStringBase& assign(const T* s, size_type n); - LLStringBase& assign(const LLStringBase& s); - LLStringBase& assign(size_type n, const T& c); - LLStringBase& assign(const T* a, const T* b); - LLStringBase& assign(typename LLStringBase::iterator &it1, typename LLStringBase::iterator &it2); - LLStringBase& assign(typename LLStringBase::const_iterator &it1, typename LLStringBase::const_iterator &it2); - - // workaround for bug in gcc2 STL headers. - #if ((__GNUC__ <= 2) && (!defined _STLPORT_VERSION)) - const T* c_str () const - { - if (length () == 0) - { - static const T zero = 0; - return &zero; - } - - //terminate (); - { string_char_traits::assign(const_cast(data())[length()], string_char_traits::eos()); } - - return data (); - } - #endif -#endif - - bool operator==(const T* _Right) const { return _Right ? (std::basic_string::compare(_Right) == 0) : this->empty(); } - public: ///////////////////////////////////////////////////////////////////////////////////////// // Static Utility functions that operate on std::strings - static LLStringBase null; + static std::basic_string null; - typedef std::map format_map_t; + typedef std::map format_map_t; static S32 format(std::basic_string& s, const format_map_t& fmt_map); static BOOL isValidIndex(const std::basic_string& string, size_type i) @@ -266,8 +209,8 @@ public: /** * @brief Unsafe way to make ascii characters. You should probably * only call this when interacting with the host operating system. - * The 1 byte LLString does not work correctly. - * The 2 and 4 byte LLString probably work, so LLWString::_makeASCII + * The 1 byte std::string does not work correctly. + * The 2 and 4 byte std::string probably work, so LLWStringUtil::_makeASCII * should work. */ static void _makeASCII(std::basic_string& string); @@ -289,11 +232,13 @@ public: // Like strcmp but also handles empty strings. Uses // current locale. static S32 compareStrings(const T* lhs, const T* rhs); + static S32 compareStrings(const std::basic_string& lhs, const std::basic_string& rhs); // case insensitive version of above. Uses current locale on // Win32, and falls back to a non-locale aware comparison on // Linux. static S32 compareInsensitive(const T* lhs, const T* rhs); + static S32 compareInsensitive(const std::basic_string& lhs, const std::basic_string& rhs); // Case sensitive comparison with good handling of numbers. Does not use current locale. // a.k.a. strdictcmp() @@ -320,21 +265,21 @@ public: }; -template LLStringBase LLStringBase::null; +template std::basic_string LLStringUtilBase::null; -typedef LLStringBase LLString; -typedef LLStringBase LLWString; +typedef LLStringUtilBase LLStringUtil; +typedef LLStringUtilBase LLWStringUtil; +typedef std::basic_string LLWString; //@ Use this where we want to disallow input in the form of "foo" // This is used to catch places where english text is embedded in the code // instead of in a translatable XUI file. -class LLStringExplicit : public LLString +class LLStringExplicit : public std::string { public: - explicit LLStringExplicit(const char* s) : LLString(s) {} - LLStringExplicit(const LLString& s) : LLString(s) {} - LLStringExplicit(const std::string& s) : LLString(s) {} - LLStringExplicit(const std::string& s, size_type pos, size_type n = std::string::npos) : LLString(s, pos, n) {} + explicit LLStringExplicit(const char* s) : std::string(s) {} + LLStringExplicit(const std::string& s) : std::string(s) {} + LLStringExplicit(const std::string& s, size_type pos, size_type n = std::string::npos) : std::string(s, pos, n) {} }; struct LLDictionaryLess @@ -342,7 +287,7 @@ struct LLDictionaryLess public: bool operator()(const std::string& a, const std::string& b) { - return (LLString::precedesDict(a, b) ? true : false); + return (LLStringUtil::precedesDict(a, b) ? true : false); } }; @@ -371,6 +316,7 @@ inline std::string chop_tail_copy( * pointer is NULL. */ std::string ll_safe_string(const char* in); +std::string ll_safe_string(const char* in, S32 maxlen); /** * @brief This translates a nybble stored as a hex value from 0-f back @@ -387,7 +333,7 @@ U8 hex_as_nybble(char hex); * @param filename The full name of the file to read. * @return Returns true on success. If false, str is unmodified. */ -bool _read_file_into_string(std::string& str, const char* filename); +bool _read_file_into_string(std::string& str, const std::string& filename); /** * Unicode support @@ -409,20 +355,17 @@ LLWString utf16str_to_wstring(const llutf16string &utf16str); llutf16string wstring_to_utf16str(const LLWString &utf32str, S32 len); llutf16string wstring_to_utf16str(const LLWString &utf32str); -llutf16string utf8str_to_utf16str ( const LLString& utf8str, S32 len); -llutf16string utf8str_to_utf16str ( const LLString& utf8str ); +llutf16string utf8str_to_utf16str ( const std::string& utf8str, S32 len); +llutf16string utf8str_to_utf16str ( const std::string& utf8str ); LLWString utf8str_to_wstring(const std::string &utf8str, S32 len); LLWString utf8str_to_wstring(const std::string &utf8str); // Same function, better name. JC inline LLWString utf8string_to_wstring(const std::string& utf8_string) { return utf8str_to_wstring(utf8_string); } -// Special hack for llfilepicker.cpp: -S32 utf16chars_to_utf8chars(const U16* inchars, char* outchars, S32* nchars8 = 0); -S32 utf16chars_to_wchar(const U16* inchars, llwchar* outchar); +// S32 wchar_to_utf8chars(llwchar inchar, char* outchars); -// std::string wstring_to_utf8str(const LLWString &utf32str, S32 len); std::string wstring_to_utf8str(const LLWString &utf32str); @@ -484,15 +427,6 @@ std::string mbcsstring_makeASCII(const std::string& str); std::string utf8str_removeCRLF(const std::string& utf8str); -template -std::ostream& operator<<(std::ostream &s, const LLStringBase &str) -{ - s << ((std::basic_string)str); - return s; -} - -std::ostream& operator<<(std::ostream &s, const LLWString &wstr); - #if LL_WINDOWS /* @name Windows string helpers */ @@ -528,7 +462,7 @@ std::string ll_convert_wide_to_string(const wchar_t* in); #endif // LL_WINDOWS /** - * Many of the 'strip' and 'replace' methods of LLStringBase need + * Many of the 'strip' and 'replace' methods of LLStringUtilBase need * specialization to work with the signed char type. * Sadly, it is not possible (AFAIK) to specialize a single method of * a template class. @@ -581,30 +515,68 @@ namespace LLStringFn */ void replace_nonprintable_and_pipe(std::basic_string& str, llwchar replacement); + + /** + * @brief Remove all characters that are not allowed in XML 1.0. + * Returns a copy of the string with those characters removed. + * Works with US ASCII and UTF-8 encoded strings. JC + */ + std::string strip_invalid_xml(const std::string& input); } //////////////////////////////////////////////////////////// +// LLStringBase::format() +// +// This function takes a string 's' and a map 'fmt_map' of strings-to-strings. +// All occurances of strings in 's' from the left-hand side of 'fmt_map' are +// then replaced with the corresponding right-hand side of 'fmt_map', non- +// recursively. The function returns the number of substitutions made. + // static template -S32 LLStringBase::format(std::basic_string& s, const format_map_t& fmt_map) +S32 LLStringUtilBase::format(std::basic_string& s, const format_map_t& fmt_map) { typedef typename std::basic_string::size_type string_size_type_t; + string_size_type_t scanstart = 0; S32 res = 0; - for (format_map_t::const_iterator iter = fmt_map.begin(); iter != fmt_map.end(); ++iter) + + // Look for the first match of any keyword, replace that keyword, + // repeat from the end of the replacement string. This avoids + // accidentally performing substitution on a substituted string. + while (1) { - U32 fmtlen = iter->first.size(); - string_size_type_t n = 0; - while (1) + string_size_type_t first_match_pos = scanstart; + string_size_type_t first_match_str_length = 0; + std::basic_string first_match_str_replacement; + + for (format_map_t::const_iterator iter = fmt_map.begin(); + iter != fmt_map.end(); + ++iter) { - n = s.find(iter->first, n); - if (n == std::basic_string::npos) + string_size_type_t n = s.find(iter->first, scanstart); + if (n != std::basic_string::npos && + (n < first_match_pos || + 0 == first_match_str_length)) { - break; + first_match_pos = n; + first_match_str_length = iter->first.length(); + first_match_str_replacement = iter->second; } - s.erase(n, fmtlen); - s.insert(n, iter->second); - n += fmtlen; + } + + if (0 == first_match_str_length) + { + // no more keys found to substitute from this point + // in the string forward. + break; + } + else + { + s.erase(first_match_pos, first_match_str_length); + s.insert(first_match_pos, first_match_str_replacement); + scanstart = first_match_pos + + first_match_str_replacement.length(); ++res; } } @@ -613,7 +585,7 @@ S32 LLStringBase::format(std::basic_string& s, const format_map_t& fmt_map // static template -S32 LLStringBase::compareStrings(const T* lhs, const T* rhs) +S32 LLStringUtilBase::compareStrings(const T* lhs, const T* rhs) { S32 result; if( lhs == rhs ) @@ -637,9 +609,16 @@ S32 LLStringBase::compareStrings(const T* lhs, const T* rhs) return result; } +//static +template +S32 LLStringUtilBase::compareStrings(const std::basic_string& lhs, const std::basic_string& rhs) +{ + return LLStringOps::collate(lhs.c_str(), rhs.c_str()); +} + // static template -S32 LLStringBase::compareInsensitive(const T* lhs, const T* rhs ) +S32 LLStringUtilBase::compareInsensitive(const T* lhs, const T* rhs ) { S32 result; if( lhs == rhs ) @@ -658,22 +637,32 @@ S32 LLStringBase::compareInsensitive(const T* lhs, const T* rhs ) } else { - LLStringBase lhs_string(lhs); - LLStringBase rhs_string(rhs); - LLStringBase::toUpper(lhs_string); - LLStringBase::toUpper(rhs_string); + std::basic_string lhs_string(lhs); + std::basic_string rhs_string(rhs); + LLStringUtilBase::toUpper(lhs_string); + LLStringUtilBase::toUpper(rhs_string); result = LLStringOps::collate(lhs_string.c_str(), rhs_string.c_str()); } return result; } +//static +template +S32 LLStringUtilBase::compareInsensitive(const std::basic_string& lhs, const std::basic_string& rhs) +{ + std::basic_string lhs_string(lhs); + std::basic_string rhs_string(rhs); + LLStringUtilBase::toUpper(lhs_string); + LLStringUtilBase::toUpper(rhs_string); + return LLStringOps::collate(lhs_string.c_str(), rhs_string.c_str()); +} // Case sensitive comparison with good handling of numbers. Does not use current locale. // a.k.a. strdictcmp() //static template -S32 LLStringBase::compareDict(const std::basic_string& astr, const std::basic_string& bstr) +S32 LLStringUtilBase::compareDict(const std::basic_string& astr, const std::basic_string& bstr) { const T* a = astr.c_str(); const T* b = bstr.c_str(); @@ -712,8 +701,9 @@ S32 LLStringBase::compareDict(const std::basic_string& astr, const std::ba return ca-cb; } +// static template -S32 LLStringBase::compareDictInsensitive(const std::basic_string& astr, const std::basic_string& bstr) +S32 LLStringUtilBase::compareDictInsensitive(const std::basic_string& astr, const std::basic_string& bstr) { const T* a = astr.c_str(); const T* b = bstr.c_str(); @@ -748,11 +738,11 @@ S32 LLStringBase::compareDictInsensitive(const std::basic_string& astr, co // Puts compareDict() in a form appropriate for LL container classes to use for sorting. // static template -BOOL LLStringBase::precedesDict( const std::basic_string& a, const std::basic_string& b ) +BOOL LLStringUtilBase::precedesDict( const std::basic_string& a, const std::basic_string& b ) { if( a.size() && b.size() ) { - return (LLStringBase::compareDict(a.c_str(), b.c_str()) < 0); + return (LLStringUtilBase::compareDict(a.c_str(), b.c_str()) < 0); } else { @@ -760,108 +750,9 @@ BOOL LLStringBase::precedesDict( const std::basic_string& a, const std::ba } } -// Constructors -template -LLStringBase::LLStringBase(const T* s ) : std::basic_string() -{ - if (s) assign(s); -} - -template -LLStringBase::LLStringBase(const T* s, size_type n ) : std::basic_string() -{ - if (s) assign(s, n); -} - -// Init from a substring -template -LLStringBase::LLStringBase(const T* s, size_type pos, size_type n ) : std::basic_string() -{ - if( s ) - { - assign(s + pos, n); - } - else - { - assign(LLStringBase::null); - } -} - -#if LL_LINUX || LL_SOLARIS -template -LLStringBase& LLStringBase::assign(const T* s) -{ - if (s) - { - std::basic_string::assign(s); - } - else - { - assign(LLStringBase::null); - } - return *this; -} - -template -LLStringBase& LLStringBase::assign(const T* s, size_type n) -{ - if (s) - { - std::basic_string::assign(s, n); - } - else - { - assign(LLStringBase::null); - } - return *this; -} - -template -LLStringBase& LLStringBase::assign(const LLStringBase& s) -{ - std::basic_string::assign(s); - return *this; -} - -template -LLStringBase& LLStringBase::assign(size_type n, const T& c) -{ - std::basic_string::assign(n, c); - return *this; -} - -template -LLStringBase& LLStringBase::assign(const T* a, const T* b) -{ - if (a > b) - assign(LLStringBase::null); - else - assign(a, (size_type) (b-a)); - return *this; -} - -template -LLStringBase& LLStringBase::assign(typename LLStringBase::iterator &it1, typename LLStringBase::iterator &it2) -{ - assign(LLStringBase::null); - while(it1 != it2) - *this += *it1++; - return *this; -} - -template -LLStringBase& LLStringBase::assign(typename LLStringBase::const_iterator &it1, typename LLStringBase::const_iterator &it2) -{ - assign(LLStringBase::null); - while(it1 != it2) - *this += *it1++; - return *this; -} -#endif - //static template -void LLStringBase::toUpper(std::basic_string& string) +void LLStringUtilBase::toUpper(std::basic_string& string) { if( !string.empty() ) { @@ -875,7 +766,7 @@ void LLStringBase::toUpper(std::basic_string& string) //static template -void LLStringBase::toLower(std::basic_string& string) +void LLStringUtilBase::toLower(std::basic_string& string) { if( !string.empty() ) { @@ -889,7 +780,7 @@ void LLStringBase::toLower(std::basic_string& string) //static template -void LLStringBase::trimHead(std::basic_string& string) +void LLStringUtilBase::trimHead(std::basic_string& string) { if( !string.empty() ) { @@ -904,7 +795,7 @@ void LLStringBase::trimHead(std::basic_string& string) //static template -void LLStringBase::trimTail(std::basic_string& string) +void LLStringUtilBase::trimTail(std::basic_string& string) { if( string.size() ) { @@ -923,7 +814,7 @@ void LLStringBase::trimTail(std::basic_string& string) // Replace line feeds with carriage return-line feed pairs. //static template -void LLStringBase::addCRLF(std::basic_string& string) +void LLStringUtilBase::addCRLF(std::basic_string& string) { const T LF = 10; const T CR = 13; @@ -964,7 +855,7 @@ void LLStringBase::addCRLF(std::basic_string& string) // Remove all carriage returns //static template -void LLStringBase::removeCRLF(std::basic_string& string) +void LLStringUtilBase::removeCRLF(std::basic_string& string) { const T CR = 13; @@ -985,7 +876,7 @@ void LLStringBase::removeCRLF(std::basic_string& string) //static template -void LLStringBase::replaceChar( std::basic_string& string, T target, T replacement ) +void LLStringUtilBase::replaceChar( std::basic_string& string, T target, T replacement ) { size_type found_pos = 0; for (found_pos = string.find(target, found_pos); @@ -998,7 +889,7 @@ void LLStringBase::replaceChar( std::basic_string& string, T target, T rep //static template -void LLStringBase::replaceNonstandardASCII( std::basic_string& string, T replacement ) +void LLStringUtilBase::replaceNonstandardASCII( std::basic_string& string, T replacement ) { const char LF = 10; const S8 MIN = 32; @@ -1018,12 +909,12 @@ void LLStringBase::replaceNonstandardASCII( std::basic_string& string, T r //static template -void LLStringBase::replaceTabsWithSpaces( std::basic_string& str, size_type spaces_per_tab ) +void LLStringUtilBase::replaceTabsWithSpaces( std::basic_string& str, size_type spaces_per_tab ) { const T TAB = '\t'; const T SPACE = ' '; - LLStringBase out_str; + std::basic_string out_str; // Replace tabs with spaces for (size_type i = 0; i < str.length(); i++) { @@ -1042,7 +933,7 @@ void LLStringBase::replaceTabsWithSpaces( std::basic_string& str, size_typ //static template -BOOL LLStringBase::containsNonprintable(const std::basic_string& string) +BOOL LLStringUtilBase::containsNonprintable(const std::basic_string& string) { const char MIN = 32; BOOL rv = FALSE; @@ -1059,7 +950,7 @@ BOOL LLStringBase::containsNonprintable(const std::basic_string& string) //static template -void LLStringBase::stripNonprintable(std::basic_string& string) +void LLStringUtilBase::stripNonprintable(std::basic_string& string) { const char MIN = 32; size_type j = 0; @@ -1090,7 +981,7 @@ void LLStringBase::stripNonprintable(std::basic_string& string) } template -void LLStringBase::_makeASCII(std::basic_string& string) +void LLStringUtilBase::_makeASCII(std::basic_string& string) { // Replace non-ASCII chars with LL_UNKNOWN_CHAR for (size_type i = 0; i < string.length(); i++) @@ -1104,7 +995,7 @@ void LLStringBase::_makeASCII(std::basic_string& string) // static template -void LLStringBase::copy( T* dst, const T* src, size_type dst_size ) +void LLStringUtilBase::copy( T* dst, const T* src, size_type dst_size ) { if( dst_size > 0 ) { @@ -1120,7 +1011,7 @@ void LLStringBase::copy( T* dst, const T* src, size_type dst_size ) // static template -void LLStringBase::copyInto(std::basic_string& dst, const std::basic_string& src, size_type offset) +void LLStringUtilBase::copyInto(std::basic_string& dst, const std::basic_string& src, size_type offset) { if ( offset == dst.length() ) { @@ -1141,7 +1032,7 @@ void LLStringBase::copyInto(std::basic_string& dst, const std::basic_strin // True if this is the head of s. //static template -BOOL LLStringBase::isHead( const std::basic_string& string, const T* s ) +BOOL LLStringUtilBase::isHead( const std::basic_string& string, const T* s ) { if( string.empty() ) { @@ -1155,14 +1046,14 @@ BOOL LLStringBase::isHead( const std::basic_string& string, const T* s ) } template -BOOL LLStringBase::convertToBOOL(const std::basic_string& string, BOOL& value) +BOOL LLStringUtilBase::convertToBOOL(const std::basic_string& string, BOOL& value) { if( string.empty() ) { return FALSE; } - LLStringBase temp( string ); + std::basic_string temp( string ); trim(temp); if( (temp == "1") || @@ -1192,7 +1083,7 @@ BOOL LLStringBase::convertToBOOL(const std::basic_string& string, BOOL& va } template -BOOL LLStringBase::convertToU8(const std::basic_string& string, U8& value) +BOOL LLStringUtilBase::convertToU8(const std::basic_string& string, U8& value) { S32 value32 = 0; BOOL success = convertToS32(string, value32); @@ -1205,7 +1096,7 @@ BOOL LLStringBase::convertToU8(const std::basic_string& string, U8& value) } template -BOOL LLStringBase::convertToS8(const std::basic_string& string, S8& value) +BOOL LLStringUtilBase::convertToS8(const std::basic_string& string, S8& value) { S32 value32 = 0; BOOL success = convertToS32(string, value32); @@ -1218,7 +1109,7 @@ BOOL LLStringBase::convertToS8(const std::basic_string& string, S8& value) } template -BOOL LLStringBase::convertToS16(const std::basic_string& string, S16& value) +BOOL LLStringUtilBase::convertToS16(const std::basic_string& string, S16& value) { S32 value32 = 0; BOOL success = convertToS32(string, value32); @@ -1231,7 +1122,7 @@ BOOL LLStringBase::convertToS16(const std::basic_string& string, S16& valu } template -BOOL LLStringBase::convertToU16(const std::basic_string& string, U16& value) +BOOL LLStringUtilBase::convertToU16(const std::basic_string& string, U16& value) { S32 value32 = 0; BOOL success = convertToS32(string, value32); @@ -1244,14 +1135,14 @@ BOOL LLStringBase::convertToU16(const std::basic_string& string, U16& valu } template -BOOL LLStringBase::convertToU32(const std::basic_string& string, U32& value) +BOOL LLStringUtilBase::convertToU32(const std::basic_string& string, U32& value) { if( string.empty() ) { return FALSE; } - LLStringBase temp( string ); + std::basic_string temp( string ); trim(temp); U32 v; std::basic_istringstream i_stream((std::basic_string)temp); @@ -1271,14 +1162,14 @@ BOOL LLStringBase::convertToU32(const std::basic_string& string, U32& valu } template -BOOL LLStringBase::convertToS32(const std::basic_string& string, S32& value) +BOOL LLStringUtilBase::convertToS32(const std::basic_string& string, S32& value) { if( string.empty() ) { return FALSE; } - LLStringBase temp( string ); + std::basic_string temp( string ); trim(temp); S32 v; std::basic_istringstream i_stream((std::basic_string)temp); @@ -1298,7 +1189,7 @@ BOOL LLStringBase::convertToS32(const std::basic_string& string, S32& valu } template -BOOL LLStringBase::convertToF32(const std::basic_string& string, F32& value) +BOOL LLStringUtilBase::convertToF32(const std::basic_string& string, F32& value) { F64 value64 = 0.0; BOOL success = convertToF64(string, value64); @@ -1311,14 +1202,14 @@ BOOL LLStringBase::convertToF32(const std::basic_string& string, F32& valu } template -BOOL LLStringBase::convertToF64(const std::basic_string& string, F64& value) +BOOL LLStringUtilBase::convertToF64(const std::basic_string& string, F64& value) { if( string.empty() ) { return FALSE; } - LLStringBase temp( string ); + std::basic_string temp( string ); trim(temp); F64 v; std::basic_istringstream i_stream((std::basic_string)temp); @@ -1338,7 +1229,7 @@ BOOL LLStringBase::convertToF64(const std::basic_string& string, F64& valu } template -void LLStringBase::truncate(std::basic_string& string, size_type count) +void LLStringUtilBase::truncate(std::basic_string& string, size_type count) { size_type cur_size = string.size(); string.resize(count < cur_size ? count : cur_size); diff --git a/linden/indra/llcommon/llsys.cpp b/linden/indra/llcommon/llsys.cpp index 1285851..cb2e34a 100644 --- a/linden/indra/llcommon/llsys.cpp +++ b/linden/indra/llcommon/llsys.cpp @@ -143,28 +143,22 @@ LLOSInfo::LLOSInfo() : std::string csdversion = utf16str_to_utf8str(osvi.szCSDVersion); // Display version, service pack (if any), and build number. - char tmp[MAX_STRING]; /* Flawfinder: ignore */ + std::string tmpstr; if(osvi.dwMajorVersion <= 4) { - snprintf( /* Flawfinder: ignore */ - tmp, - sizeof(tmp), - "version %d.%d %s (Build %d)", - osvi.dwMajorVersion, - osvi.dwMinorVersion, - csdversion.c_str(), - (osvi.dwBuildNumber & 0xffff)); + tmpstr = llformat("version %d.%d %s (Build %d)", + osvi.dwMajorVersion, + osvi.dwMinorVersion, + csdversion.c_str(), + (osvi.dwBuildNumber & 0xffff)); } else { - snprintf( /* Flawfinder: ignore */ - tmp, - sizeof(tmp), - "%s (Build %d)", - csdversion.c_str(), - (osvi.dwBuildNumber & 0xffff)); + tmpstr = llformat("%s (Build %d)", + csdversion.c_str(), + (osvi.dwBuildNumber & 0xffff)); } - mOSString = mOSStringSimple + tmp; + mOSString = mOSStringSimple + tmpstr; } break; @@ -397,7 +391,7 @@ LLCPUInfo::LLCPUInfo() mCPUString = out.str(); #elif LL_LINUX - std::map< LLString, LLString > cpuinfo; + std::map< std::string, std::string > cpuinfo; LLFILE* cpuinfo_fp = LLFile::fopen(CPUINFO_FILE, "rb"); if(cpuinfo_fp) { @@ -420,21 +414,21 @@ LLCPUInfo::LLCPUInfo() if (nlspot == NULL) nlspot = line + strlen( line ); // Fallback to terminating NUL std::string linename( line, tabspot ); - LLString llinename(linename); - LLString::toLower(llinename); + std::string llinename(linename); + LLStringUtil::toLower(llinename); std::string lineval( spacespot + 1, nlspot ); cpuinfo[ llinename ] = lineval; } fclose(cpuinfo_fp); } # if LL_X86 - LLString flags = " " + cpuinfo["flags"] + " "; - LLString::toLower(flags); + std::string flags = " " + cpuinfo["flags"] + " "; + LLStringUtil::toLower(flags); mHasSSE = ( flags.find( " sse " ) != std::string::npos ); mHasSSE2 = ( flags.find( " sse2 " ) != std::string::npos ); F64 mhz; - if (LLString::convertToF64(cpuinfo["cpu mhz"], mhz) + if (LLStringUtil::convertToF64(cpuinfo["cpu mhz"], mhz) && 200.0 < mhz && mhz < 10000.0) { mCPUMhz = (S32)llrint(mhz); @@ -658,18 +652,17 @@ std::ostream& operator<<(std::ostream& s, const LLMemoryInfo& info) return s; } -BOOL gunzip_file(const char *srcfile, const char *dstfile) +BOOL gunzip_file(const std::string& srcfile, const std::string& dstfile) { - char tmpfile[LL_MAX_PATH]; /* Flawfinder: ignore */ + std::string tmpfile; const S32 UNCOMPRESS_BUFFER_SIZE = 32768; BOOL retval = FALSE; gzFile src = NULL; U8 buffer[UNCOMPRESS_BUFFER_SIZE]; LLFILE *dst = NULL; S32 bytes = 0; - (void *) strcpy(tmpfile, dstfile); /* Flawfinder: ignore */ - (void *) strncat(tmpfile, ".t", sizeof(tmpfile) - strlen(tmpfile) -1); /* Flawfinder: ignore */ - src = gzopen(srcfile, "rb"); + tmpfile = dstfile + ".t"; + src = gzopen(srcfile.c_str(), "rb"); if (! src) goto err; dst = LLFile::fopen(tmpfile, "wb"); /* Flawfinder: ignore */ if (! dst) goto err; @@ -693,18 +686,17 @@ err: return retval; } -BOOL gzip_file(const char *srcfile, const char *dstfile) +BOOL gzip_file(const std::string& srcfile, const std::string& dstfile) { const S32 COMPRESS_BUFFER_SIZE = 32768; - char tmpfile[LL_MAX_PATH]; /* Flawfinder: ignore */ + std::string tmpfile; BOOL retval = FALSE; U8 buffer[COMPRESS_BUFFER_SIZE]; gzFile dst = NULL; LLFILE *src = NULL; S32 bytes = 0; - (void *) strcpy(tmpfile, dstfile); /* Flawfinder: ignore */ - (void *) strncat(tmpfile, ".t", sizeof(tmpfile) - strlen(tmpfile) -1); /* Flawfinder: ignore */ - dst = gzopen(tmpfile, "wb"); /* Flawfinder: ignore */ + tmpfile = dstfile + ".t"; + dst = gzopen(tmpfile.c_str(), "wb"); /* Flawfinder: ignore */ if (! dst) goto err; src = LLFile::fopen(srcfile, "rb"); /* Flawfinder: ignore */ if (! src) goto err; diff --git a/linden/indra/llcommon/llsys.h b/linden/indra/llcommon/llsys.h index da7f07e..b764ca9 100644 --- a/linden/indra/llcommon/llsys.h +++ b/linden/indra/llcommon/llsys.h @@ -127,9 +127,9 @@ std::ostream& operator<<(std::ostream& s, const LLCPUInfo& info); std::ostream& operator<<(std::ostream& s, const LLMemoryInfo& info); // gunzip srcfile into dstfile. Returns FALSE on error. -BOOL gunzip_file(const char *srcfile, const char *dstfile); +BOOL gunzip_file(const std::string& srcfile, const std::string& dstfile); // gzip srcfile into dstfile. Returns FALSE on error. -BOOL gzip_file(const char *srcfile, const char *dstfile); +BOOL gzip_file(const std::string& srcfile, const std::string& dstfile); extern LLCPUInfo gSysCPU; diff --git a/linden/indra/llcommon/llthread.cpp b/linden/indra/llcommon/llthread.cpp index 48ebc4b..e07170b 100644 --- a/linden/indra/llcommon/llthread.cpp +++ b/linden/indra/llcommon/llthread.cpp @@ -31,7 +31,7 @@ #include "linden_common.h" #include "llapr.h" -#include "apr-1/apr_portable.h" +#include "apr_portable.h" #include "llthread.h" diff --git a/linden/indra/llcommon/llthread.h b/linden/indra/llcommon/llthread.h index 608b218..9da3134 100644 --- a/linden/indra/llcommon/llthread.h +++ b/linden/indra/llcommon/llthread.h @@ -36,7 +36,7 @@ #include "llapp.h" #include "llmemory.h" -#include "apr-1/apr_thread_cond.h" +#include "apr_thread_cond.h" class LLThread; class LLMutex; diff --git a/linden/indra/llcommon/lltimer.cpp b/linden/indra/llcommon/lltimer.cpp index 25d9897..967570d 100644 --- a/linden/indra/llcommon/lltimer.cpp +++ b/linden/indra/llcommon/lltimer.cpp @@ -429,10 +429,9 @@ BOOL LLTimer::knownBadTimer() // /////////////////////////////////////////////////////////////////////////////// -U32 time_corrected() +time_t time_corrected() { - U32 corrected_time = (U32)time(NULL) + gUTCOffset; - return corrected_time; + return time(NULL) + gUTCOffset; } @@ -452,27 +451,25 @@ BOOL is_daylight_savings() } -struct tm* utc_to_pacific_time(S32 utc_time, BOOL pacific_daylight_time) +struct tm* utc_to_pacific_time(time_t utc_time, BOOL pacific_daylight_time) { - time_t unix_time = (time_t)utc_time; - S32 pacific_offset_hours; if (pacific_daylight_time) { - pacific_offset_hours = -7; + pacific_offset_hours = 7; } else { - pacific_offset_hours = -8; + pacific_offset_hours = 8; } // We subtract off the PST/PDT offset _before_ getting // "UTC" time, because this will handle wrapping around // for 5 AM UTC -> 10 PM PDT of the previous day. - unix_time += pacific_offset_hours * MIN_PER_HOUR * SEC_PER_MIN; + utc_time -= pacific_offset_hours * MIN_PER_HOUR * SEC_PER_MIN; // Internal buffer to PST/PDT (see above) - struct tm* internal_time = gmtime(&unix_time); + struct tm* internal_time = gmtime(&utc_time); /* // Don't do this, this won't correctly tell you if daylight savings is active in CA or not. @@ -486,7 +483,7 @@ struct tm* utc_to_pacific_time(S32 utc_time, BOOL pacific_daylight_time) } -void microsecondsToTimecodeString(U64 current_time, char *tcstring) +void microsecondsToTimecodeString(U64 current_time, std::string& tcstring) { U64 hours; U64 minutes; @@ -504,11 +501,11 @@ void microsecondsToTimecodeString(U64 current_time, char *tcstring) subframes = current_time / (U64)42; subframes %= 100; - sprintf(tcstring,"%3.3d:%2.2d:%2.2d:%2.2d.%2.2d",(int)hours,(int)minutes,(int)seconds,(int)frames,(int)subframes); /* Flawfinder: ignore */ + tcstring = llformat("%3.3d:%2.2d:%2.2d:%2.2d.%2.2d",(int)hours,(int)minutes,(int)seconds,(int)frames,(int)subframes); } -void secondsToTimecodeString(F32 current_time, char *tcstring) +void secondsToTimecodeString(F32 current_time, std::string& tcstring) { microsecondsToTimecodeString((U64)((F64)(SEC_TO_MICROSEC*current_time)), tcstring); } @@ -541,7 +538,7 @@ void LLEventTimer::updateClass() { LLEventTimer* timer = *iter++; F32 et = timer->mEventTimer.getElapsedTimeF32(); - if (et > timer->mPeriod) { + if (timer->mEventTimer.getStarted() && et > timer->mPeriod) { timer->mEventTimer.reset(); if ( timer->tick() ) { diff --git a/linden/indra/llcommon/lltimer.h b/linden/indra/llcommon/lltimer.h index 91b93d6..8d94276 100644 --- a/linden/indra/llcommon/lltimer.h +++ b/linden/indra/llcommon/lltimer.h @@ -35,6 +35,7 @@ #if LL_LINUX || LL_DARWIN #include #endif +#include #include "stdtypes.h" @@ -117,7 +118,35 @@ void ms_sleep(U32 ms); // Returns the correct UTC time in seconds, like time(NULL). // Useful on the viewer, which may have its local clock set wrong. -U32 time_corrected(); +time_t time_corrected(); + +static inline time_t time_min() +{ + if (sizeof(time_t) == 4) + { + return (time_t) INT_MIN; + } else { +#ifdef LLONG_MIN + return (time_t) LLONG_MIN; +#else + return (time_t) LONG_MIN; +#endif + } +} + +static inline time_t time_max() +{ + if (sizeof(time_t) == 4) + { + return (time_t) INT_MAX; + } else { +#ifdef LLONG_MAX + return (time_t) LLONG_MAX; +#else + return (time_t) LONG_MAX; +#endif + } +} // Correction factor used by time_corrected() above. extern S32 gUTCOffset; @@ -131,10 +160,10 @@ BOOL is_daylight_savings(); // S32 utc_time; // utc_time = time_corrected(); // struct tm* internal_time = utc_to_pacific_time(utc_time, gDaylight); -struct tm* utc_to_pacific_time(S32 utc_time, BOOL pacific_daylight_time); +struct tm* utc_to_pacific_time(time_t utc_time, BOOL pacific_daylight_time); -void microsecondsToTimecodeString(U64 current_time, char *tcstring); -void secondsToTimecodeString(F32 current_time, char *tcstring); +void microsecondsToTimecodeString(U64 current_time, std::string& tcstring); +void secondsToTimecodeString(F32 current_time, std::string& tcstring); // class for scheduling a function to be called at a given frequency (approximate, inprecise) class LLEventTimer diff --git a/linden/indra/llcommon/lluri.cpp b/linden/indra/llcommon/lluri.cpp index 7db8f3b..b83036b 100644 --- a/linden/indra/llcommon/lluri.cpp +++ b/linden/indra/llcommon/lluri.cpp @@ -38,7 +38,7 @@ #include "llsd.h" #include -#include "../llmath/lluuid.h" +#include "lluuid.h" // system includes #include diff --git a/linden/indra/llcommon/lluuid.cpp b/linden/indra/llcommon/lluuid.cpp new file mode 100644 index 0000000..7e4eb50 --- /dev/null +++ b/linden/indra/llcommon/lluuid.cpp @@ -0,0 +1,923 @@ +/** + * @file lluuid.cpp + * + * $LicenseInfo:firstyear=2000&license=viewergpl$ + * + * Copyright (c) 2000-2008, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "linden_common.h" + +// We can't use WIN32_LEAN_AND_MEAN here, needs lots of includes. +#if LL_WINDOWS +# undef WIN32_LEAN_AND_MEAN +# include +# include +#endif + +#include "lldefs.h" +#include "llerror.h" + +#include "lluuid.h" +#include "llerror.h" +#include "llrand.h" +#include "llmd5.h" +#include "llstring.h" +#include "lltimer.h" + +const LLUUID LLUUID::null; +const LLTransactionID LLTransactionID::tnull; + +/* + +NOT DONE YET!!! + +static char BASE85_TABLE[] = { + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', + 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', + 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', + 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', + 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', + 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', + 'y', 'z', '!', '#', '$', '%', '&', '(', ')', '*', + '+', '-', ';', '[', '=', '>', '?', '@', '^', '_', + '`', '{', '|', '}', '~', '\0' +}; + + +void encode( char * fiveChars, unsigned int word ) throw( ) +{ +for( int ix = 0; ix < 5; ++ix ) { +fiveChars[4-ix] = encodeTable[ word % 85]; +word /= 85; +} +} + +To decode: +unsigned int decode( char const * fiveChars ) throw( bad_input_data ) +{ +unsigned int ret = 0; +for( int ix = 0; ix < 5; ++ix ) { +char * s = strchr( encodeTable, fiveChars[ ix ] ); +if( s == 0 ) throw bad_input_data(); +ret = ret * 85 + (s-encodeTable); +} +return ret; +} + +void LLUUID::toBase85(char* out) +{ + U32* me = (U32*)&(mData[0]); + for(S32 i = 0; i < 4; ++i) + { + char* o = &out[i*i]; + for(S32 j = 0; j < 5; ++j) + { + o[4-j] = BASE85_TABLE[ me[i] % 85]; + word /= 85; + } + } +} + +unsigned int decode( char const * fiveChars ) throw( bad_input_data ) +{ + unsigned int ret = 0; + for( S32 ix = 0; ix < 5; ++ix ) + { + char * s = strchr( encodeTable, fiveChars[ ix ] ); + ret = ret * 85 + (s-encodeTable); + } + return ret; +} +*/ + +#define LL_USE_JANKY_RANDOM_NUMBER_GENERATOR 0 +#if LL_USE_JANKY_RANDOM_NUMBER_GENERATOR +/** + * @brief a global for + */ +static U64 sJankyRandomSeed(LLUUID::getRandomSeed()); + +/** + * @brief generate a random U32. + */ +U32 janky_fast_random_bytes() +{ + sJankyRandomSeed = U64L(1664525) * sJankyRandomSeed + U64L(1013904223); + return (U32)sJankyRandomSeed; +} + +/** + * @brief generate a random U32 from [0, val) + */ +U32 janky_fast_random_byes_range(U32 val) +{ + sJankyRandomSeed = U64L(1664525) * sJankyRandomSeed + U64L(1013904223); + return (U32)(sJankyRandomSeed) % val; +} + +/** + * @brief generate a random U32 from [0, val) + */ +U32 janky_fast_random_seeded_bytes(U32 seed, U32 val) +{ + seed = U64L(1664525) * (U64)(seed) + U64L(1013904223); + return (U32)(seed) % val; +} +#endif + +// Common to all UUID implementations +void LLUUID::toString(std::string& out) const +{ + out = llformat( + "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x", + (U8)(mData[0]), + (U8)(mData[1]), + (U8)(mData[2]), + (U8)(mData[3]), + (U8)(mData[4]), + (U8)(mData[5]), + (U8)(mData[6]), + (U8)(mData[7]), + (U8)(mData[8]), + (U8)(mData[9]), + (U8)(mData[10]), + (U8)(mData[11]), + (U8)(mData[12]), + (U8)(mData[13]), + (U8)(mData[14]), + (U8)(mData[15])); +} + +// *TODO: deprecate +void LLUUID::toString(char *out) const +{ + std::string buffer; + toString(buffer); + strcpy(out,buffer.c_str()); /* Flawfinder: ignore */ +} + +void LLUUID::toCompressedString(std::string& out) const +{ + char bytes[UUID_BYTES+1]; + memcpy(bytes, mData, UUID_BYTES); /* Flawfinder: ignore */ + bytes[UUID_BYTES] = '\0'; + out.assign(bytes, UUID_BYTES); +} + +// *TODO: deprecate +void LLUUID::toCompressedString(char *out) const +{ + memcpy(out, mData, UUID_BYTES); /* Flawfinder: ignore */ + out[UUID_BYTES] = '\0'; +} + +std::string LLUUID::getString() const +{ + return asString(); +} + +std::string LLUUID::asString() const +{ + std::string str; + toString(str); + return str; +} + +BOOL LLUUID::set(const char* in_string, BOOL emit) +{ + return set(ll_safe_string(in_string)); +} + +BOOL LLUUID::set(const std::string& in_string, BOOL emit) +{ + BOOL broken_format = FALSE; + + // empty strings should make NULL uuid + if (in_string.empty()) + { + setNull(); + return TRUE; + } + + if (in_string.length() != (UUID_STR_LENGTH - 1)) /* Flawfinder: ignore */ + { + // I'm a moron. First implementation didn't have the right UUID format. + // Shouldn't see any of these any more + if (in_string.length() == (UUID_STR_LENGTH - 2)) /* Flawfinder: ignore */ + { + if(emit) + { + llinfos << "Warning! Using broken UUID string format" << llendl; + } + broken_format = TRUE; + } + else + { + // Bad UUID string. Spam as INFO, as most cases we don't care. + if(emit) + { + llinfos << "Bad UUID string: " << in_string << llendl; + } + setNull(); + return FALSE; + } + } + + U8 cur_pos = 0; + S32 i; + for (i = 0; i < UUID_BYTES; i++) + { + if ((i == 4) || (i == 6) || (i == 8) || (i == 10)) + { + cur_pos++; + if (broken_format && (i==10)) + { + // Missing - in the broken format + cur_pos--; + } + } + + mData[i] = 0; + + if ((in_string[cur_pos] >= '0') && (in_string[cur_pos] <= '9')) + { + mData[i] += (U8)(in_string[cur_pos] - '0'); + } + else if ((in_string[cur_pos] >= 'a') && (in_string[cur_pos] <='f')) + { + mData[i] += (U8)(10 + in_string[cur_pos] - 'a'); + } + else if ((in_string[cur_pos] >= 'A') && (in_string[cur_pos] <='F')) + { + mData[i] += (U8)(10 + in_string[cur_pos] - 'A'); + } + else + { + if(emit) + { + llwarns << "Invalid UUID string character" << llendl; + } + setNull(); + return FALSE; + } + + mData[i] = mData[i] << 4; + cur_pos++; + + if ((in_string[cur_pos] >= '0') && (in_string[cur_pos] <= '9')) + { + mData[i] += (U8)(in_string[cur_pos] - '0'); + } + else if ((in_string[cur_pos] >= 'a') && (in_string[cur_pos] <='f')) + { + mData[i] += (U8)(10 + in_string[cur_pos] - 'a'); + } + else if ((in_string[cur_pos] >= 'A') && (in_string[cur_pos] <='F')) + { + mData[i] += (U8)(10 + in_string[cur_pos] - 'A'); + } + else + { + if(emit) + { + llwarns << "Invalid UUID string character" << llendl; + } + setNull(); + return FALSE; + } + cur_pos++; + } + + return TRUE; +} + +BOOL LLUUID::validate(const std::string& in_string) +{ + BOOL broken_format = FALSE; + if (in_string.length() != (UUID_STR_LENGTH - 1)) /* Flawfinder: ignore */ + { + // I'm a moron. First implementation didn't have the right UUID format. + if (in_string.length() == (UUID_STR_LENGTH - 2)) /* Flawfinder: ignore */ + { + broken_format = TRUE; + } + else + { + return FALSE; + } + } + + U8 cur_pos = 0; + for (U32 i = 0; i < 16; i++) + { + if ((i == 4) || (i == 6) || (i == 8) || (i == 10)) + { + cur_pos++; + if (broken_format && (i==10)) + { + // Missing - in the broken format + cur_pos--; + } + } + + if ((in_string[cur_pos] >= '0') && (in_string[cur_pos] <= '9')) + { + } + else if ((in_string[cur_pos] >= 'a') && (in_string[cur_pos] <='f')) + { + } + else if ((in_string[cur_pos] >= 'A') && (in_string[cur_pos] <='F')) + { + } + else + { + return FALSE; + } + + cur_pos++; + + if ((in_string[cur_pos] >= '0') && (in_string[cur_pos] <= '9')) + { + } + else if ((in_string[cur_pos] >= 'a') && (in_string[cur_pos] <='f')) + { + } + else if ((in_string[cur_pos] >= 'A') && (in_string[cur_pos] <='F')) + { + } + else + { + return FALSE; + } + cur_pos++; + } + return TRUE; +} + +const LLUUID& LLUUID::operator^=(const LLUUID& rhs) +{ + U32* me = (U32*)&(mData[0]); + const U32* other = (U32*)&(rhs.mData[0]); + for(S32 i = 0; i < 4; ++i) + { + me[i] = me[i] ^ other[i]; + } + return *this; +} + +LLUUID LLUUID::operator^(const LLUUID& rhs) const +{ + LLUUID id(*this); + id ^= rhs; + return id; +} + +void LLUUID::combine(const LLUUID& other, LLUUID& result) const +{ + LLMD5 md5_uuid; + md5_uuid.update((unsigned char*)mData, 16); + md5_uuid.update((unsigned char*)other.mData, 16); + md5_uuid.finalize(); + md5_uuid.raw_digest(result.mData); +} + +LLUUID LLUUID::combine(const LLUUID &other) const +{ + LLUUID combination; + combine(other, combination); + return combination; +} + +std::ostream& operator<<(std::ostream& s, const LLUUID &uuid) +{ + std::string uuid_str; + uuid.toString(uuid_str); + s << uuid_str; + return s; +} + +std::istream& operator>>(std::istream &s, LLUUID &uuid) +{ + U32 i; + char uuid_str[UUID_STR_LENGTH]; /* Flawfinder: ignore */ + for (i = 0; i < UUID_STR_LENGTH-1; i++) + { + s >> uuid_str[i]; + } + uuid_str[i] = '\0'; + uuid.set(std::string(uuid_str)); + return s; +} + +static void get_random_bytes(void *buf, int nbytes) +{ + int i; + char *cp = (char *) buf; + + // *NOTE: If we are not using the janky generator ll_rand() + // generates at least 3 good bytes of data since it is 0 to + // RAND_MAX. This could be made more efficient by copying all the + // bytes. + for (i=0; i < nbytes; i++) +#if LL_USE_JANKY_RANDOM_NUMBER_GENERATOR + *cp++ = janky_fast_random_bytes() & 0xFF; +#else + *cp++ = ll_rand() & 0xFF; +#endif + return; +} + +#if LL_WINDOWS +typedef struct _ASTAT_ +{ + ADAPTER_STATUS adapt; + NAME_BUFFER NameBuff [30]; +}ASTAT, * PASTAT; + +// static +S32 LLUUID::getNodeID(unsigned char * node_id) +{ + ASTAT Adapter; + NCB Ncb; + UCHAR uRetCode; + LANA_ENUM lenum; + int i; + int retval = 0; + + memset( &Ncb, 0, sizeof(Ncb) ); + Ncb.ncb_command = NCBENUM; + Ncb.ncb_buffer = (UCHAR *)&lenum; + Ncb.ncb_length = sizeof(lenum); + uRetCode = Netbios( &Ncb ); + // printf( "The NCBENUM return code is: 0x%x \n", uRetCode ); + + for(i=0; i < lenum.length ;i++) + { + memset( &Ncb, 0, sizeof(Ncb) ); + Ncb.ncb_command = NCBRESET; + Ncb.ncb_lana_num = lenum.lana[i]; + + uRetCode = Netbios( &Ncb ); + // printf( "The NCBRESET on LANA %d return code is: 0x%x \n", + // lenum.lana[i], uRetCode ); + + memset( &Ncb, 0, sizeof (Ncb) ); + Ncb.ncb_command = NCBASTAT; + Ncb.ncb_lana_num = lenum.lana[i]; + + strcpy( (char *)Ncb.ncb_callname, "* " ); /* Flawfinder: ignore */ + Ncb.ncb_buffer = (unsigned char *)&Adapter; + Ncb.ncb_length = sizeof(Adapter); + + uRetCode = Netbios( &Ncb ); +// printf( "The NCBASTAT on LANA %d return code is: 0x%x \n", +// lenum.lana[i], uRetCode ); + if ( uRetCode == 0 ) + { +// printf( "The Ethernet Number on LANA %d is: %02x%02x%02x%02x%02x%02x\n", +// lenum.lana[i], +// Adapter.adapt.adapter_address[0], +// Adapter.adapt.adapter_address[1], +// Adapter.adapt.adapter_address[2], +// Adapter.adapt.adapter_address[3], +// Adapter.adapt.adapter_address[4], +// Adapter.adapt.adapter_address[5] ); + memcpy(node_id,Adapter.adapt.adapter_address,6); /* Flawfinder: ignore */ + retval = 1; + + } + } + return retval; +} + +#elif LL_DARWIN +// Mac OS X version of the UUID generation code... +/* + * Get an ethernet hardware address, if we can find it... + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// static +S32 LLUUID::getNodeID(unsigned char *node_id) +{ + int i; + unsigned char *a = NULL; + struct ifaddrs *ifap, *ifa; + int rv; + S32 result = 0; + + if ((rv=getifaddrs(&ifap))==-1) + { + return -1; + } + if (ifap == NULL) + { + return -1; + } + + for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) + { +// printf("Interface %s, address family %d, ", ifa->ifa_name, ifa->ifa_addr->sa_family); + for(i=0; i< ifa->ifa_addr->sa_len; i++) + { +// printf("%02X ", (unsigned char)ifa->ifa_addr->sa_data[i]); + } +// printf("\n"); + + if(ifa->ifa_addr->sa_family == AF_LINK) + { + // This is a link-level address + struct sockaddr_dl *lla = (struct sockaddr_dl *)ifa->ifa_addr; + +// printf("\tLink level address, type %02X\n", lla->sdl_type); + + if(lla->sdl_type == IFT_ETHER) + { + // Use the first ethernet MAC in the list. + // For some reason, the macro LLADDR() defined in net/if_dl.h doesn't expand correctly. This is what it would do. + a = (unsigned char *)&((lla)->sdl_data); + a += (lla)->sdl_nlen; + + if (!a[0] && !a[1] && !a[2] && !a[3] && !a[4] && !a[5]) + { + continue; + } + + if (node_id) + { + memcpy(node_id, a, 6); + result = 1; + } + + // We found one. + break; + } + } + } + freeifaddrs(ifap); + + return result; +} + +#else + +// Linux version of the UUID generation code... +/* + * Get the ethernet hardware address, if we can find it... + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#define HAVE_NETINET_IN_H +#ifdef HAVE_NETINET_IN_H +#include +#if LL_SOLARIS +#include +#elif !LL_DARWIN +#include +#endif +#endif + +// static +S32 LLUUID::getNodeID(unsigned char *node_id) +{ + int sd; + struct ifreq ifr, *ifrp; + struct ifconf ifc; + char buf[1024]; + int n, i; + unsigned char *a; + +/* + * BSD 4.4 defines the size of an ifreq to be + * max(sizeof(ifreq), sizeof(ifreq.ifr_name)+ifreq.ifr_addr.sa_len + * However, under earlier systems, sa_len isn't present, so the size is + * just sizeof(struct ifreq) + */ +#ifdef HAVE_SA_LEN +#ifndef max +#define max(a,b) ((a) > (b) ? (a) : (b)) +#endif +#define ifreq_size(i) max(sizeof(struct ifreq),\ + sizeof((i).ifr_name)+(i).ifr_addr.sa_len) +#else +#define ifreq_size(i) sizeof(struct ifreq) +#endif /* HAVE_SA_LEN*/ + + sd = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP); + if (sd < 0) { + return -1; + } + memset(buf, 0, sizeof(buf)); + ifc.ifc_len = sizeof(buf); + ifc.ifc_buf = buf; + if (ioctl (sd, SIOCGIFCONF, (char *)&ifc) < 0) { + close(sd); + return -1; + } + n = ifc.ifc_len; + for (i = 0; i < n; i+= ifreq_size(*ifr) ) { + ifrp = (struct ifreq *)((char *) ifc.ifc_buf+i); + strncpy(ifr.ifr_name, ifrp->ifr_name, IFNAMSIZ); /* Flawfinder: ignore */ +#ifdef SIOCGIFHWADDR + if (ioctl(sd, SIOCGIFHWADDR, &ifr) < 0) + continue; + a = (unsigned char *) &ifr.ifr_hwaddr.sa_data; +#else +#ifdef SIOCGENADDR + if (ioctl(sd, SIOCGENADDR, &ifr) < 0) + continue; + a = (unsigned char *) ifr.ifr_enaddr; +#else + /* + * XXX we don't have a way of getting the hardware + * address + */ + close(sd); + return 0; +#endif /* SIOCGENADDR */ +#endif /* SIOCGIFHWADDR */ + if (!a[0] && !a[1] && !a[2] && !a[3] && !a[4] && !a[5]) + continue; + if (node_id) { + memcpy(node_id, a, 6); /* Flawfinder: ignore */ + close(sd); + return 1; + } + } + close(sd); + return 0; +} + +#endif + +S32 LLUUID::cmpTime(uuid_time_t *t1, uuid_time_t *t2) +{ + // Compare two time values. + + if (t1->high < t2->high) return -1; + if (t1->high > t2->high) return 1; + if (t1->low < t2->low) return -1; + if (t1->low > t2->low) return 1; + return 0; +} + +void LLUUID::getSystemTime(uuid_time_t *timestamp) +{ + // Get system time with 100ns precision. Time is since Oct 15, 1582. +#if LL_WINDOWS + ULARGE_INTEGER time; + GetSystemTimeAsFileTime((FILETIME *)&time); + // NT keeps time in FILETIME format which is 100ns ticks since + // Jan 1, 1601. UUIDs use time in 100ns ticks since Oct 15, 1582. + // The difference is 17 Days in Oct + 30 (Nov) + 31 (Dec) + // + 18 years and 5 leap days. + time.QuadPart += + (unsigned __int64) (1000*1000*10) // seconds + * (unsigned __int64) (60 * 60 * 24) // days + * (unsigned __int64) (17+30+31+365*18+5); // # of days + + timestamp->high = time.HighPart; + timestamp->low = time.LowPart; +#else + struct timeval tp; + gettimeofday(&tp, 0); + + // Offset between UUID formatted times and Unix formatted times. + // UUID UTC base time is October 15, 1582. + // Unix base time is January 1, 1970. + U64 uuid_time = ((U64)tp.tv_sec * 10000000) + (tp.tv_usec * 10) + + U64L(0x01B21DD213814000); + timestamp->high = (U32) (uuid_time >> 32); + timestamp->low = (U32) (uuid_time & 0xFFFFFFFF); +#endif +} + +void LLUUID::getCurrentTime(uuid_time_t *timestamp) +{ + // Get current time as 60 bit 100ns ticks since whenever. + // Compensate for the fact that real clock resolution is less + // than 100ns. + + const U32 uuids_per_tick = 1024; + + static uuid_time_t time_last; + static U32 uuids_this_tick; + static BOOL init = FALSE; + + if (!init) { + getSystemTime(&time_last); + uuids_this_tick = uuids_per_tick; + init = TRUE; + } + + uuid_time_t time_now = {0,0}; + + while (1) { + getSystemTime(&time_now); + + // if clock reading changed since last UUID generated + if (cmpTime(&time_last, &time_now)) { + // reset count of uuid's generated with this clock reading + uuids_this_tick = 0; + break; + } + if (uuids_this_tick < uuids_per_tick) { + uuids_this_tick++; + break; + } + // going too fast for our clock; spin + } + + time_last = time_now; + + if (uuids_this_tick != 0) { + if (time_now.low & 0x80000000) { + time_now.low += uuids_this_tick; + if (!(time_now.low & 0x80000000)) + time_now.high++; + } else + time_now.low += uuids_this_tick; + } + + timestamp->high = time_now.high; + timestamp->low = time_now.low; +} + +void LLUUID::generate() +{ + // Create a UUID. + uuid_time_t timestamp; + + static unsigned char node_id[6]; /* Flawfinder: ignore */ + static int has_init = 0; + + // Create a UUID. + static uuid_time_t time_last = {0,0}; + static U16 clock_seq = 0; +#if LL_USE_JANKY_RANDOM_NUMBER_GENERATOR + static U32 seed = 0L; // dummy seed. reset it below +#endif + if (!has_init) + { + if (getNodeID(node_id) <= 0) + { + get_random_bytes(node_id, 6); + /* + * Set multicast bit, to prevent conflicts + * with IEEE 802 addresses obtained from + * network cards + */ + node_id[0] |= 0x80; + } + + getCurrentTime(&time_last); +#if LL_USE_JANKY_RANDOM_NUMBER_GENERATOR + seed = time_last.low; +#endif + +#if LL_USE_JANKY_RANDOM_NUMBER_GENERATOR + clock_seq = (U16)janky_fast_random_seeded_bytes(seed, 65536); +#else + clock_seq = (U16)ll_rand(65536); +#endif + has_init = 1; + } + + // get current time + getCurrentTime(×tamp); + + // if clock went backward change clockseq + if (cmpTime(×tamp, &time_last) == -1) { + clock_seq = (clock_seq + 1) & 0x3FFF; + if (clock_seq == 0) clock_seq++; + } + + memcpy(mData+10, node_id, 6); /* Flawfinder: ignore */ + U32 tmp; + tmp = timestamp.low; + mData[3] = (unsigned char) tmp; + tmp >>= 8; + mData[2] = (unsigned char) tmp; + tmp >>= 8; + mData[1] = (unsigned char) tmp; + tmp >>= 8; + mData[0] = (unsigned char) tmp; + + tmp = (U16) timestamp.high; + mData[5] = (unsigned char) tmp; + tmp >>= 8; + mData[4] = (unsigned char) tmp; + + tmp = (timestamp.high >> 16) | 0x1000; + mData[7] = (unsigned char) tmp; + tmp >>= 8; + mData[6] = (unsigned char) tmp; + + tmp = clock_seq; + mData[9] = (unsigned char) tmp; + tmp >>= 8; + mData[8] = (unsigned char) tmp; + + LLMD5 md5_uuid; + + md5_uuid.update(mData,16); + md5_uuid.finalize(); + md5_uuid.raw_digest(mData); + + time_last = timestamp; +} + +void LLUUID::generate(const std::string& hash_string) +{ + LLMD5 md5_uuid((U8*)hash_string.c_str()); + md5_uuid.raw_digest(mData); +} + +U32 LLUUID::getRandomSeed() +{ + static unsigned char seed[16]; /* Flawfinder: ignore */ + + getNodeID(&seed[0]); + seed[6]='\0'; + seed[7]='\0'; + getSystemTime((uuid_time_t *)(&seed[8])); + + LLMD5 md5_seed; + + md5_seed.update(seed,16); + md5_seed.finalize(); + md5_seed.raw_digest(seed); + + return(*(U32 *)seed); +} + +BOOL LLUUID::parseUUID(const std::string& buf, LLUUID* value) +{ + if( buf.empty() || value == NULL) + { + return FALSE; + } + + std::string temp( buf ); + LLStringUtil::trim(temp); + if( LLUUID::validate( temp ) ) + { + value->set( temp ); + return TRUE; + } + return FALSE; +} + +LLAssetID LLTransactionID::makeAssetID(const LLUUID& session) const +{ + LLAssetID result; + if (isNull()) + { + result.setNull(); + } + else + { + combine(session, result); + } + return result; +} diff --git a/linden/indra/llcommon/lluuid.h b/linden/indra/llcommon/lluuid.h new file mode 100644 index 0000000..3b057fb --- /dev/null +++ b/linden/indra/llcommon/lluuid.h @@ -0,0 +1,331 @@ +/** + * @file lluuid.h + * + * $LicenseInfo:firstyear=2000&license=viewergpl$ + * + * Copyright (c) 2000-2008, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LL_LLUUID_H +#define LL_LLUUID_H + +#include +#include +#include "stdtypes.h" + +const S32 UUID_BYTES = 16; +const S32 UUID_WORDS = 4; +const S32 UUID_STR_LENGTH = 37; // actually wrong, should be 36 and use size below +const S32 UUID_STR_SIZE = 37; +const S32 UUID_BASE85_LENGTH = 21; // including the trailing NULL. + +struct uuid_time_t { + U32 high; + U32 low; + }; + +class LLUUID +{ +public: + // + // CREATORS + // + LLUUID(); + explicit LLUUID(const char *in_string); // Convert from string. + explicit LLUUID(const std::string& in_string); // Convert from string. + LLUUID(const LLUUID &in); + LLUUID &operator=(const LLUUID &rhs); + + ~LLUUID(); + + // + // MANIPULATORS + // + void generate(); // Generate a new UUID + void generate(const std::string& stream); //Generate a new UUID based on hash of input stream + BOOL set(const char *in_string, BOOL emit = TRUE); // Convert from string, if emit is FALSE, do not emit warnings + BOOL set(const std::string& in_string, BOOL emit = TRUE); // Convert from string, if emit is FALSE, do not emit warnings + void setNull(); // Faster than setting to LLUUID::null. + + S32 cmpTime(uuid_time_t *t1, uuid_time_t *t2); + static void getSystemTime(uuid_time_t *timestamp); + void getCurrentTime(uuid_time_t *timestamp); + + // + // ACCESSORS + // + BOOL isNull() const; // Faster than comparing to LLUUID::null. + BOOL notNull() const; // Faster than comparing to LLUUID::null. + // JC: This is dangerous. It allows UUIDs to be cast automatically + // to integers, among other things. Use isNull() or notNull(). + // operator bool() const; + + // JC: These must return real bool's (not BOOLs) or else use of the STL + // will generate bool-to-int performance warnings. + bool operator==(const LLUUID &rhs) const; + bool operator!=(const LLUUID &rhs) const; + bool operator<(const LLUUID &rhs) const; + bool operator>(const LLUUID &rhs) const; + + // xor functions. Useful since any two random uuids xored together + // will yield a determinate third random unique id that can be + // used as a key in a single uuid that represents 2. + const LLUUID& operator^=(const LLUUID& rhs); + LLUUID operator^(const LLUUID& rhs) const; + + // similar to functions above, but not invertible + // yields a third random UUID that can be reproduced from the two inputs + // but which, given the result and one of the inputs can't be used to + // deduce the other input + LLUUID combine(const LLUUID& other) const; + void combine(const LLUUID& other, LLUUID& result) const; + + friend std::ostream& operator<<(std::ostream& s, const LLUUID &uuid); + friend std::istream& operator>>(std::istream& s, LLUUID &uuid); + + void toString(char *out) const; // Does not allocate memory, needs 36 characters (including \0) + void toString(std::string& out) const; + void toCompressedString(char *out) const; // Does not allocate memory, needs 17 characters (including \0) + void toCompressedString(std::string& out) const; + + std::string asString() const; + std::string getString() const; + + U16 getCRC16() const; + U32 getCRC32() const; + + static BOOL validate(const std::string& in_string); // Validate that the UUID string is legal. + + static const LLUUID null; + + static U32 getRandomSeed(); + static S32 getNodeID(unsigned char * node_id); + + static BOOL parseUUID(const std::string& buf, LLUUID* value); + + U8 mData[UUID_BYTES]; +}; + + +// Construct +inline LLUUID::LLUUID() +{ + setNull(); +} + + +// Faster than copying from memory +inline void LLUUID::setNull() +{ + U32 *word = (U32 *)mData; + word[0] = 0; + word[1] = 0; + word[2] = 0; + word[3] = 0; +} + + +// Compare +inline bool LLUUID::operator==(const LLUUID& rhs) const +{ + U32 *tmp = (U32 *)mData; + U32 *rhstmp = (U32 *)rhs.mData; + // Note: binary & to avoid branching + return + (tmp[0] == rhstmp[0]) & + (tmp[1] == rhstmp[1]) & + (tmp[2] == rhstmp[2]) & + (tmp[3] == rhstmp[3]); +} + + +inline bool LLUUID::operator!=(const LLUUID& rhs) const +{ + U32 *tmp = (U32 *)mData; + U32 *rhstmp = (U32 *)rhs.mData; + // Note: binary | to avoid branching + return + (tmp[0] != rhstmp[0]) | + (tmp[1] != rhstmp[1]) | + (tmp[2] != rhstmp[2]) | + (tmp[3] != rhstmp[3]); +} + +/* +// JC: This is dangerous. It allows UUIDs to be cast automatically +// to integers, among other things. Use isNull() or notNull(). +inline LLUUID::operator bool() const +{ + U32 *word = (U32 *)mData; + return (word[0] | word[1] | word[2] | word[3]) > 0; +} +*/ + +inline BOOL LLUUID::notNull() const +{ + U32 *word = (U32 *)mData; + return (word[0] | word[1] | word[2] | word[3]) > 0; +} + +// Faster than == LLUUID::null because doesn't require +// as much memory access. +inline BOOL LLUUID::isNull() const +{ + U32 *word = (U32 *)mData; + // If all bits are zero, return !0 == TRUE + return !(word[0] | word[1] | word[2] | word[3]); +} + +// Copy constructor +inline LLUUID::LLUUID(const LLUUID& rhs) +{ + U32 *tmp = (U32 *)mData; + U32 *rhstmp = (U32 *)rhs.mData; + tmp[0] = rhstmp[0]; + tmp[1] = rhstmp[1]; + tmp[2] = rhstmp[2]; + tmp[3] = rhstmp[3]; +} + +inline LLUUID::~LLUUID() +{ +} + +// Assignment +inline LLUUID& LLUUID::operator=(const LLUUID& rhs) +{ + // No need to check the case where this==&rhs. The branch is slower than the write. + U32 *tmp = (U32 *)mData; + U32 *rhstmp = (U32 *)rhs.mData; + tmp[0] = rhstmp[0]; + tmp[1] = rhstmp[1]; + tmp[2] = rhstmp[2]; + tmp[3] = rhstmp[3]; + + return *this; +} + + +inline LLUUID::LLUUID(const char *in_string) +{ + if (!in_string || in_string[0] == 0) + { + setNull(); + return; + } + + set(in_string); +} + +inline LLUUID::LLUUID(const std::string& in_string) +{ + if (in_string.empty()) + { + setNull(); + return; + } + + set(in_string); +} + +// IW: DON'T "optimize" these w/ U32s or you'll scoogie the sort order +// IW: this will make me very sad +inline bool LLUUID::operator<(const LLUUID &rhs) const +{ + U32 i; + for( i = 0; i < (UUID_BYTES - 1); i++ ) + { + if( mData[i] != rhs.mData[i] ) + { + return (mData[i] < rhs.mData[i]); + } + } + return (mData[UUID_BYTES - 1] < rhs.mData[UUID_BYTES - 1]); +} + +inline bool LLUUID::operator>(const LLUUID &rhs) const +{ + U32 i; + for( i = 0; i < (UUID_BYTES - 1); i++ ) + { + if( mData[i] != rhs.mData[i] ) + { + return (mData[i] > rhs.mData[i]); + } + } + return (mData[UUID_BYTES - 1] > rhs.mData[UUID_BYTES - 1]); +} + +inline U16 LLUUID::getCRC16() const +{ + // A UUID is 16 bytes, or 8 shorts. + U16 *short_data = (U16*)mData; + U16 out = 0; + out += short_data[0]; + out += short_data[1]; + out += short_data[2]; + out += short_data[3]; + out += short_data[4]; + out += short_data[5]; + out += short_data[6]; + out += short_data[7]; + return out; +} + +inline U32 LLUUID::getCRC32() const +{ + U32 *tmp = (U32*)mData; + return tmp[0] + tmp[1] + tmp[2] + tmp[3]; +} + + +// Helper structure for ordering lluuids in stl containers. +// eg: std::map widget_map; +struct lluuid_less +{ + bool operator()(const LLUUID& lhs, const LLUUID& rhs) const + { + return (lhs < rhs) ? true : false; + } +}; + +typedef std::set uuid_list_t; + +/* + * Sub-classes for keeping transaction IDs and asset IDs + * straight. + */ +typedef LLUUID LLAssetID; + +class LLTransactionID : public LLUUID +{ +public: + LLTransactionID() : LLUUID() { } + + static const LLTransactionID tnull; + LLAssetID makeAssetID(const LLUUID& session) const; +}; + +#endif diff --git a/linden/indra/llcommon/llversionserver.h b/linden/indra/llcommon/llversionserver.h index e3ceadf..0b88ce8 100644 --- a/linden/indra/llcommon/llversionserver.h +++ b/linden/indra/llcommon/llversionserver.h @@ -33,9 +33,9 @@ #define LL_LLVERSIONSERVER_H const S32 LL_VERSION_MAJOR = 1; -const S32 LL_VERSION_MINOR = 21; -const S32 LL_VERSION_PATCH = 1; -const S32 LL_VERSION_BUILD = 86526; +const S32 LL_VERSION_MINOR = 24; +const S32 LL_VERSION_PATCH = 0; +const S32 LL_VERSION_BUILD = 93453; const char * const LL_CHANNEL = "Second Life Server"; diff --git a/linden/indra/llcommon/llversionviewer.h b/linden/indra/llcommon/llversionviewer.h index 9b3cf80..4820f68 100644 --- a/linden/indra/llcommon/llversionviewer.h +++ b/linden/indra/llcommon/llversionviewer.h @@ -33,8 +33,8 @@ #define LL_LLVERSIONVIEWER_H const S32 LL_VERSION_MAJOR = 1; -const S32 LL_VERSION_MINOR = 20; -const S32 LL_VERSION_PATCH = 15; +const S32 LL_VERSION_MINOR = 21; +const S32 LL_VERSION_PATCH = 0; const S32 LL_VERSION_BUILD = 0; const char * const LL_CHANNEL = "Second Life Release"; diff --git a/linden/indra/llcommon/metapropertyt.h b/linden/indra/llcommon/metapropertyt.h index 5c25ec4..73c2a7a 100644 --- a/linden/indra/llcommon/metapropertyt.h +++ b/linden/indra/llcommon/metapropertyt.h @@ -86,13 +86,6 @@ inline const LLReflective* LLMetaPropertyT::get(const LLReflective* } template <> -inline const LLReflective* LLMetaPropertyT::get(const LLReflective* object) const -{ - checkObjectClass(object); - return NULL; -} - -template <> inline const LLReflective* LLMetaPropertyT::get(const LLReflective* object) const { checkObjectClass(object); @@ -112,12 +105,6 @@ inline LLSD LLMetaPropertyT::getLLSD(const LLReflective* object) co } template <> -inline LLSD LLMetaPropertyT::getLLSD(const LLReflective* object) const -{ - return *(getProperty(object)); -} - -template <> inline LLSD LLMetaPropertyT::getLLSD(const LLReflective* object) const { return *(getProperty(object)); diff --git a/linden/indra/llcommon/roles_constants.h b/linden/indra/llcommon/roles_constants.h index 956a9de..ee2986b 100644 --- a/linden/indra/llcommon/roles_constants.h +++ b/linden/indra/llcommon/roles_constants.h @@ -143,11 +143,18 @@ const U64 GP_NOTICES_RECEIVE = 0x1LL << 43; // Receive Notices and View Notice const U64 GP_PROPOSAL_START = 0x1LL << 44; // Start Proposal const U64 GP_PROPOSAL_VOTE = 0x1LL << 45; // Vote on Proposal +// Group chat moderation related +const U64 GP_SESSION_JOIN = 0x1LL << 16; //can join session +const U64 GP_SESSION_VOICE = 0x1LL << 27; //can hear/talk +const U64 GP_SESSION_MODERATOR = 0x1LL << 37; //can mute people's session + const U64 GP_DEFAULT_MEMBER = GP_ACCOUNTING_ACCOUNTABLE | GP_LAND_ALLOW_SET_HOME | GP_NOTICES_RECEIVE | GP_PROPOSAL_START | GP_PROPOSAL_VOTE + | GP_SESSION_JOIN + | GP_SESSION_VOICE ; const U64 GP_DEFAULT_OFFICER = GP_ACCOUNTING_ACCOUNTABLE @@ -188,5 +195,8 @@ const U64 GP_DEFAULT_OFFICER = GP_ACCOUNTING_ACCOUNTABLE | GP_PROPOSAL_VOTE | GP_ROLE_ASSIGN_MEMBER_LIMITED | GP_ROLE_PROPERTIES + | GP_SESSION_MODERATOR + | GP_SESSION_JOIN + | GP_SESSION_VOICE ; #endif diff --git a/linden/indra/llcommon/stdtypes.h b/linden/indra/llcommon/stdtypes.h index c1f5303..44f67f2 100644 --- a/linden/indra/llcommon/stdtypes.h +++ b/linden/indra/llcommon/stdtypes.h @@ -31,6 +31,8 @@ #ifndef LL_STDTYPES_H #define LL_STDTYPES_H +#include + typedef signed char S8; typedef unsigned char U8; typedef signed short S16; diff --git a/linden/indra/llcommon/u64.cpp b/linden/indra/llcommon/u64.cpp index bbeed9f..5aebdb3 100644 --- a/linden/indra/llcommon/u64.cpp +++ b/linden/indra/llcommon/u64.cpp @@ -34,10 +34,10 @@ #include "u64.h" -U64 str_to_U64(const char *str) +U64 str_to_U64(const std::string& str) { U64 result = 0; - const char *aptr = strpbrk(str,"0123456789"); + const char *aptr = strpbrk(str.c_str(),"0123456789"); if (!aptr) { @@ -54,8 +54,9 @@ U64 str_to_U64(const char *str) } -char* U64_to_str(U64 value, char* result, S32 result_size) -{ +std::string U64_to_str(U64 value) +{ + std::string res; U32 part1,part2,part3; part3 = (U32)(value % (U64)10000000); @@ -70,31 +71,26 @@ char* U64_to_str(U64 value, char* result, S32 result_size) if (part1) { - snprintf( /* Flawfinder: ignore */ - result, - result_size, - "%u%07u%07u", - part1,part2,part3); + res = llformat("%u%07u%07u",part1,part2,part3); } else if (part2) { - snprintf( /* Flawfinder: ignore */ - result, - result_size, - "%u%07u", - part2,part3); + res = llformat("%u%07u",part2,part3); } else { - snprintf( /* Flawfinder: ignore */ - result, - result_size, - "%u", - part3); + res = llformat("%u",part3); } - return (result); + return res; } +char* U64_to_str(U64 value, char* result, S32 result_size) +{ + std::string res = U64_to_str(value); + LLStringUtil::copy(result, res.c_str(), result_size); + return result; +} + F64 U64_to_F64(const U64 value) { S64 top_bits = (S64)(value >> 1); diff --git a/linden/indra/llcommon/u64.h b/linden/indra/llcommon/u64.h index ab06836..3d45fc3 100644 --- a/linden/indra/llcommon/u64.h +++ b/linden/indra/llcommon/u64.h @@ -38,7 +38,14 @@ * @param str The string to parse. * @return Returns the first U64 value found in the string or 0 on failure. */ -U64 str_to_U64(const char* str); +U64 str_to_U64(const std::string& str); + +/** + * @brief Given a U64 value, return a printable representation. + * @param value The U64 to turn into a printable character array. + * @return Returns the result string. + */ +std::string U64_to_str(U64 value); /** * @brief Given a U64 value, return a printable representation. -- cgit v1.1