gnucash stable: Multiple changes pushed
Christopher Lam
clam at code.gnucash.org
Fri Nov 28 18:58:38 EST 2025
Updated via https://github.com/Gnucash/gnucash/commit/534bea74 (commit)
via https://github.com/Gnucash/gnucash/commit/3c5a1801 (commit)
from https://github.com/Gnucash/gnucash/commit/7e5f5597 (commit)
commit 534bea748f556097c45695180d4adb71c359f9bf
Author: Christopher Lam <christopher.lck at gmail.com>
Date: Sat Nov 29 07:57:14 2025 +0800
[guid.cpp] Specialise guid<->32-byte string
- string->guid has branch-lite unrollable loop, fallback to slow
boost parser
- guid->string uses lookup table
- avoids creating several temporary heap-allocated std::strings
diff --git a/libgnucash/engine/guid.cpp b/libgnucash/engine/guid.cpp
index c65ae7261a..0fd36fd3d7 100644
--- a/libgnucash/engine/guid.cpp
+++ b/libgnucash/engine/guid.cpp
@@ -87,6 +87,41 @@ GncGUID * guid_convert_create (gnc::GUID const &);
static gnc::GUID s_null_guid {boost::uuids::uuid { {0}}};
static GncGUID * s_null_gncguid {guid_convert_create (s_null_guid)};
+static inline int
+char_to_num (unsigned char c) noexcept
+{
+ unsigned int digit = c - '0';
+ unsigned int alpha = (c | 0x20) - 'a';
+ return digit <= 9 ? digit : alpha <= 6 ? alpha + 10 : -1;
+}
+
+static inline bool
+fast_string_to_guid (const char* s, uint8_t* out) noexcept
+{
+ if (strnlen (s, GUID_ENCODING_LENGTH + 1) != GUID_ENCODING_LENGTH) return false;
+ bool all_ok = true;
+ for (int i = 0; i < GUID_DATA_SIZE; i++)
+ {
+ int hi = char_to_num (*s++);
+ int lo = char_to_num (*s++);
+ all_ok &= (hi >= 0 && lo >= 0);
+ out[i] = (unsigned char)((hi << 4) | lo);
+ }
+ return all_ok;
+}
+
+static inline void
+fast_guid_to_string (const uint8_t* src, char* dest) noexcept
+{
+ static constexpr char hex[] = "0123456789abcdef";
+ for (size_t i = 0; i < 16; i++)
+ {
+ uint8_t b = src[i];
+ *dest++ = hex[b >> 4];
+ *dest++ = hex[b & 0x0F];
+ }
+}
+
/* Memory management routines ***************************************/
/**
@@ -164,23 +199,18 @@ gchar *
guid_to_string (const GncGUID * guid)
{
if (!guid) return nullptr;
- gnc::GUID temp {*guid};
- auto temp_str = temp.to_string ();
- return g_strdup (temp_str.c_str ());
+ char* buffer = g_new (char, GUID_ENCODING_LENGTH + 1);
+ guid_to_string_buff (guid, buffer);
+ return buffer;
}
gchar *
guid_to_string_buff (const GncGUID * guid, gchar *str)
{
if (!str || !guid) return nullptr;
-
- gnc::GUID temp {*guid};
- auto val = temp.to_string ();
- /*We need to be sure to copy the terminating null character.
- * The standard guarantees that std::basic_string::c_str ()
- * returns with a terminating null character, too.*/
- std::copy (val.c_str (), val.c_str () + val.size () + 1, str);
- return str + val.size ();
+ fast_guid_to_string (guid->reserved, str);
+ str[GUID_ENCODING_LENGTH] = '\0';
+ return str;
}
gboolean
@@ -188,6 +218,9 @@ string_to_guid (const char * str, GncGUID * guid)
{
if (!guid || !str || !*str) return false;
+ if (fast_string_to_guid (str, guid->reserved))
+ return true;
+
try
{
guid_assign (*guid, gnc::GUID::from_string (str));
@@ -323,12 +356,10 @@ GUID::null_guid () noexcept
std::string
GUID::to_string () const noexcept
{
- auto const & val = boost::uuids::to_string (implementation);
- std::string ret;
- std::for_each (val.begin (), val.end (), [&ret] (char a) {
- if (a != '-') ret.push_back (a);
- });
- return ret;
+ std::string out;
+ out.resize (implementation.size() * 2);
+ fast_guid_to_string (implementation.data, out.data());
+ return out;
}
GUID
@@ -336,6 +367,14 @@ GUID::from_string (const char* str)
{
if (!str)
throw guid_syntax_exception {};
+
+ uint8_t bytes[16];
+ if (fast_string_to_guid(str, bytes))
+ {
+ boost::uuids::uuid u;
+ std::memcpy(u.data, bytes, 16);
+ return GUID{u};
+ }
try
{
static boost::uuids::string_generator strgen;
@@ -350,6 +389,9 @@ GUID::from_string (const char* str)
bool
GUID::is_valid_guid (const char* str)
{
+ uint8_t bytes[16];
+ if (fast_string_to_guid(str, bytes))
+ return true;
try
{
static boost::uuids::string_generator strgen;
commit 3c5a1801e29ed824287e95fdca57084c965e757a
Author: Christopher Lam <christopher.lck at gmail.com>
Date: Fri Nov 28 00:31:12 2025 +0800
[guid.cpp] fix guid==nullptr comparison retvals
- if guid_1 guid_2 are both null they should return int(0) or bool(true)
diff --git a/libgnucash/engine/guid.cpp b/libgnucash/engine/guid.cpp
index 9526a06778..c65ae7261a 100644
--- a/libgnucash/engine/guid.cpp
+++ b/libgnucash/engine/guid.cpp
@@ -203,8 +203,8 @@ string_to_guid (const char * str, GncGUID * guid)
gboolean
guid_equal (const GncGUID *guid_1, const GncGUID *guid_2)
{
- if (!guid_1 || !guid_2)
- return !guid_1 && !guid_2;
+ if (guid_1 == guid_2) return true;
+ if (!guid_1 || !guid_2) return false;
gnc::GUID temp1 {*guid_1};
gnc::GUID temp2 {*guid_2};
return temp1 == temp2;
@@ -213,8 +213,9 @@ guid_equal (const GncGUID *guid_1, const GncGUID *guid_2)
gint
guid_compare (const GncGUID *guid_1, const GncGUID *guid_2)
{
- if (!guid_1 || !guid_2)
- return !guid_1 && !guid_2;
+ if (guid_1 == guid_2) return 0;
+ if (!guid_1) return -1;
+ if (!guid_2) return 1;
gnc::GUID temp1 {*guid_1};
gnc::GUID temp2 {*guid_2};
if (temp1 < temp2)
Summary of changes:
libgnucash/engine/guid.cpp | 85 ++++++++++++++++++++++++++++++++++------------
1 file changed, 64 insertions(+), 21 deletions(-)
More information about the gnucash-changes
mailing list