diff options
Diffstat (limited to 'linden/indra/llmath/lluuid.h')
-rw-r--r-- | linden/indra/llmath/lluuid.h | 321 |
1 files changed, 321 insertions, 0 deletions
diff --git a/linden/indra/llmath/lluuid.h b/linden/indra/llmath/lluuid.h new file mode 100644 index 0000000..b8288eb --- /dev/null +++ b/linden/indra/llmath/lluuid.h | |||
@@ -0,0 +1,321 @@ | |||
1 | /** | ||
2 | * @file lluuid.h | ||
3 | * | ||
4 | * Copyright (c) 2000-2007, Linden Research, Inc. | ||
5 | * | ||
6 | * The source code in this file ("Source Code") is provided by Linden Lab | ||
7 | * to you under the terms of the GNU General Public License, version 2.0 | ||
8 | * ("GPL"), unless you have obtained a separate licensing agreement | ||
9 | * ("Other License"), formally executed by you and Linden Lab. Terms of | ||
10 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | ||
11 | * online at http://secondlife.com/developers/opensource/gplv2 | ||
12 | * | ||
13 | * There are special exceptions to the terms and conditions of the GPL as | ||
14 | * it is applied to this Source Code. View the full text of the exception | ||
15 | * in the file doc/FLOSS-exception.txt in this software distribution, or | ||
16 | * online at http://secondlife.com/developers/opensource/flossexception | ||
17 | * | ||
18 | * By copying, modifying or distributing this software, you acknowledge | ||
19 | * that you have read and understood your obligations described above, | ||
20 | * and agree to abide by those obligations. | ||
21 | * | ||
22 | * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO | ||
23 | * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, | ||
24 | * COMPLETENESS OR PERFORMANCE. | ||
25 | */ | ||
26 | |||
27 | #ifndef LL_LLUUID_H | ||
28 | #define LL_LLUUID_H | ||
29 | |||
30 | #include <iostream> | ||
31 | #include <set> | ||
32 | |||
33 | #include "llstring.h" | ||
34 | |||
35 | const S32 UUID_BYTES = 16; | ||
36 | const S32 UUID_WORDS = 4; | ||
37 | const S32 UUID_STR_LENGTH = 37; // actually wrong, should be 36 and use size below | ||
38 | const S32 UUID_STR_SIZE = 37; | ||
39 | const S32 UUID_BASE85_LENGTH = 21; // including the trailing NULL. | ||
40 | |||
41 | struct uuid_time_t { | ||
42 | U32 high; | ||
43 | U32 low; | ||
44 | }; | ||
45 | |||
46 | class LLUUID | ||
47 | { | ||
48 | public: | ||
49 | // | ||
50 | // CREATORS | ||
51 | // | ||
52 | LLUUID(); | ||
53 | explicit LLUUID(const char *in_string); // Convert from string. | ||
54 | explicit LLUUID(const std::string& in_string); // Convert from string. | ||
55 | LLUUID(const LLUUID &in); | ||
56 | LLUUID &operator=(const LLUUID &rhs); | ||
57 | |||
58 | ~LLUUID(); | ||
59 | |||
60 | // | ||
61 | // MANIPULATORS | ||
62 | // | ||
63 | void generate(); // Generate a new UUID | ||
64 | BOOL set(const char *in_string, BOOL emit = TRUE); // Convert from string, if emit is FALSE, do not emit warnings | ||
65 | BOOL set(const std::string& in_string, BOOL emit = TRUE); // Convert from string, if emit is FALSE, do not emit warnings | ||
66 | void setNull(); // Faster than setting to LLUUID::null. | ||
67 | |||
68 | S32 cmpTime(uuid_time_t *t1, uuid_time_t *t2); | ||
69 | static void getSystemTime(uuid_time_t *timestamp); | ||
70 | void getCurrentTime(uuid_time_t *timestamp); | ||
71 | |||
72 | // | ||
73 | // ACCESSORS | ||
74 | // | ||
75 | BOOL isNull() const; // Faster than comparing to LLUUID::null. | ||
76 | BOOL notNull() const; // Faster than comparing to LLUUID::null. | ||
77 | // JC: This is dangerous. It allows UUIDs to be cast automatically | ||
78 | // to integers, among other things. Use isNull() or notNull(). | ||
79 | // operator bool() const; | ||
80 | |||
81 | // JC: These must return real bool's (not BOOLs) or else use of the STL | ||
82 | // will generate bool-to-int performance warnings. | ||
83 | bool operator==(const LLUUID &rhs) const; | ||
84 | bool operator!=(const LLUUID &rhs) const; | ||
85 | bool operator<(const LLUUID &rhs) const; | ||
86 | bool operator>(const LLUUID &rhs) const; | ||
87 | |||
88 | // xor functions. Useful since any two random uuids xored together | ||
89 | // will yield a determinate third random unique id that can be | ||
90 | // used as a key in a single uuid that represents 2. | ||
91 | const LLUUID& operator^=(const LLUUID& rhs); | ||
92 | LLUUID operator^(const LLUUID& rhs) const; | ||
93 | |||
94 | // similar to functions above, but not invertible | ||
95 | // yields a third random UUID that can be reproduced from the two inputs | ||
96 | // but which, given the result and one of the inputs can't be used to | ||
97 | // deduce the other input | ||
98 | LLUUID combine(const LLUUID& other) const; | ||
99 | void combine(const LLUUID& other, LLUUID& result) const; | ||
100 | |||
101 | friend std::ostream& operator<<(std::ostream& s, const LLUUID &uuid); | ||
102 | friend std::istream& operator>>(std::istream& s, LLUUID &uuid); | ||
103 | |||
104 | void toString(char *out) const; // Does not allocate memory, needs 36 characters (including \0) | ||
105 | void toCompressedString(char *out) const; // Does not allocate memory, needs 17 characters (including \0) | ||
106 | LLString getString() const; | ||
107 | U16 getCRC16() const; | ||
108 | U32 getCRC32() const; | ||
109 | |||
110 | static BOOL validate(const std::string& in_string); // Validate that the UUID string is legal. | ||
111 | static BOOL validate(const char *in_string); // Validate that the UUID string is legal. | ||
112 | |||
113 | static const LLUUID null; | ||
114 | |||
115 | static U32 getRandomSeed(); | ||
116 | static S32 getNodeID(unsigned char * node_id); | ||
117 | |||
118 | static BOOL parseUUID(const char* buf, LLUUID* value); | ||
119 | |||
120 | U8 mData[UUID_BYTES]; | ||
121 | }; | ||
122 | |||
123 | |||
124 | // Construct | ||
125 | inline LLUUID::LLUUID() | ||
126 | { | ||
127 | setNull(); | ||
128 | } | ||
129 | |||
130 | |||
131 | // Faster than copying from memory | ||
132 | inline void LLUUID::setNull() | ||
133 | { | ||
134 | U32 *word = (U32 *)mData; | ||
135 | word[0] = 0; | ||
136 | word[1] = 0; | ||
137 | word[2] = 0; | ||
138 | word[3] = 0; | ||
139 | } | ||
140 | |||
141 | |||
142 | // Compare | ||
143 | inline bool LLUUID::operator==(const LLUUID& rhs) const | ||
144 | { | ||
145 | U32 *tmp = (U32 *)mData; | ||
146 | U32 *rhstmp = (U32 *)rhs.mData; | ||
147 | // Note: binary & to avoid branching | ||
148 | return | ||
149 | (tmp[0] == rhstmp[0]) & | ||
150 | (tmp[1] == rhstmp[1]) & | ||
151 | (tmp[2] == rhstmp[2]) & | ||
152 | (tmp[3] == rhstmp[3]); | ||
153 | } | ||
154 | |||
155 | |||
156 | inline bool LLUUID::operator!=(const LLUUID& rhs) const | ||
157 | { | ||
158 | U32 *tmp = (U32 *)mData; | ||
159 | U32 *rhstmp = (U32 *)rhs.mData; | ||
160 | // Note: binary | to avoid branching | ||
161 | return | ||
162 | (tmp[0] != rhstmp[0]) | | ||
163 | (tmp[1] != rhstmp[1]) | | ||
164 | (tmp[2] != rhstmp[2]) | | ||
165 | (tmp[3] != rhstmp[3]); | ||
166 | } | ||
167 | |||
168 | /* | ||
169 | // JC: This is dangerous. It allows UUIDs to be cast automatically | ||
170 | // to integers, among other things. Use isNull() or notNull(). | ||
171 | inline LLUUID::operator bool() const | ||
172 | { | ||
173 | U32 *word = (U32 *)mData; | ||
174 | return (word[0] | word[1] | word[2] | word[3]) > 0; | ||
175 | } | ||
176 | */ | ||
177 | |||
178 | inline BOOL LLUUID::notNull() const | ||
179 | { | ||
180 | U32 *word = (U32 *)mData; | ||
181 | return (word[0] | word[1] | word[2] | word[3]) > 0; | ||
182 | } | ||
183 | |||
184 | // Faster than == LLUUID::null because doesn't require | ||
185 | // as much memory access. | ||
186 | inline BOOL LLUUID::isNull() const | ||
187 | { | ||
188 | U32 *word = (U32 *)mData; | ||
189 | // If all bits are zero, return !0 == TRUE | ||
190 | return !(word[0] | word[1] | word[2] | word[3]); | ||
191 | } | ||
192 | |||
193 | // Copy constructor | ||
194 | inline LLUUID::LLUUID(const LLUUID& rhs) | ||
195 | { | ||
196 | U32 *tmp = (U32 *)mData; | ||
197 | U32 *rhstmp = (U32 *)rhs.mData; | ||
198 | tmp[0] = rhstmp[0]; | ||
199 | tmp[1] = rhstmp[1]; | ||
200 | tmp[2] = rhstmp[2]; | ||
201 | tmp[3] = rhstmp[3]; | ||
202 | } | ||
203 | |||
204 | inline LLUUID::~LLUUID() | ||
205 | { | ||
206 | } | ||
207 | |||
208 | // Assignment | ||
209 | inline LLUUID& LLUUID::operator=(const LLUUID& rhs) | ||
210 | { | ||
211 | // No need to check the case where this==&rhs. The branch is slower than the write. | ||
212 | U32 *tmp = (U32 *)mData; | ||
213 | U32 *rhstmp = (U32 *)rhs.mData; | ||
214 | tmp[0] = rhstmp[0]; | ||
215 | tmp[1] = rhstmp[1]; | ||
216 | tmp[2] = rhstmp[2]; | ||
217 | tmp[3] = rhstmp[3]; | ||
218 | |||
219 | return *this; | ||
220 | } | ||
221 | |||
222 | |||
223 | inline LLUUID::LLUUID(const char *in_string) | ||
224 | { | ||
225 | if (!in_string || in_string[0] == 0) | ||
226 | { | ||
227 | setNull(); | ||
228 | return; | ||
229 | } | ||
230 | |||
231 | set(in_string); | ||
232 | } | ||
233 | |||
234 | inline LLUUID::LLUUID(const std::string& in_string) | ||
235 | { | ||
236 | if (in_string.empty()) | ||
237 | { | ||
238 | setNull(); | ||
239 | return; | ||
240 | } | ||
241 | |||
242 | set(in_string); | ||
243 | } | ||
244 | |||
245 | // IW: DON'T "optimize" these w/ U32s or you'll scoogie the sort order | ||
246 | // IW: this will make me very sad | ||
247 | inline bool LLUUID::operator<(const LLUUID &rhs) const | ||
248 | { | ||
249 | U32 i; | ||
250 | for( i = 0; i < (UUID_BYTES - 1); i++ ) | ||
251 | { | ||
252 | if( mData[i] != rhs.mData[i] ) | ||
253 | { | ||
254 | return (mData[i] < rhs.mData[i]); | ||
255 | } | ||
256 | } | ||
257 | return (mData[UUID_BYTES - 1] < rhs.mData[UUID_BYTES - 1]); | ||
258 | } | ||
259 | |||
260 | inline bool LLUUID::operator>(const LLUUID &rhs) const | ||
261 | { | ||
262 | U32 i; | ||
263 | for( i = 0; i < (UUID_BYTES - 1); i++ ) | ||
264 | { | ||
265 | if( mData[i] != rhs.mData[i] ) | ||
266 | { | ||
267 | return (mData[i] > rhs.mData[i]); | ||
268 | } | ||
269 | } | ||
270 | return (mData[UUID_BYTES - 1] > rhs.mData[UUID_BYTES - 1]); | ||
271 | } | ||
272 | |||
273 | inline U16 LLUUID::getCRC16() const | ||
274 | { | ||
275 | // A UUID is 16 bytes, or 8 shorts. | ||
276 | U16 *short_data = (U16*)mData; | ||
277 | U16 out = 0; | ||
278 | out += short_data[0]; | ||
279 | out += short_data[1]; | ||
280 | out += short_data[2]; | ||
281 | out += short_data[3]; | ||
282 | out += short_data[4]; | ||
283 | out += short_data[5]; | ||
284 | out += short_data[6]; | ||
285 | out += short_data[7]; | ||
286 | return out; | ||
287 | } | ||
288 | |||
289 | inline U32 LLUUID::getCRC32() const | ||
290 | { | ||
291 | U32 *tmp = (U32*)mData; | ||
292 | return tmp[0] + tmp[1] + tmp[2] + tmp[3]; | ||
293 | } | ||
294 | |||
295 | |||
296 | // Helper structure for ordering lluuids in stl containers. | ||
297 | // eg: std::map<LLUUID, LLWidget*, lluuid_less> widget_map; | ||
298 | struct lluuid_less | ||
299 | { | ||
300 | bool operator()(const LLUUID& lhs, const LLUUID& rhs) const | ||
301 | { | ||
302 | return (lhs < rhs) ? true : false; | ||
303 | } | ||
304 | }; | ||
305 | |||
306 | typedef std::set<LLUUID, lluuid_less> uuid_list_t; | ||
307 | |||
308 | /* | ||
309 | * Sub-classes for keeping transaction IDs and asset IDs | ||
310 | * straight. | ||
311 | */ | ||
312 | typedef LLUUID LLAssetID; | ||
313 | |||
314 | class LLTransactionID : public LLUUID | ||
315 | { | ||
316 | public: | ||
317 | static const LLTransactionID tnull; | ||
318 | LLAssetID makeAssetID(const LLUUID& session) const; | ||
319 | }; | ||
320 | |||
321 | #endif | ||