1 /*
2 * Copyright (C) 2009 Tommi Maekitalo
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License as
6 * published by the Free Software Foundation; either version 2 of the
7 * License, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * is provided AS IS, WITHOUT ANY WARRANTY; without even the implied
11 * warranty of MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, and
12 * NON-INFRINGEMENT. See the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 *
18 */
19
20 #include <zim/uuid.h>
21 #include <iostream>
22 #include <time.h>
23 #include <zim/zim.h> // necessary to have the new types
24 #include "log.h"
25 #include "md5.h"
26
27 #ifdef _WIN32
28
29 # include <time.h>
30 # include <windows.h>
gettimeofday(struct timeval * tp,void * tzp)31 int gettimeofday(struct timeval* tp, void* tzp) {
32 DWORD t;
33 t = timeGetTime();
34 tp->tv_sec = t / 1000;
35 tp->tv_usec = t % 1000;
36 return 0;
37 }
38
39 #define getpid GetCurrentProcessId
40
41 #else
42 # include <sys/time.h>
43 #endif
44
45 log_define("zim.uuid")
46
47 namespace zim
48 {
49 namespace
50 {
51 char hex[] = "0123456789abcdef";
hi(char v)52 inline char hi(char v)
53 { return hex[(v >> 4) & 0xf]; }
54
lo(char v)55 inline char lo(char v)
56 { return hex[v & 0xf]; }
57 }
58
generate(std::string value)59 Uuid Uuid::generate(std::string value)
60 {
61 Uuid ret;
62 struct zim_MD5_CTX md5ctx;
63 zim_MD5Init(&md5ctx);
64
65 if ( value.empty() ) {
66 struct timeval tv;
67 gettimeofday(&tv, 0);
68
69 clock_t c = clock();
70
71 zim_MD5Update(&md5ctx, reinterpret_cast<const uint8_t*>(&c), sizeof(clock_t));
72 zim_MD5Update(&md5ctx, reinterpret_cast<const uint8_t*>(&tv), sizeof(struct timeval));
73 } else {
74 zim_MD5Update(&md5ctx, reinterpret_cast<const uint8_t*>(value.data()), value.size());
75 }
76 zim_MD5Final(reinterpret_cast<uint8_t*>(&ret.data[0]), &md5ctx);
77
78 log_debug("generated uuid: " << ret.data);
79
80 return ret;
81 }
82
operator <<(std::ostream & out,const Uuid & uuid)83 std::ostream& operator<< (std::ostream& out, const Uuid& uuid)
84 {
85 for (unsigned n = 0; n < 4; ++n)
86 out << hi(uuid.data[n]) << lo(uuid.data[n]);
87 out << '-';
88 for (unsigned n = 4; n < 6; ++n)
89 out << hi(uuid.data[n]) << lo(uuid.data[n]);
90 out << '-';
91 for (unsigned n = 6; n < 8; ++n)
92 out << hi(uuid.data[n]) << lo(uuid.data[n]);
93 out << '-';
94 for (unsigned n = 8; n < 10; ++n)
95 out << hi(uuid.data[n]) << lo(uuid.data[n]);
96 out << '-';
97 for (unsigned n = 10; n < 16; ++n)
98 out << hi(uuid.data[n]) << lo(uuid.data[n]);
99 return out;
100 }
101
102 }
103