diff options
Diffstat (limited to 'linden/indra/llcommon/lluuid.h')
-rw-r--r-- | linden/indra/llcommon/lluuid.h | 331 |
1 files changed, 331 insertions, 0 deletions
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 @@ | |||
1 | /** | ||
2 | * @file lluuid.h | ||
3 | * | ||
4 | * $LicenseInfo:firstyear=2000&license=viewergpl$ | ||
5 | * | ||
6 | * Copyright (c) 2000-2008, Linden Research, Inc. | ||
7 | * | ||
8 | * Second Life Viewer Source Code | ||
9 | * The source code in this file ("Source Code") is provided by Linden Lab | ||
10 | * to you under the terms of the GNU General Public License, version 2.0 | ||
11 | * ("GPL"), unless you have obtained a separate licensing agreement | ||
12 | * ("Other License"), formally executed by you and Linden Lab. Terms of | ||
13 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | ||
14 | * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 | ||
15 | * | ||
16 | * There are special exceptions to the terms and conditions of the GPL as | ||
17 | * it is applied to this Source Code. View the full text of the exception | ||
18 | * in the file doc/FLOSS-exception.txt in this software distribution, or | ||
19 | * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception | ||
20 | * | ||
21 | * By copying, modifying or distributing this software, you acknowledge | ||
22 | * that you have read and understood your obligations described above, | ||
23 | * and agree to abide by those obligations. | ||
24 | * | ||
25 | * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO | ||
26 | * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, | ||
27 | * COMPLETENESS OR PERFORMANCE. | ||
28 | * $/LicenseInfo$ | ||
29 | */ | ||
30 | |||
31 | #ifndef LL_LLUUID_H | ||
32 | #define LL_LLUUID_H | ||
33 | |||
34 | #include <iostream> | ||
35 | #include <set> | ||
36 | #include "stdtypes.h" | ||
37 | |||
38 | const S32 UUID_BYTES = 16; | ||
39 | const S32 UUID_WORDS = 4; | ||
40 | const S32 UUID_STR_LENGTH = 37; // actually wrong, should be 36 and use size below | ||
41 | const S32 UUID_STR_SIZE = 37; | ||
42 | const S32 UUID_BASE85_LENGTH = 21; // including the trailing NULL. | ||
43 | |||
44 | struct uuid_time_t { | ||
45 | U32 high; | ||
46 | U32 low; | ||
47 | }; | ||
48 | |||
49 | class LLUUID | ||
50 | { | ||
51 | public: | ||
52 | // | ||
53 | // CREATORS | ||
54 | // | ||
55 | LLUUID(); | ||
56 | explicit LLUUID(const char *in_string); // Convert from string. | ||
57 | explicit LLUUID(const std::string& in_string); // Convert from string. | ||
58 | LLUUID(const LLUUID &in); | ||
59 | LLUUID &operator=(const LLUUID &rhs); | ||
60 | |||
61 | ~LLUUID(); | ||
62 | |||
63 | // | ||
64 | // MANIPULATORS | ||
65 | // | ||
66 | void generate(); // Generate a new UUID | ||
67 | void generate(const std::string& stream); //Generate a new UUID based on hash of input stream | ||
68 | BOOL set(const char *in_string, BOOL emit = TRUE); // Convert from string, if emit is FALSE, do not emit warnings | ||
69 | BOOL set(const std::string& in_string, BOOL emit = TRUE); // Convert from string, if emit is FALSE, do not emit warnings | ||
70 | void setNull(); // Faster than setting to LLUUID::null. | ||
71 | |||
72 | S32 cmpTime(uuid_time_t *t1, uuid_time_t *t2); | ||
73 | static void getSystemTime(uuid_time_t *timestamp); | ||
74 | void getCurrentTime(uuid_time_t *timestamp); | ||
75 | |||
76 | // | ||
77 | // ACCESSORS | ||
78 | // | ||
79 | BOOL isNull() const; // Faster than comparing to LLUUID::null. | ||
80 | BOOL notNull() const; // Faster than comparing to LLUUID::null. | ||
81 | // JC: This is dangerous. It allows UUIDs to be cast automatically | ||
82 | // to integers, among other things. Use isNull() or notNull(). | ||
83 | // operator bool() const; | ||
84 | |||
85 | // JC: These must return real bool's (not BOOLs) or else use of the STL | ||
86 | // will generate bool-to-int performance warnings. | ||
87 | bool operator==(const LLUUID &rhs) const; | ||
88 | bool operator!=(const LLUUID &rhs) const; | ||
89 | bool operator<(const LLUUID &rhs) const; | ||
90 | bool operator>(const LLUUID &rhs) const; | ||
91 | |||
92 | // xor functions. Useful since any two random uuids xored together | ||
93 | // will yield a determinate third random unique id that can be | ||
94 | // used as a key in a single uuid that represents 2. | ||
95 | const LLUUID& operator^=(const LLUUID& rhs); | ||
96 | LLUUID operator^(const LLUUID& rhs) const; | ||
97 | |||
98 | // similar to functions above, but not invertible | ||
99 | // yields a third random UUID that can be reproduced from the two inputs | ||
100 | // but which, given the result and one of the inputs can't be used to | ||
101 | // deduce the other input | ||
102 | LLUUID combine(const LLUUID& other) const; | ||
103 | void combine(const LLUUID& other, LLUUID& result) const; | ||
104 | |||
105 | friend std::ostream& operator<<(std::ostream& s, const LLUUID &uuid); | ||
106 | friend std::istream& operator>>(std::istream& s, LLUUID &uuid); | ||
107 | |||
108 | void toString(char *out) const; // Does not allocate memory, needs 36 characters (including \0) | ||
109 | void toString(std::string& out) const; | ||
110 | void toCompressedString(char *out) const; // Does not allocate memory, needs 17 characters (including \0) | ||
111 | void toCompressedString(std::string& out) const; | ||
112 | |||
113 | std::string asString() const; | ||
114 | std::string getString() const; | ||
115 | |||
116 | U16 getCRC16() const; | ||
117 | U32 getCRC32() const; | ||
118 | |||
119 | static BOOL validate(const std::string& in_string); // Validate that the UUID string is legal. | ||
120 | |||
121 | static const LLUUID null; | ||
122 | |||
123 | static U32 getRandomSeed(); | ||
124 | static S32 getNodeID(unsigned char * node_id); | ||
125 | |||
126 | static BOOL parseUUID(const std::string& buf, LLUUID* value); | ||
127 | |||
128 | U8 mData[UUID_BYTES]; | ||
129 | }; | ||
130 | |||
131 | |||
132 | // Construct | ||
133 | inline LLUUID::LLUUID() | ||
134 | { | ||
135 | setNull(); | ||
136 | } | ||
137 | |||
138 | |||
139 | // Faster than copying from memory | ||
140 | inline 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 | ||
151 | inline 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 | |||
164 | inline 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(). | ||
179 | inline LLUUID::operator bool() const | ||
180 | { | ||
181 | U32 *word = (U32 *)mData; | ||
182 | return (word[0] | word[1] | word[2] | word[3]) > 0; | ||
183 | } | ||
184 | */ | ||
185 | |||
186 | inline 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. | ||
194 | inline 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 | ||
202 | inline 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 | |||
212 | inline LLUUID::~LLUUID() | ||
213 | { | ||
214 | } | ||
215 | |||
216 | // Assignment | ||
217 | inline 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 | |||
231 | inline 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 | |||
242 | inline 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 | ||
255 | inline 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 | |||
268 | inline 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 | |||
281 | inline 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 | |||
297 | inline 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; | ||
306 | struct lluuid_less | ||
307 | { | ||
308 | bool operator()(const LLUUID& lhs, const LLUUID& rhs) const | ||
309 | { | ||
310 | return (lhs < rhs) ? true : false; | ||
311 | } | ||
312 | }; | ||
313 | |||
314 | typedef std::set<LLUUID, lluuid_less> uuid_list_t; | ||
315 | |||
316 | /* | ||
317 | * Sub-classes for keeping transaction IDs and asset IDs | ||
318 | * straight. | ||
319 | */ | ||
320 | typedef LLUUID LLAssetID; | ||
321 | |||
322 | class LLTransactionID : public LLUUID | ||
323 | { | ||
324 | public: | ||
325 | LLTransactionID() : LLUUID() { } | ||
326 | |||
327 | static const LLTransactionID tnull; | ||
328 | LLAssetID makeAssetID(const LLUUID& session) const; | ||
329 | }; | ||
330 | |||
331 | #endif | ||