From 9db949eec327df4173fde3de934a87bedb0db13c Mon Sep 17 00:00:00 2001 From: Bryan O'Sullivan Date: Mon, 2 Jun 2008 21:14:31 +0000 Subject: svn merge -r88066:88786 svn+ssh://svn.lindenlab.com/svn/linden/branches/cmake-9-merge dataserver-is-deprecated for-fucks-sake-whats-with-these-commit-markers --- indra/llcommon/lluuid.h | 330 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 330 insertions(+) create mode 100644 indra/llcommon/lluuid.h (limited to 'indra/llcommon/lluuid.h') diff --git a/indra/llcommon/lluuid.h b/indra/llcommon/lluuid.h new file mode 100644 index 0000000000..2f82ec9a93 --- /dev/null +++ b/indra/llcommon/lluuid.h @@ -0,0 +1,330 @@ +/** + * @file lluuid.h + * + * $LicenseInfo:firstyear=2000&license=viewergpl$ + * + * Copyright (c) 2000-2007, 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://secondlife.com/developers/opensource/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://secondlife.com/developers/opensource/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 toCompressedString(char *out) const; // Does not allocate memory, needs 17 characters (including \0) + + 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 BOOL validate(const char *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 char* 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 -- cgit v1.2.3