diff options
Diffstat (limited to 'indra/llcommon')
-rw-r--r-- | indra/llcommon/llassettype.cpp | 3 | ||||
-rw-r--r-- | indra/llcommon/llassettype.h | 3 | ||||
-rw-r--r-- | indra/llcommon/llchat.h | 2 | ||||
-rw-r--r-- | indra/llcommon/lldefs.h | 8 | ||||
-rw-r--r-- | indra/llcommon/llerror.cpp | 10 | ||||
-rw-r--r-- | indra/llcommon/llerror.h | 2 | ||||
-rw-r--r-- | indra/llcommon/llmemory.cpp | 19 | ||||
-rw-r--r-- | indra/llcommon/llmemory.h | 55 | ||||
-rw-r--r-- | indra/llcommon/llstring.cpp | 107 | ||||
-rw-r--r-- | indra/llcommon/llstring.h | 22 | ||||
-rw-r--r-- | indra/llcommon/lluri.cpp | 3 | ||||
-rw-r--r-- | indra/llcommon/lluuid.cpp | 162 | ||||
-rw-r--r-- | indra/llcommon/tests/llerror_test.cpp | 9 |
13 files changed, 303 insertions, 102 deletions
diff --git a/indra/llcommon/llassettype.cpp b/indra/llcommon/llassettype.cpp index e19f8b0454..476a23ec64 100644 --- a/indra/llcommon/llassettype.cpp +++ b/indra/llcommon/llassettype.cpp @@ -99,8 +99,9 @@ LLAssetDictionary::LLAssetDictionary() addEntry(LLAssetType::AT_LINK, new AssetEntry("LINK", "link", "sym link", false, false, true)); addEntry(LLAssetType::AT_LINK_FOLDER, new AssetEntry("FOLDER_LINK", "link_f", "sym folder link", false, false, true)); - +#if LL_MESH_ENABLED addEntry(LLAssetType::AT_MESH, new AssetEntry("MESH", "mesh", "mesh", false, false, false)); +#endif addEntry(LLAssetType::AT_NONE, new AssetEntry("NONE", "-1", NULL, FALSE, FALSE, FALSE)); diff --git a/indra/llcommon/llassettype.h b/indra/llcommon/llassettype.h index 90cd03c433..ebc43134cb 100644 --- a/indra/llcommon/llassettype.h +++ b/indra/llcommon/llassettype.h @@ -114,9 +114,10 @@ public: AT_LINK_FOLDER = 25, // Inventory folder link - +#if LL_MESH_ENABLED AT_MESH = 49, // Mesh data in our proprietary SLM format +#endif AT_COUNT = 50, diff --git a/indra/llcommon/llchat.h b/indra/llcommon/llchat.h index f1b9091298..63cce24005 100644 --- a/indra/llcommon/llchat.h +++ b/indra/llcommon/llchat.h @@ -82,6 +82,7 @@ public: mFromName(), mFromID(), mNotifId(), + mOwnerID(), mSourceType(CHAT_SOURCE_AGENT), mChatType(CHAT_TYPE_NORMAL), mAudible(CHAT_AUDIBLE_FULLY), @@ -98,6 +99,7 @@ public: std::string mFromName; // agent or object name LLUUID mFromID; // agent id or object id LLUUID mNotifId; + LLUUID mOwnerID; EChatSourceType mSourceType; EChatType mChatType; EChatAudible mAudible; diff --git a/indra/llcommon/lldefs.h b/indra/llcommon/lldefs.h index f3b5ca361f..10e6cb34bf 100644 --- a/indra/llcommon/lldefs.h +++ b/indra/llcommon/lldefs.h @@ -242,5 +242,13 @@ inline LLDATATYPE llclampb(const LLDATATYPE& a) return llmin(llmax(a, (LLDATATYPE)0), (LLDATATYPE)255); } +template <class LLDATATYPE> +inline void llswap(LLDATATYPE& lhs, LLDATATYPE& rhs) +{ + LLDATATYPE tmp = lhs; + lhs = rhs; + rhs = tmp; +} + #endif // LL_LLDEFS_H diff --git a/indra/llcommon/llerror.cpp b/indra/llcommon/llerror.cpp index 41ff5849f4..d06d6baf85 100644 --- a/indra/llcommon/llerror.cpp +++ b/indra/llcommon/llerror.cpp @@ -954,7 +954,12 @@ namespace LLError std::string class_name = className(site.mClassInfo); std::string function_name = functionName(site.mFunction); +#if LL_LINUX + // gross, but typeid comparison seems to always fail here with gcc4.1 + if (0 != strcmp(site.mClassInfo.name(), typeid(NoClassInfo).name())) +#else if (site.mClassInfo != typeid(NoClassInfo)) +#endif // LL_LINUX { function_name = class_name + "::" + function_name; } @@ -1079,7 +1084,12 @@ namespace LLError #if LL_WINDOWS // DevStudio: __FUNCTION__ already includes the full class name #else + #if LL_LINUX + // gross, but typeid comparison seems to always fail here with gcc4.1 + if (0 != strcmp(site.mClassInfo.name(), typeid(NoClassInfo).name())) + #else if (site.mClassInfo != typeid(NoClassInfo)) + #endif // LL_LINUX { prefix << className(site.mClassInfo) << "::"; } diff --git a/indra/llcommon/llerror.h b/indra/llcommon/llerror.h index 09812de2b8..e64ee5e081 100644 --- a/indra/llcommon/llerror.h +++ b/indra/llcommon/llerror.h @@ -179,7 +179,7 @@ namespace LLError { return s; } // used to indicate the end of a message - class NoClassInfo { }; + class LL_COMMON_API NoClassInfo { }; // used to indicate no class info known for logging //LLCallStacks keeps track of call stacks and output the call stacks to log file diff --git a/indra/llcommon/llmemory.cpp b/indra/llcommon/llmemory.cpp index 2a8015e26d..5c6ca30cdd 100644 --- a/indra/llcommon/llmemory.cpp +++ b/indra/llcommon/llmemory.cpp @@ -73,25 +73,6 @@ void LLMemory::freeReserve() reserveMem = NULL; } -void* ll_allocate (size_t size) -{ - if (size == 0) - { - llwarns << "Null allocation" << llendl; - } - void *p = malloc(size); - if (p == NULL) - { - LLMemory::freeReserve(); - llerrs << "Out of memory Error" << llendl; - } - return p; -} - -void ll_release (void *p) -{ - free(p); -} //---------------------------------------------------------------------------- diff --git a/indra/llcommon/llmemory.h b/indra/llcommon/llmemory.h index 1c6f64dd8b..1c8c91f57e 100644 --- a/indra/llcommon/llmemory.h +++ b/indra/llcommon/llmemory.h @@ -32,14 +32,59 @@ #ifndef LLMEMORY_H #define LLMEMORY_H +#include <stdlib.h> +inline void* ll_aligned_malloc_16(size_t size) // returned hunk MUST be freed with ll_aligned_free_16(). +{ +#if defined(LL_WINDOWS) + return _mm_malloc(size, 16); +#elif defined(LL_DARWIN) + return malloc(size); // default osx malloc is 16 byte aligned. +#else + void *rtn; + if (LL_LIKELY(0 == posix_memalign(&rtn, 16, size))) + return rtn; + else // bad alignment requested, or out of memory + return NULL; +#endif +} -extern S32 gTotalDAlloc; -extern S32 gTotalDAUse; -extern S32 gDACount; +inline void ll_aligned_free_16(void *p) +{ +#if defined(LL_WINDOWS) + _mm_free(p); +#elif defined(LL_DARWIN) + return free(p); +#else + free(p); // posix_memalign() is compatible with heap deallocator +#endif +} -extern void* ll_allocate (size_t size); -extern void ll_release (void *p); +inline void* ll_aligned_malloc_32(size_t size) // returned hunk MUST be freed with ll_aligned_free_32(). +{ +#if defined(LL_WINDOWS) + return _mm_malloc(size, 32); +#elif defined(LL_DARWIN) +# error implement me. +#else + void *rtn; + if (LL_LIKELY(0 == posix_memalign(&rtn, 32, size))) + return rtn; + else // bad alignment requested, or out of memory + return NULL; +#endif +} + +inline void ll_aligned_free_32(void *p) +{ +#if defined(LL_WINDOWS) + _mm_free(p); +#elif defined(LL_DARWIN) +# error implement me. +#else + free(p); // posix_memalign() is compatible with heap deallocator +#endif +} class LL_COMMON_API LLMemory { diff --git a/indra/llcommon/llstring.cpp b/indra/llcommon/llstring.cpp index b5a73ec1d1..f14d947734 100644 --- a/indra/llcommon/llstring.cpp +++ b/indra/llcommon/llstring.cpp @@ -676,6 +676,17 @@ long LLStringOps::sLocalTimeOffset = 0; bool LLStringOps::sPacificDaylightTime = 0; std::map<std::string, std::string> LLStringOps::datetimeToCodes; +std::vector<std::string> LLStringOps::sWeekDayList; +std::vector<std::string> LLStringOps::sWeekDayShortList; +std::vector<std::string> LLStringOps::sMonthList; +std::vector<std::string> LLStringOps::sMonthShortList; + + +std::string LLStringOps::sDayFormat; +std::string LLStringOps::sAM; +std::string LLStringOps::sPM; + + S32 LLStringOps::collate(const llwchar* a, const llwchar* b) { #if LL_WINDOWS @@ -724,6 +735,50 @@ void LLStringOps::setupDatetimeInfo (bool daylight) datetimeToCodes["timezone"] = "%Z"; // PST } +void tokenizeStringToArray(const std::string& data, std::vector<std::string>& output) +{ + output.clear(); + size_t length = data.size(); + + // tokenize it and put it in the array + std::string cur_word; + for(size_t i = 0; i < length; ++i) + { + if(data[i] == ':') + { + output.push_back(cur_word); + cur_word.clear(); + } + else + { + cur_word.append(1, data[i]); + } + } + output.push_back(cur_word); +} + +void LLStringOps::setupWeekDaysNames(const std::string& data) +{ + tokenizeStringToArray(data,sWeekDayList); +} +void LLStringOps::setupWeekDaysShortNames(const std::string& data) +{ + tokenizeStringToArray(data,sWeekDayShortList); +} +void LLStringOps::setupMonthNames(const std::string& data) +{ + tokenizeStringToArray(data,sMonthList); +} +void LLStringOps::setupMonthShortNames(const std::string& data) +{ + tokenizeStringToArray(data,sMonthShortList); +} +void LLStringOps::setupDayFormat(const std::string& data) +{ + sDayFormat = data; +} + + std::string LLStringOps::getDatetimeCode (std::string key) { std::map<std::string, std::string>::iterator iter; @@ -819,6 +874,10 @@ namespace LLStringFn //////////////////////////////////////////////////////////// +// Forward specialization of LLStringUtil::format before use in LLStringUtil::formatDatetime. +template<> +S32 LLStringUtil::format(std::string& s, const format_map_t& substitutions); + //static template<> void LLStringUtil::getTokens(const std::string& instr, std::vector<std::string >& tokens, const std::string& delims) @@ -998,7 +1057,53 @@ bool LLStringUtil::formatDatetime(std::string& replacement, std::string token, } return true; } - replacement = datetime.toHTTPDateString(code); + + //EXT-7013 + //few codes are not suppotred by strtime function (example - weekdays for Japanise) + //so use predefined ones + + //if sWeekDayList is not empty than current locale doesn't support + //weekday name. + time_t loc_seconds = (time_t) secFromEpoch; + if(LLStringOps::sWeekDayList.size() == 7 && code == "%A") + { + struct tm * gmt = gmtime (&loc_seconds); + replacement = LLStringOps::sWeekDayList[gmt->tm_wday]; + } + else if(LLStringOps::sWeekDayShortList.size() == 7 && code == "%a") + { + struct tm * gmt = gmtime (&loc_seconds); + replacement = LLStringOps::sWeekDayShortList[gmt->tm_wday]; + } + else if(LLStringOps::sMonthList.size() == 12 && code == "%B") + { + struct tm * gmt = gmtime (&loc_seconds); + replacement = LLStringOps::sWeekDayList[gmt->tm_mon]; + } + else if( !LLStringOps::sDayFormat.empty() && code == "%d" ) + { + struct tm * gmt = gmtime (&loc_seconds); + LLStringUtil::format_map_t args; + args["[MDAY]"] = llformat ("%d", gmt->tm_mday); + replacement = LLStringOps::sDayFormat; + LLStringUtil::format(replacement, args); + } + else if( !LLStringOps::sAM.empty() && !LLStringOps::sPM.empty() && code == "%p" ) + { + struct tm * gmt = gmtime (&loc_seconds); + if(gmt->tm_hour<12) + { + replacement = LLStringOps::sAM; + } + else + { + replacement = LLStringOps::sPM; + } + } + else + { + replacement = datetime.toHTTPDateString(code); + } // *HACK: delete leading zero from hour string in case 'hour12' (code = %I) time format // to show time without leading zero, e.g. 08:16 -> 8:16 (EXT-2738). diff --git a/indra/llcommon/llstring.h b/indra/llcommon/llstring.h index 96588b29b9..8071c8aa2d 100644 --- a/indra/llcommon/llstring.h +++ b/indra/llcommon/llstring.h @@ -154,9 +154,19 @@ private: static long sPacificTimeOffset; static long sLocalTimeOffset; static bool sPacificDaylightTime; + static std::map<std::string, std::string> datetimeToCodes; public: + static std::vector<std::string> sWeekDayList; + static std::vector<std::string> sWeekDayShortList; + static std::vector<std::string> sMonthList; + static std::vector<std::string> sMonthShortList; + static std::string sDayFormat; + + static std::string sAM; + static std::string sPM; + static char toUpper(char elem) { return toupper((unsigned char)elem); } static llwchar toUpper(llwchar elem) { return towupper(elem); } @@ -185,6 +195,14 @@ public: static S32 collate(const llwchar* a, const llwchar* b); static void setupDatetimeInfo(bool pacific_daylight_time); + + static void setupWeekDaysNames(const std::string& data); + static void setupWeekDaysShortNames(const std::string& data); + static void setupMonthNames(const std::string& data); + static void setupMonthShortNames(const std::string& data); + static void setupDayFormat(const std::string& data); + + static long getPacificTimeOffset(void) { return sPacificTimeOffset;} static long getLocalTimeOffset(void) { return sLocalTimeOffset;} // Is the Pacific time zone (aka server time zone) @@ -231,7 +249,7 @@ public: ///////////////////////////////////////////////////////////////////////////////////////// // Static Utility functions that operate on std::strings - static std::basic_string<T> null; + static const std::basic_string<T> null; typedef std::map<LLFormatMapString, LLFormatMapString> format_map_t; LL_COMMON_API static void getTokens(const std::basic_string<T>& instr, std::vector<std::basic_string<T> >& tokens, const std::basic_string<T>& delims); @@ -353,7 +371,7 @@ private: LL_COMMON_API static size_type getSubstitution(const std::basic_string<T>& instr, size_type& start, std::vector<std::basic_string<T> >& tokens); }; -template<class T> std::basic_string<T> LLStringUtilBase<T>::null; +template<class T> const std::basic_string<T> LLStringUtilBase<T>::null; template<class T> std::string LLStringUtilBase<T>::sLocale; typedef LLStringUtilBase<char> LLStringUtil; diff --git a/indra/llcommon/lluri.cpp b/indra/llcommon/lluri.cpp index 9d4f3a98f0..0e8f3f0f73 100644 --- a/indra/llcommon/lluri.cpp +++ b/indra/llcommon/lluri.cpp @@ -231,7 +231,8 @@ static BOOL isDefault(const std::string& scheme, U16 port) void LLURI::parseAuthorityAndPathUsingOpaque() { if (mScheme == "http" || mScheme == "https" || - mScheme == "ftp" || mScheme == "secondlife" ) + mScheme == "ftp" || mScheme == "secondlife" || + mScheme == "x-grid-location-info") { if (mEscapedOpaque.substr(0,2) != "//") { diff --git a/indra/llcommon/lluuid.cpp b/indra/llcommon/lluuid.cpp index bcbae06ec5..583c1e589b 100644 --- a/indra/llcommon/lluuid.cpp +++ b/indra/llcommon/lluuid.cpp @@ -33,9 +33,12 @@ // We can't use WIN32_LEAN_AND_MEAN here, needs lots of includes. #if LL_WINDOWS -# undef WIN32_LEAN_AND_MEAN -# include <winsock2.h> -# include <windows.h> +#undef WIN32_LEAN_AND_MEAN +#include <winsock2.h> +#include <windows.h> +// ugh, this is ugly. We need to straighten out our linking for this library +#pragma comment(lib, "IPHLPAPI.lib") +#include <iphlpapi.h> #endif #include "lldefs.h" @@ -452,67 +455,102 @@ static void get_random_bytes(void *buf, int nbytes) return; } -#if LL_WINDOWS -typedef struct _ASTAT_ -{ - ADAPTER_STATUS adapt; - NAME_BUFFER NameBuff [30]; -}ASTAT, * PASTAT; +#if LL_WINDOWS +// Code copied from http://msdn.microsoft.com/en-us/library/aa365939(VS.85).aspx +// This code grabs the first hardware address, rather than the first interface. +// Using a VPN can cause the first returned interface to be changed. + +const S32 MAC_ADDRESS_BYTES=6; + // 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; +S32 LLUUID::getNodeID(unsigned char *node_id) +{ + + // Declare and initialize variables. + DWORD dwSize = 0; + DWORD dwRetVal = 0; + int i; + +/* variables used for GetIfTable and GetIfEntry */ + MIB_IFTABLE *pIfTable; + MIB_IFROW *pIfRow; + + // Allocate memory for our pointers. + pIfTable = (MIB_IFTABLE *) malloc(sizeof (MIB_IFTABLE)); + if (pIfTable == NULL) + { + printf("Error allocating memory needed to call GetIfTable\n"); + return 0; + } + + // Before calling GetIfEntry, we call GetIfTable to make + // sure there are entries to get and retrieve the interface index. + + // Make an initial call to GetIfTable to get the + // necessary size into dwSize + if (GetIfTable(pIfTable, &dwSize, 0) == ERROR_INSUFFICIENT_BUFFER) { + free(pIfTable); + pIfTable = (MIB_IFTABLE *) malloc(dwSize); + if (pIfTable == NULL) + { + printf("Error allocating memory\n"); + return 0; + } + } + // Make a second call to GetIfTable to get the actual + // data we want. + if ((dwRetVal = GetIfTable(pIfTable, &dwSize, 0)) == NO_ERROR) + { + if (pIfTable->dwNumEntries > 0) + { + pIfRow = (MIB_IFROW *) malloc(sizeof (MIB_IFROW)); + if (pIfRow == NULL) + { + printf("Error allocating memory\n"); + if (pIfTable != NULL) + { + free(pIfTable); + pIfTable = NULL; + } + return 0; + } + + int limit = MAC_ADDRESS_BYTES; + memcpy(node_id, "\0\0\0\0\0\0", limit); // zero out array of bytes + for (i = 0; i < (int) pIfTable->dwNumEntries; i++) + { + pIfRow->dwIndex = pIfTable->table[i].dwIndex; + if ((dwRetVal = GetIfEntry(pIfRow)) == NO_ERROR) + { + switch (pIfRow->dwType) + { + case IF_TYPE_ETHERNET_CSMACD: + case IF_TYPE_IEEE80211: + limit = min((int) pIfRow->dwPhysAddrLen, limit); + if (pIfRow->dwPhysAddrLen == 0) + break; + memcpy(node_id, (UCHAR *)&pIfRow->bPhysAddr[0], limit); // just incase the PhysAddr is not the expected MAC_Address size + free(pIfTable); + return 1; //return first hardware device found. + break; + + case IF_TYPE_OTHER: + case IF_TYPE_PPP: + case IF_TYPE_SOFTWARE_LOOPBACK: + case IF_TYPE_ISO88025_TOKENRING: + case IF_TYPE_IEEE1394: + case IF_TYPE_ATM: + case IF_TYPE_TUNNEL: + default: + break; + } + } + } + } + } + free(pIfTable); + return 0; } #elif LL_DARWIN diff --git a/indra/llcommon/tests/llerror_test.cpp b/indra/llcommon/tests/llerror_test.cpp index 6785d0cf17..1558df231a 100644 --- a/indra/llcommon/tests/llerror_test.cpp +++ b/indra/llcommon/tests/llerror_test.cpp @@ -545,15 +545,6 @@ namespace tut // output order void ErrorTestObject::test<10>() { -#if LL_LINUX - skip("Fails on Linux, see comments"); -// on Linux: -// [error, 10] fail: 'order is time type location function message: expected -// '1947-07-08T03:04:05Z INFO: llcommon/tests/llerror_test.cpp(268) : -// writeReturningLocationAndFunction: apple' actual -// '1947-07-08T03:04:05Z INFO: llcommon/tests/llerror_test.cpp(268) : -// LLError::NoClassInfo::writeReturningLocationAndFunction: apple'' -#endif LLError::setPrintLocation(true); LLError::setTimeFunction(roswell); mRecorder.setWantsTime(true); |