PageRenderTime 30ms CodeModel.GetById 12ms app.highlight 14ms RepoModel.GetById 1ms app.codeStats 1ms

/indra/llcommon/lluuid.h

https://bitbucket.org/lindenlab/viewer-beta/
C++ Header | 331 lines | 203 code | 54 blank | 74 comment | 18 complexity | 1a66fb78109c235a5ae28de8a3dccb8d MD5 | raw file
  1/** 
  2 * @file lluuid.h
  3 *
  4 * $LicenseInfo:firstyear=2000&license=viewerlgpl$
  5 * Second Life Viewer Source Code
  6 * Copyright (C) 2010, Linden Research, Inc.
  7 * 
  8 * This library is free software; you can redistribute it and/or
  9 * modify it under the terms of the GNU Lesser General Public
 10 * License as published by the Free Software Foundation;
 11 * version 2.1 of the License only.
 12 * 
 13 * This library is distributed in the hope that it will be useful,
 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 16 * Lesser General Public License for more details.
 17 * 
 18 * You should have received a copy of the GNU Lesser General Public
 19 * License along with this library; if not, write to the Free Software
 20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 21 * 
 22 * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 23 * $/LicenseInfo$
 24 */
 25
 26#ifndef LL_LLUUID_H
 27#define LL_LLUUID_H
 28
 29#include <iostream>
 30#include <set>
 31#include "stdtypes.h"
 32#include "llpreprocessor.h"
 33
 34const S32 UUID_BYTES = 16;
 35const S32 UUID_WORDS = 4;
 36const S32 UUID_STR_LENGTH = 37;	// actually wrong, should be 36 and use size below
 37const S32 UUID_STR_SIZE = 37;
 38const S32 UUID_BASE85_LENGTH = 21; // including the trailing NULL.
 39
 40struct uuid_time_t {
 41	U32 high;
 42	U32 low;
 43		};
 44
 45class LL_COMMON_API LLUUID
 46{
 47public:
 48	//
 49	// CREATORS
 50	//
 51	LLUUID();
 52	explicit LLUUID(const char *in_string); // Convert from string.
 53	explicit LLUUID(const std::string& in_string); // Convert from string.
 54	LLUUID(const LLUUID &in);
 55	LLUUID &operator=(const LLUUID &rhs);
 56
 57	~LLUUID();
 58
 59	//
 60	// MANIPULATORS
 61	//
 62	void	generate();					// Generate a new UUID
 63	void	generate(const std::string& stream); //Generate a new UUID based on hash of input stream
 64
 65	static LLUUID generateNewID(std::string stream = "");	//static version of above for use in initializer expressions such as constructor params, etc. 
 66
 67	BOOL	set(const char *in_string, BOOL emit = TRUE);	// Convert from string, if emit is FALSE, do not emit warnings
 68	BOOL	set(const std::string& in_string, BOOL emit = TRUE);	// Convert from string, if emit is FALSE, do not emit warnings
 69	void	setNull();					// Faster than setting to LLUUID::null.
 70
 71    S32     cmpTime(uuid_time_t *t1, uuid_time_t *t2);
 72	static void    getSystemTime(uuid_time_t *timestamp);
 73	void    getCurrentTime(uuid_time_t *timestamp);
 74
 75	//
 76	// ACCESSORS
 77	//
 78	BOOL	isNull() const;			// Faster than comparing to LLUUID::null.
 79	BOOL	notNull() const;		// Faster than comparing to LLUUID::null.
 80	// JC: This is dangerous.  It allows UUIDs to be cast automatically
 81	// to integers, among other things.  Use isNull() or notNull().
 82	//		operator bool() const;
 83
 84	// JC: These must return real bool's (not BOOLs) or else use of the STL
 85	// will generate bool-to-int performance warnings.
 86	bool	operator==(const LLUUID &rhs) const;
 87	bool	operator!=(const LLUUID &rhs) const;
 88	bool	operator<(const LLUUID &rhs) const;
 89	bool	operator>(const LLUUID &rhs) const;
 90
 91	// xor functions. Useful since any two random uuids xored together
 92	// will yield a determinate third random unique id that can be
 93	// used as a key in a single uuid that represents 2.
 94	const LLUUID& operator^=(const LLUUID& rhs);
 95	LLUUID operator^(const LLUUID& rhs) const;
 96
 97	// similar to functions above, but not invertible
 98	// yields a third random UUID that can be reproduced from the two inputs
 99	// but which, given the result and one of the inputs can't be used to
100	// deduce the other input
101	LLUUID combine(const LLUUID& other) const;
102	void combine(const LLUUID& other, LLUUID& result) const;  
103
104	friend LL_COMMON_API std::ostream&	 operator<<(std::ostream& s, const LLUUID &uuid);
105	friend LL_COMMON_API std::istream&	 operator>>(std::istream& s, LLUUID &uuid);
106
107	void toString(char *out) const;		// Does not allocate memory, needs 36 characters (including \0)
108	void toString(std::string& out) const;
109	void toCompressedString(char *out) const;	// Does not allocate memory, needs 17 characters (including \0)
110	void toCompressedString(std::string& out) const;
111
112	std::string asString() const;
113	std::string getString() const;
114
115	U16 getCRC16() const;
116	U32 getCRC32() const;
117
118	static BOOL validate(const std::string& in_string); // Validate that the UUID string is legal.
119
120	static const LLUUID null;
121
122	static U32 getRandomSeed();
123	static S32 getNodeID(unsigned char * node_id);
124
125	static BOOL parseUUID(const std::string& buf, LLUUID* value);
126
127	U8 mData[UUID_BYTES];
128};
129
130typedef std::vector<LLUUID> uuid_vec_t;
131
132// Construct
133inline LLUUID::LLUUID()
134{
135	setNull();
136}
137
138
139// Faster than copying from memory
140inline void LLUUID::setNull()
141{
142	U32 *word = (U32 *)mData;
143	word[0] = 0;
144	word[1] = 0;
145	word[2] = 0;
146	word[3] = 0;
147}
148
149
150// Compare
151inline bool LLUUID::operator==(const LLUUID& rhs) const
152{
153	U32 *tmp = (U32 *)mData;
154	U32 *rhstmp = (U32 *)rhs.mData;
155	// Note: binary & to avoid branching
156	return 
157		(tmp[0] == rhstmp[0]) &  
158		(tmp[1] == rhstmp[1]) &
159		(tmp[2] == rhstmp[2]) &
160		(tmp[3] == rhstmp[3]);
161}
162
163
164inline bool LLUUID::operator!=(const LLUUID& rhs) const
165{
166	U32 *tmp = (U32 *)mData;
167	U32 *rhstmp = (U32 *)rhs.mData;
168	// Note: binary | to avoid branching
169	return 
170		(tmp[0] != rhstmp[0]) |
171		(tmp[1] != rhstmp[1]) |
172		(tmp[2] != rhstmp[2]) |
173		(tmp[3] != rhstmp[3]);
174}
175
176/*
177// JC: This is dangerous.  It allows UUIDs to be cast automatically
178// to integers, among other things.  Use isNull() or notNull().
179inline LLUUID::operator bool() const
180{
181	U32 *word = (U32 *)mData;
182	return (word[0] | word[1] | word[2] | word[3]) > 0;
183}
184*/
185
186inline BOOL LLUUID::notNull() const
187{
188	U32 *word = (U32 *)mData;
189	return (word[0] | word[1] | word[2] | word[3]) > 0;
190}
191
192// Faster than == LLUUID::null because doesn't require
193// as much memory access.
194inline BOOL LLUUID::isNull() const
195{
196	U32 *word = (U32 *)mData;
197	// If all bits are zero, return !0 == TRUE
198	return !(word[0] | word[1] | word[2] | word[3]);
199}
200
201// Copy constructor
202inline LLUUID::LLUUID(const LLUUID& rhs)
203{
204	U32 *tmp = (U32 *)mData;
205	U32 *rhstmp = (U32 *)rhs.mData;
206	tmp[0] = rhstmp[0];
207	tmp[1] = rhstmp[1];
208	tmp[2] = rhstmp[2];
209	tmp[3] = rhstmp[3];
210}
211
212inline LLUUID::~LLUUID()
213{
214}
215
216// Assignment
217inline LLUUID& LLUUID::operator=(const LLUUID& rhs)
218{
219	// No need to check the case where this==&rhs.  The branch is slower than the write.
220	U32 *tmp = (U32 *)mData;
221	U32 *rhstmp = (U32 *)rhs.mData;
222	tmp[0] = rhstmp[0];
223	tmp[1] = rhstmp[1];
224	tmp[2] = rhstmp[2];
225	tmp[3] = rhstmp[3];
226	
227	return *this;
228}
229
230
231inline LLUUID::LLUUID(const char *in_string)
232{
233	if (!in_string || in_string[0] == 0)
234	{
235		setNull();
236		return;
237	}
238 
239	set(in_string);
240}
241
242inline LLUUID::LLUUID(const std::string& in_string)
243{
244	if (in_string.empty())
245	{
246		setNull();
247		return;
248	}
249
250	set(in_string);
251}
252
253// IW: DON'T "optimize" these w/ U32s or you'll scoogie the sort order
254// IW: this will make me very sad
255inline bool LLUUID::operator<(const LLUUID &rhs) const
256{
257	U32 i;
258	for( i = 0; i < (UUID_BYTES - 1); i++ )
259	{
260		if( mData[i] != rhs.mData[i] )
261		{
262			return (mData[i] < rhs.mData[i]);
263		}
264	}
265	return (mData[UUID_BYTES - 1] < rhs.mData[UUID_BYTES - 1]);
266}
267
268inline bool LLUUID::operator>(const LLUUID &rhs) const
269{
270	U32 i;
271	for( i = 0; i < (UUID_BYTES - 1); i++ )
272	{
273		if( mData[i] != rhs.mData[i] )
274		{
275			return (mData[i] > rhs.mData[i]);
276		}
277	}
278	return (mData[UUID_BYTES - 1] > rhs.mData[UUID_BYTES - 1]);
279}
280
281inline U16 LLUUID::getCRC16() const
282{
283	// A UUID is 16 bytes, or 8 shorts.
284	U16 *short_data = (U16*)mData;
285	U16 out = 0;
286	out += short_data[0];
287	out += short_data[1];
288	out += short_data[2];
289	out += short_data[3];
290	out += short_data[4];
291	out += short_data[5];
292	out += short_data[6];
293	out += short_data[7];
294	return out;
295}
296
297inline U32 LLUUID::getCRC32() const
298{
299	U32 *tmp = (U32*)mData;
300	return tmp[0] + tmp[1] + tmp[2] + tmp[3];
301}
302
303
304// Helper structure for ordering lluuids in stl containers.
305// eg: 	std::map<LLUUID, LLWidget*, lluuid_less> widget_map;
306struct lluuid_less
307{
308	bool operator()(const LLUUID& lhs, const LLUUID& rhs) const
309	{
310		return (lhs < rhs) ? true : false;
311	}
312};
313
314typedef std::set<LLUUID, lluuid_less> uuid_list_t;
315
316/*
317 * Sub-classes for keeping transaction IDs and asset IDs
318 * straight.
319 */
320typedef LLUUID LLAssetID;
321
322class LL_COMMON_API LLTransactionID : public LLUUID
323{
324public:
325	LLTransactionID() : LLUUID() { }
326	
327	static const LLTransactionID tnull;
328	LLAssetID makeAssetID(const LLUUID& session) const;
329};
330
331#endif