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>
62static 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);
87static gnc::GUID s_null_guid {boost::uuids::uuid { {0}}};
88static GncGUID * s_null_gncguid {guid_convert_create (s_null_guid)};
91char_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 <= 5 ? alpha + 10 : -1;
99fast_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)(((
unsigned)hi << 4) | (
unsigned)lo);
114fast_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];
132guid_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);
217string_to_guid (
const char * str,
GncGUID * guid)
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 return guid_compare (guid_1, guid_2) == 0;
245 if (guid_1 == guid_2)
return 0;
246 if (!guid_1)
return -1;
247 if (!guid_2)
return 1;
248 return std::memcmp (guid_1->reserved, guid_2->reserved, GUID_DATA_SIZE);
259 PERR (
"received nullptr guid pointer.");
264 memcpy (&rv, &g->reserved[12], sizeof (guint));
272 reinterpret_cast<const GncGUID*
> (guid_b));
283gnc_string_to_guid (
const GValue *src, GValue *dest)
287 const gchar *as_string;
289 g_return_if_fail (G_VALUE_HOLDS_STRING (src) &&
290 GNC_VALUE_HOLDS_GUID (dest));
292 as_string = g_value_get_string (src);
295 string_to_guid (as_string, guid);
297 g_value_take_boxed (dest, guid);
301gnc_guid_to_string (
const GValue *src, GValue *dest)
305 g_return_if_fail (G_VALUE_HOLDS_STRING (dest) &&
306 GNC_VALUE_HOLDS_GUID (src));
310 g_value_take_string (dest, str);
314 g_value_register_transform_func (G_TYPE_STRING,
318 g_value_register_transform_func (g_define_type_id,
327GUID::create_random () noexcept
329 static boost::uuids::random_generator gen;
333GUID::GUID (boost::uuids::uuid
const & other) noexcept
334 : implementation (other)
339GUID::null_guid () noexcept
345GUID::to_string () const noexcept
348 out.resize (implementation.size() * 2);
349 fast_guid_to_string (implementation.data, out.data());
354GUID::from_string (
const char* str)
357 throw guid_syntax_exception {};
359 if (boost::uuids::uuid u; fast_string_to_guid(str, u.data))
363 static boost::uuids::string_generator strgen;
368 throw guid_syntax_exception {};
373GUID::is_valid_guid (
const char* str)
376 if (fast_string_to_guid(str, bytes))
380 static boost::uuids::string_generator strgen;
390guid_syntax_exception::guid_syntax_exception () noexcept
391 : invalid_argument {
"Invalid syntax for guid."}
395GUID::GUID (
GncGUID const & other) noexcept
396: implementation {{other.reserved[0] , other.reserved[1]
397 , other.reserved[2], other.reserved[3]
398 , other.reserved[4], other.reserved[5]
399 , other.reserved[6], other.reserved[7]
400 , other.reserved[8], other.reserved[9]
401 , other.reserved[10], other.reserved[11]
402 , other.reserved[12], other.reserved[13]
403 , other.reserved[14], other.reserved[15]}
410GUID::end () const noexcept -> decltype (implementation.end ())
412 return implementation.end ();
416GUID::begin () const noexcept -> decltype (implementation.begin ())
418 return implementation.begin ();
422GUID::operator < (GUID
const & other)
noexcept
424 return implementation < other.implementation;
427bool operator == (GUID
const & lhs,
GncGUID const & rhs)
noexcept
429 return lhs.implementation == GUID(rhs).implementation;
433operator != (GUID
const & one, GUID
const & two)
noexcept
435 return one.implementation != two.implementation;
438GUID & GUID::operator = (GUID && other)
noexcept
440 boost::uuids::swap (other.implementation, implementation);
444GUID::operator
GncGUID () const noexcept
447 guid_assign (ret, *
this);
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(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.
#define GUID_ENCODING_LENGTH
Number of characters needed to encode a guid as a string not including the null terminator.
gboolean guid_equal(const GncGUID *guid_1, const GncGUID *guid_2)
Given two GUIDs, return TRUE if they are non-NULL and equal.
guint guid_hash_to_guint(gconstpointer ptr)
Hash function for a GUID.
void guid_replace(GncGUID *guid)
Generate a new guid.
GncGUID * guid_copy(const GncGUID *guid)
Returns a newly allocated GncGUID that matches the passed-in GUID.
const GncGUID * gnc_value_get_guid(const GValue *value)
gnc_value_get_guid
gint guid_g_hash_table_equal(gconstpointer guid_a, gconstpointer guid_b)
Equality function for two GUIDs in a GHashTable.
GncGUID guid_new_return(void)
Generate a new id.
GncGUID * guid_malloc(void)
Allocate memory for a GUID.
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...
GncGUID * guid_new(void)
Allocate and construct a new GUID.
#define PINFO(format, args...)
Print an informational note.
#define PERR(format, args...)
Log a serious error.
globally unique ID User API
The type used to store guids in C.