32 #ifdef HAVE_SYS_TYPES_H 33 # include <sys/types.h> 41 #include <glib/gstdio.h> 45 #ifdef HAVE_SYS_TIMES_H 46 # include <sys/times.h> 54 #include <boost/uuid/uuid.hpp> 55 #include <boost/uuid/uuid_generators.hpp> 56 #include <boost/uuid/uuid_io.hpp> 62 static QofLogModule log_module = QOF_MOD_ENGINE;
74 if (!value)
return nullptr;
77 g_return_val_if_fail (value && G_IS_VALUE (value),
nullptr);
78 g_return_val_if_fail (GNC_VALUE_HOLDS_GUID (value),
nullptr);
80 val = (
GncGUID*) g_value_get_boxed (value);
87 static gnc::GUID s_null_guid {boost::uuids::uuid { {0}}};
88 static GncGUID * s_null_gncguid {guid_convert_create (s_null_guid)};
91 char_to_num (
unsigned char c) noexcept
93 unsigned int digit = c -
'0';
94 unsigned int alpha = (c | 0x20) -
'a';
95 return digit <= 9 ? digit : alpha <= 6 ? alpha + 10 : -1;
99 fast_string_to_guid (
const char* s, uint8_t* out) noexcept
103 for (
int i = 0; i < GUID_DATA_SIZE; i++)
105 int hi = char_to_num (*s++);
106 int lo = char_to_num (*s++);
107 all_ok &= (hi >= 0 && lo >= 0);
108 out[i] = (
unsigned char)((hi << 4) | lo);
114 fast_guid_to_string (
const uint8_t* src,
char* dest) noexcept
116 static constexpr
char hex[] =
"0123456789abcdef";
117 for (
size_t i = 0; i < 16; i++)
120 *dest++ = hex[b >> 4];
121 *dest++ = hex[b & 0x0F];
132 guid_convert_create (
gnc::GUID const & guid)
148 if (guid == s_null_gncguid)
157 if (!guid)
return nullptr;
167 return s_null_gncguid;
173 std::copy (source.begin(), source.end(), target.reserved);
181 gnc::GUID temp_random {gnc::GUID::create_random ()};
182 guid_assign (*guid, temp_random);
195 return gnc::GUID::create_random ();
201 if (!guid)
return nullptr;
210 if (!str || !guid)
return nullptr;
211 fast_guid_to_string (guid->reserved, str);
219 if (!guid || !str || !*str)
return false;
221 if (fast_string_to_guid (str, guid->reserved))
226 guid_assign (*guid, gnc::GUID::from_string (str));
230 PINFO(
"Failed to construct a GUID from %s", str);
239 if (guid_1 == guid_2)
return true;
240 if (!guid_1 || !guid_2)
return false;
243 return temp1 == temp2;
249 if (guid_1 == guid_2)
return 0;
250 if (!guid_1)
return -1;
251 if (!guid_2)
return 1;
266 PERR (
"received nullptr guid pointer.");
269 GncGUID const & guid = * reinterpret_cast <
GncGUID const *> (ptr);
273 std::for_each (temp.begin (), temp.end (), [&hash] (
unsigned char a) {
283 return guid_equal (reinterpret_cast<const GncGUID*> (guid_a),
284 reinterpret_cast<const GncGUID*> (guid_b));
295 gnc_string_to_guid (
const GValue *src, GValue *dest)
299 const gchar *as_string;
301 g_return_if_fail (G_VALUE_HOLDS_STRING (src) &&
302 GNC_VALUE_HOLDS_GUID (dest));
304 as_string = g_value_get_string (src);
309 g_value_take_boxed (dest, guid);
313 gnc_guid_to_string (
const GValue *src, GValue *dest)
317 g_return_if_fail (G_VALUE_HOLDS_STRING (dest) &&
318 GNC_VALUE_HOLDS_GUID (src));
322 g_value_set_string (dest, str);
326 g_value_register_transform_func (G_TYPE_STRING,
330 g_value_register_transform_func (g_define_type_id,
339 GUID::create_random () noexcept
341 static boost::uuids::random_generator gen;
345 GUID::GUID (boost::uuids::uuid
const & other) noexcept
346 : implementation (other)
351 GUID::null_guid () noexcept
357 GUID::to_string () const noexcept
360 out.resize (implementation.size() * 2);
361 fast_guid_to_string (implementation.data, out.data());
366 GUID::from_string (
const char* str)
369 throw guid_syntax_exception {};
372 if (fast_string_to_guid(str, bytes))
374 boost::uuids::uuid u;
375 std::memcpy(u.data, bytes, 16);
380 static boost::uuids::string_generator strgen;
385 throw guid_syntax_exception {};
390 GUID::is_valid_guid (
const char* str)
393 if (fast_string_to_guid(str, bytes))
397 static boost::uuids::string_generator strgen;
407 guid_syntax_exception::guid_syntax_exception () noexcept
408 : invalid_argument {
"Invalid syntax for guid."}
412 GUID::GUID (
GncGUID const & other) noexcept
413 : implementation {{other.reserved[0] , other.reserved[1]
414 , other.reserved[2], other.reserved[3]
415 , other.reserved[4], other.reserved[5]
416 , other.reserved[6], other.reserved[7]
417 , other.reserved[8], other.reserved[9]
418 , other.reserved[10], other.reserved[11]
419 , other.reserved[12], other.reserved[13]
420 , other.reserved[14], other.reserved[15]}
427 GUID::end () const noexcept -> decltype (implementation.end ())
429 return implementation.end ();
433 GUID::begin () const noexcept -> decltype (implementation.begin ())
435 return implementation.begin ();
439 GUID::operator < (GUID
const & other) noexcept
441 return implementation < other.implementation;
444 bool operator == (GUID
const & lhs,
GncGUID const & rhs) noexcept
446 return lhs.implementation == GUID(rhs).implementation;
450 operator != (GUID
const & one, GUID
const & two) noexcept
452 return one.implementation != two.implementation;
455 GUID & GUID::operator = (GUID && other) noexcept
457 boost::uuids::swap (other.implementation, implementation);
461 GUID::operator
GncGUID () const noexcept
464 guid_assign (ret, *
this);
void guid_replace(GncGUID *guid)
Generate a new guid.
#define PINFO(format, args...)
Print an informational note.
GncGUID guid_new_return(void)
Generate a new id.
GncGUID * guid_copy(const GncGUID *guid)
Returns a newly allocated GncGUID that matches the passed-in GUID.
gboolean string_to_guid(const gchar *string, GncGUID *guid)
Given a string, replace the given guid with the parsed one unless the given value is null...
GncGUID * guid_new(void)
Allocate and construct a new GUID.
globally unique ID User API
GHashTable * guid_hash_table_new(void)
Returns a GHashTable with <GUID*> as key and a <gpointer> as value and no destructor functions for ke...
gchar * guid_to_string_buff(const GncGUID *guid, gchar *str)
The guid_to_string_buff() routine puts a null-terminated string encoding of the id into the memory po...
guint guid_hash_to_guint(gconstpointer ptr)
Hash function for a GUID.
const GncGUID * gnc_value_get_guid(const GValue *value)
gnc_value_get_guid
#define PERR(format, args...)
Log a serious error.
GncGUID * guid_malloc(void)
Allocate memory for a GUID.
gboolean guid_equal(const GncGUID *guid_1, const GncGUID *guid_2)
Given two GUIDs, return TRUE if they are non-NULL and equal.
#define GUID_ENCODING_LENGTH
Number of characters needed to encode a guid as a string not including the null terminator.
gchar * guid_to_string(const GncGUID *guid)
The guid_to_string() routine returns a null-terminated string encoding of the id. ...
const GncGUID * guid_null(void)
Returns a GncGUID which is guaranteed to never reference any entity.
The type used to store guids in C.
gint guid_g_hash_table_equal(gconstpointer guid_a, gconstpointer guid_b)
Equality function for two GUIDs in a GHashTable.