~ubuntu-branches/ubuntu/gutsy/poco/gutsy

« back to all changes in this revision

Viewing changes to Foundation/src/UUID.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Krzysztof Burghardt
  • Date: 2007-04-27 18:33:48 UTC
  • Revision ID: james.westby@ubuntu.com-20070427183348-xgnpct0qd6a2ip34
Tags: upstream-1.2.9
ImportĀ upstreamĀ versionĀ 1.2.9

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
//
 
2
// UUID.cpp
 
3
//
 
4
// $Id: //poco/1.2/Foundation/src/UUID.cpp#1 $
 
5
//
 
6
// Library: Foundation
 
7
// Package: UUID
 
8
// Module:  UUID
 
9
//
 
10
// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
 
11
// and Contributors.
 
12
//
 
13
// Permission is hereby granted, free of charge, to any person or organization
 
14
// obtaining a copy of the software and accompanying documentation covered by
 
15
// this license (the "Software") to use, reproduce, display, distribute,
 
16
// execute, and transmit the Software, and to prepare derivative works of the
 
17
// Software, and to permit third-parties to whom the Software is furnished to
 
18
// do so, all subject to the following:
 
19
// 
 
20
// The copyright notices in the Software and this entire statement, including
 
21
// the above license grant, this restriction and the following disclaimer,
 
22
// must be included in all copies of the Software, in whole or in part, and
 
23
// all derivative works of the Software, unless such copies or derivative
 
24
// works are solely in the form of machine-executable object code generated by
 
25
// a source language processor.
 
26
// 
 
27
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 
28
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 
29
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
 
30
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
 
31
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
 
32
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 
33
// DEALINGS IN THE SOFTWARE.
 
34
//
 
35
 
 
36
 
 
37
#include "Poco/UUID.h"
 
38
#include "Poco/ByteOrder.h"
 
39
#include "Poco/Exception.h"
 
40
#include <algorithm>
 
41
#include <string.h>
 
