1 /* === S Y N F I G ========================================================= */
3 ** \brief Template File
8 ** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
9 ** Copyright (c) 2007, 2008 Chris Moore
11 ** This package is free software; you can redistribute it and/or
12 ** modify it under the terms of the GNU General Public License as
13 ** published by the Free Software Foundation; either version 2 of
14 ** the License, or (at your option) any later version.
16 ** This package is distributed in the hope that it will be useful,
17 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
18 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 ** General Public License for more details.
22 /* ========================================================================= */
24 /* === H E A D E R S ======================================================= */
34 #include "quick_rng.h"
35 #include <sys/types.h>
39 #include <ETL/stringf>
57 /* === U S I N G =========================================================== */
61 using namespace synfig;
63 /* === M A C R O S ========================================================= */
65 #define MANUAL_GUID_CALC
67 /* === G L O B A L S ======================================================= */
69 /* === P R O C E D U R E S ================================================= */
71 /* === M E T H O D S ======================================================= */
73 #define GUID_RNG quick_rng
74 //#define GUID_RNG subtractive_rng
78 #ifdef MANUAL_GUID_CALC
80 static GUID_RNG _a, _b;
81 static void _set_up_rand_long_long(uint64_t &x);
82 static void _get_rand_long_long(uint64_t &x);
83 static void (*get_rand_long_long)(uint64_t&)=_set_up_rand_long_long;
84 static void _set_up_rand_long_long(uint64_t &x)
87 // synfig::info("Starting up GUID system...");
89 _a=GUID_RNG(time(0)+clock());
91 get_rand_long_long=_get_rand_long_long;
92 _get_rand_long_long(x);
95 static void _get_rand_long_long(uint64_t &x)
97 //subtractive_rng _c(clock());
98 unsigned short* data(reinterpret_cast<unsigned short *>(&x));
106 // Use OS-Dependent method
110 static void get_rand_long_long(uint64_t &x)
112 _GUID* guid(reinterpret_cast<_GUID*>(&x));
119 static void _set_up_rand_long_long(uint64_t &x);
120 static void _get_rand_long_long(uint64_t &x);
121 static void (*get_rand_long_long)(uint64_t&)=_set_up_rand_long_long;
122 static void _set_up_rand_long_long(uint64_t &x)
125 // synfig::info("Starting up GUID system...");
127 rand_fd=open("/dev/urandom",O_RDONLY);
128 get_rand_long_long=_get_rand_long_long;
129 _get_rand_long_long(x);
132 static void _get_rand_long_long(uint64_t &x){ read(rand_fd,&x,sizeof(x));}
140 synfig::GUID::make_unique()
142 get_rand_long_long(data.u_64.a);
143 get_rand_long_long(data.u_64.b);
147 synfig::GUID::hasher(const String& str)
150 /* http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2003/n1456.html says:
152 * "Some earlier hash table implementations gave char* special
153 * treatment: it specialized the default hash function to look
154 * at character array being pointed to, rather than the pointer
155 * itself. This proposal removes that special treatment."
157 * Unfortunately, the older implementation doesn't seem to want to
158 * accept Strings, so we're left with this conditional compilation.
160 # ifdef FUNCTIONAL_HASH_ON_STRING
161 HASH_MAP_NAMESPACE::hash<String> string_hash_;
162 const unsigned int seed(string_hash_(str));
163 # else // FUNCTIONAL_HASH_ON_STRING
164 HASH_MAP_NAMESPACE::hash<const char*> string_hash_;
165 const unsigned int seed(string_hash_(str.c_str()));
166 # endif // FUNCTIONAL_HASH_ON_STRING
168 unsigned int seed(0x3B642879);
169 for(unsigned int i=0;i<str.size();i++)
171 seed^=(seed*str[i])*i;
172 seed=(seed>>(32-(i%24)))^(seed<<(i%24));
176 GUID_RNG random(seed);
178 ret.data.u_32.a=random(~(unsigned int)0);
179 ret.data.u_32.b=random(~(unsigned int)0);
180 ret.data.u_32.c=random(~(unsigned int)0);
181 ret.data.u_32.d=random(~(unsigned int)0);
186 synfig::GUID::hasher(int i)
190 ret.data.u_32.a=random(~(unsigned int)0);
191 ret.data.u_32.b=random(~(unsigned int)0);
192 ret.data.u_32.c=random(~(unsigned int)0);
193 ret.data.u_32.d=random(~(unsigned int)0);
198 synfig::GUID::get_string()const
200 return strprintf("%08X%08X%08X%08X",data.u_32.a,data.u_32.b,data.u_32.c,data.u_32.d);
203 synfig::GUID::GUID(const String &str)
205 strscanf(str,"%08X%08X%08X%08X",&data.u_32.a,&data.u_32.b,&data.u_32.c,&data.u_32.d);