42
 
 
43
 
 
44
namespace Poco {
 
45
 
 
46
 
 
47
UUID::UUID(): 
 
48
        _timeLow(0), 
 
49
        _timeMid(0),
 
50
        _timeHiAndVersion(0),
 
51
        _clockSeq(0)
 
52
{
 
53
        memset(_node, 0, sizeof(_node));
 
54
}
 
55
 
 
56
 
 
57
UUID::UUID(const UUID& uuid):
 
58
        _timeLow(uuid._timeLow), 
 
59
        _timeMid(uuid._timeMid),
 
60
        _timeHiAndVersion(uuid._timeHiAndVersion),
 
61
        _clockSeq(uuid._clockSeq)
 
62
{
 
63
        memcpy(_node, uuid._node, sizeof(_node));
 
64
}
 
65
 
 
66
 
 
67
UUID::UUID(const std::string& uuid)
 
68
{
 
69
        parse(uuid);
 
70
}
 
71
 
 
72
        
 
73
UUID::UUID(const char* uuid)
 
74
{
 
75
        poco_check_ptr (uuid);
 
76
        parse(std::string(uuid));
 
77
}
 
78
 
 
79
 
 
80
UUID::UUID(UInt32 timeLow, UInt32 timeMid, UInt32 timeHiAndVersion, UInt16 clockSeq, UInt8 node[]):
 
81
        _timeLow(timeLow),
 
82
        _timeMid(timeMid),
 
83
        _timeHiAndVersion(timeHiAndVersion),
 
84
        _clockSeq(clockSeq)
 
85
{
 
86
        memcpy(_node, node, sizeof(_node));
 
87
}
 
88
 
 
89
 
 
90
UUID::UUID(const char* bytes, Version version)
 
91
{
 
92
        UInt32 i32;
 
93
        UInt16 i16;
 
94
        memcpy(&i32, bytes, sizeof(i32));
 
95
        _timeLow = ByteOrder::fromNetwork(i32);
 
96
        bytes += sizeof(i32);
 
97
        memcpy(&i16, bytes, sizeof(i16));
 
98
        _timeMid = ByteOrder::fromNetwork(i16);
 
99
        bytes += sizeof(i16);
 
100
        memcpy(&i16, bytes, sizeof(i16));
 
101
        _timeHiAndVersion = ByteOrder::fromNetwork(i16);
 
102
        bytes += sizeof(i16);
 
103
        memcpy(&i16, bytes, sizeof(i16));
 
104
        _clockSeq = ByteOrder::fromNetwork(i16);
 
105
        bytes += sizeof(i16);
 
106
        memcpy(_node, bytes, sizeof(_node));
 
107
 
 
108
        _timeHiAndVersion &= 0x0FFF;
 
109
        _timeHiAndVersion |= (version << 12);
 
110
        _clockSeq &= 0x3FFF;
 
111
        _clockSeq |= 0x8000;
 
112
}
 
113
 
 
114
 
 
115
UUID::~UUID()
 
116
{
 
117
}
 
118
 
 
119
 
 
120
UUID& UUID::operator = (const UUID& uuid)
 
121
{
 
122
        if (&uuid != this)
 
123
        {
 
124
                _timeLow = uuid._timeLow;
 
125
                _timeMid = uuid._timeMid;
 
126
                _timeHiAndVersion = uuid._timeHiAndVersion;
 
127
                _clockSeq         = uuid._clockSeq;
 
128
                memcpy(_node, uuid._node, sizeof(_node));
 
129
        }
 
130
        return *this;
 
131
}
 
132
 
 
133
 
 
134
void UUID::swap(UUID& uuid)
 
135
{
 
136
        std::swap(_timeLow, uuid._timeLow);
 
137
        std::swap(_timeMid, uuid._timeMid);
 
138
        std::swap(_timeHiAndVersion, uuid._timeHiAndVersion);
 
139
        std::swap(_clockSeq, uuid._clockSeq);
 
140
        std::swap_ranges(_node, _node + 6, uuid._node);
 
141
}
 
142
 
 
143
 
 
144
void UUID::parse(const std::string& uuid)
 
145
{
 
146
        UInt32 timeLow = 0;
 
147
        UInt16 timeMid = 0;
 
148
        UInt16 timeHiAndVersion = 0;
 
149
        UInt16 clockSeq = 0;
 
150
        UInt8  node[6] = {0, 0, 0, 0, 0, 0};
 
151
        std::string::const_iterator it  = uuid.begin();
 
152
        std::string::const_iterator end = uuid.end();
 
153
        if (it != end)
 
154
        {
 
155
                for (int i = 0; i < 8; ++i)
 
156
                {
 
157
                        timeLow = timeLow*16 + nibble(*it++);
 
158
                        if (it == end) throw SyntaxException(uuid);
 
159
                }
 
160
                if (*it != '-') throw SyntaxException(uuid);
 
161
                ++it;
 
162
                for (int i = 0; i < 4; ++i)
 
163
                {
 
164
                        timeMid = timeMid*16 + nibble(*it++);
 
165
                        if (it == end) throw SyntaxException(uuid);
 
166
                }
 
167
                if (*it != '-') throw SyntaxException(uuid);
 
168
                ++it;
 
169
                for (int i = 0; i < 4; ++i)
 
170
                {
 
171
                        timeHiAndVersion = timeHiAndVersion*16 + nibble(*it++);
 
172
                        if (it == end) throw SyntaxException(uuid);
 
173
                }
 
174
                if (*it != '-') throw SyntaxException(uuid);
 
175
                ++it;
 
176
                for (int i = 0; i < 4; ++i)
 
177
                {
 
178
                        clockSeq = clockSeq*16 + nibble(*it++);
 
179
                        if (it == end) throw SyntaxException(uuid);
 
180
                }
 
181
                if (*it != '-') throw SyntaxException(uuid);
 
182
                ++it;
 
183
                for (int i = 0; i < 6; ++i)
 
184
                {
 
185
                        if (it == end) throw SyntaxException(uuid);
 
186
                        node[i] = node[i]*16 + nibble(*it++);
 
187
                        if (it == end) throw SyntaxException(uuid);
 
188
                        node[i] = node[i]*16 + nibble(*it++);
 
189
                }
 
190
                _timeLow = timeLow;
 
191
                _timeMid = timeMid;
 
192
                _timeHiAndVersion = timeHiAndVersion;
 
193
                _clockSeq = clockSeq;
 
194
                memcpy(_node, node, sizeof(_node));
 
195
        }
 
196
}
 
197
 
 
198
 
 
199
std::string UUID::toString() const
 
200
{
 
201
        std::string result;
 
202
        result.reserve(36);
 
203
        appendHex(result, _timeLow);
 
204
        result += '-';
 
205
        appendHex(result, _timeMid);
 
206
        result += '-';
 
207
        appendHex(result, _timeHiAndVersion);
 
208
        result += '-';
 
209
        appendHex(result, _clockSeq);
 
210
        result += '-';
 
211
        for (int i = 0; i < sizeof(_node); ++i)
 
212
                appendHex(result, _node[i]);
 
213
        return result;
 
214
}
 
215
 
 
216
 
 
217
void UUID::copyFrom(const char* buffer)
 
218
{
 
219
        UInt32 i32;
 
220
        UInt16 i16;
 
221
        memcpy(&i32, buffer, sizeof(i32));
 
222
        _timeLow = ByteOrder::fromNetwork(i32);
 
223
        buffer += sizeof(i32);
 
224
        memcpy(&i16, buffer, sizeof(i16));
 
225
        _timeMid = ByteOrder::fromNetwork(i16);
 
226
        buffer += sizeof(i16);
 
227
        memcpy(&i16, buffer, sizeof(i16));
 
228
        _timeHiAndVersion = ByteOrder::fromNetwork(i16);
 
229
        buffer += sizeof(i16);
 
230
        memcpy(&i16, buffer, sizeof(i16));
 
231
        _clockSeq = ByteOrder::fromNetwork(i16);
 
232
        buffer += sizeof(i16);
 
233
        memcpy(_node, buffer, sizeof(_node));
 
234
}
 
235
 
 
236
 
 
237
void UUID::copyTo(char* buffer) const
 
238
{
 
239
        UInt32 i32 = ByteOrder::toNetwork(_timeLow);
 
240
        memcpy(buffer, &i32, sizeof(i32));
 
241
        buffer += sizeof(i32);
 
242
        UInt16 i16 = ByteOrder::toNetwork(_timeMid);
 
243
        memcpy(buffer, &i16, sizeof(i16));
 
244
        buffer += sizeof(i16);
 
245
        i16 = ByteOrder::toNetwork(_timeHiAndVersion);
 
246
        memcpy(buffer, &i16, sizeof(i16));
 
247
        buffer += sizeof(i16);
 
248
        i16 = ByteOrder::toNetwork(_clockSeq);
 
249
        memcpy(buffer, &i16, sizeof(i16));
 
250
        buffer += sizeof(i16);
 
251
        memcpy(buffer, _node, sizeof(_node));
 
252
}
 
253
 
 
254
 
 
255
int UUID::variant() const
 
256
{
 
257
        int v = _clockSeq >> 13;
 
258
        if ((v & 6) == 6)
 
259
                return v;
 
260
        else if (v & 4)
 
261
                return 2;
 
262
        else
 
263
                return 0;
 
264
}
 
265
 
 
266
 
 
267
int UUID::compare(const UUID& uuid) const
 
268
{
 
269
        if (_timeLow != uuid._timeLow) return _timeLow < uuid._timeLow ? -1 : 1;
 
270
        if (_timeMid != uuid._timeMid) return _timeMid < uuid._timeMid ? -1 : 1;
 
271
        if (_timeHiAndVersion != uuid._timeHiAndVersion) return _timeHiAndVersion < uuid._timeHiAndVersion ? -1 : 1;
 
272
        if (_clockSeq != uuid._clockSeq) return _clockSeq < uuid._clockSeq ? -1 : 1;
 
273
        for (int i = 0; i < sizeof(_node); ++i)
 
274
        {
 
275
                if (_node[i] < uuid._node[i]) 
 
276
                        return -1;
 
277
                else if (_node[i] > uuid._node[i])
 
278
                        return 1;       
 
279
        }
 
280
        return 0;
 
281
}
 
282
 
 
283
 
 
284
void UUID::appendHex(std::string& str, UInt8 n) 
 
285
{
 
286
        static const char* digits = "0123456789abcdef";
 
287
        str += digits[(n >> 4) & 0xF];
 
288
        str += digits[n & 0xF];
 
289
}
 
290
 
 
291
 
 
292
void UUID::appendHex(std::string& str, UInt16 n)
 
293
{
 
294
        appendHex(str, UInt8(n >> 8));
 
295
        appendHex(str, UInt8(n & 0xFF));
 
296
}
 
297
 
 
298
 
 
299
void UUID::appendHex(std::string& str, UInt32 n)
 
300
{
 
301
        appendHex(str, UInt16(n >> 16));
 
302
        appendHex(str, UInt16(n & 0xFFFF));
 
303
}
 
304
 
 
305
 
 
306
int UUID::nibble(char hex)
 
307
{
 
308
        if (hex >= 'a' && hex <= 'f')
 
309
                return hex - 'a' + 10;
 
310
        else if (hex >= 'A' && hex <= 'F')
 
311
                return hex - 'A' + 10;
 
312
        else if (hex >= '0' && hex <= '9')
 
313
                return hex - '0';
 
314
        else
 
315
                return 0;
 
316
}
 
317
 
 
318
 
 
319
void UUID::fromNetwork()
 
320
{
 
321
        _timeLow = ByteOrder::fromNetwork(_timeLow);
 
322
        _timeMid = ByteOrder::fromNetwork(_timeMid);
 
323
        _timeHiAndVersion = ByteOrder::fromNetwork(_timeHiAndVersion);
 
324
        _clockSeq = ByteOrder::fromNetwork(_clockSeq);
 
325
}
 
326
 
 
327
 
 
328
void UUID::toNetwork()
 
329
{
 
330
        _timeLow = ByteOrder::toNetwork(_timeLow);
 
331
        _timeMid = ByteOrder::toNetwork(_timeMid);
 
332
        _timeHiAndVersion = ByteOrder::toNetwork(_timeHiAndVersion);
 
333
        _clockSeq = ByteOrder::toNetwork(_clockSeq);
 
334
}
 
335
 
 
336
 
 
337
const UUID& UUID::nil()
 
338
{
 
339
        static UUID nil;
 
340
        return nil;
 
341
}
 
342
 
 
343
 
 
344
const UUID& UUID::dns()
 
345
{
 
346
        static UUID uuidDNS("6ba7b810-9dad-11d1-80b4-00c04fd430c8");
 
347
        return uuidDNS;
 
348
}
 
349
 
 
350
        
 
351
const UUID& UUID::uri()
 
352
{
 
353
        static UUID uuidURI("6ba7b811-9dad-11d1-80b4-00c04fd430c8");
 
354
        return uuidURI;
 
355
}
 
356
 
 
357
 
 
358
const UUID& UUID::oid()
 
359
{
 
360
        static UUID uuidOID("6ba7b812-9dad-11d1-80b4-00c04fd430c8");
 
361
        return uuidOID;
 
362
}
 
363
 
 
364
 
 
365
const UUID& UUID::x500()
 
366
{
 
367
        static UUID uuidX500("6ba7b814-9dad-11d1-80b4-00c04fd430c8");
 
368
        return uuidX500;
 
369
}
 
370
 
 
371
 
 
372
} // namespace Poco