Simplified some of the GUID code.

This change applies some recommendations from jralls. It better utilizes for loops,
and usage of swap. We also try to make sure the null guid is not freed since it's
reused, and catch a c++ exception to make sure it doens't escape into C code when
parsing a GUID.
This commit is contained in:
lmat 2014-07-28 17:03:07 -04:00
parent ce94872ec8
commit 726ab02d65
2 changed files with 41 additions and 39 deletions

View File

@ -85,6 +85,15 @@ gnc_value_get_guid (const GValue *value)
return val; return val;
} }
static GncGUID * nullguid {reinterpret_cast<GncGUID*> (new boost::uuids::uuid{0})};
/*It looks like we are expected to provide the same pointer every time from this function*/
const GncGUID *
guid_null (void)
{
return nullguid;
}
/* Memory management routines ***************************************/ /* Memory management routines ***************************************/
GncGUID * GncGUID *
@ -99,7 +108,11 @@ guid_free (GncGUID *guid)
{ {
if (!guid) if (!guid)
return; return;
if (guid == nullguid)
/*!!Don't delete that!!*/
return;
delete reinterpret_cast<boost::uuids::uuid*> (guid); delete reinterpret_cast<boost::uuids::uuid*> (guid);
guid = nullptr;
} }
@ -111,23 +124,15 @@ guid_copy (const GncGUID *guid)
return reinterpret_cast<GncGUID*> (ret); return reinterpret_cast<GncGUID*> (ret);
} }
static GncGUID * nullguid {reinterpret_cast<GncGUID*> (new boost::uuids::uuid{0})};
/*It looks like we are expected to provide the same pointer every time from this function*/
const GncGUID *
guid_null (void)
{
return nullguid;
}
/*Takes an allocated guid pointer and constructs it in place*/ /*Takes an allocated guid pointer and constructs it in place*/
void void
guid_replace (GncGUID *guid) guid_replace (GncGUID *guid)
{ {
static boost::uuids::random_generator gen; static boost::uuids::random_generator gen;
boost::uuids::uuid * val {reinterpret_cast<boost::uuids::uuid*> (guid)}; boost::uuids::uuid * val {reinterpret_cast<boost::uuids::uuid*> (guid)};
val->boost::uuids::uuid::~uuid(); val->boost::uuids::uuid::~uuid ();
new (val) boost::uuids::uuid (gen ()); boost::uuids::uuid temp (gen ());
val->swap (temp);
} }
GncGUID * GncGUID *
@ -169,25 +174,13 @@ guid_to_string_buff (const GncGUID * guid, gchar *str)
{ {
if (!str || !guid) return NULL; if (!str || !guid) return NULL;
static boost::uuids::string_generator str_gen; boost::uuids::uuid const & tempg = *reinterpret_cast<boost::uuids::uuid const *> (guid);
stringstream ostr; unsigned destspot {0};
boost::uuids::uuid const & tempg = *reinterpret_cast<boost::uuids::uuid const *>(guid); string const & val {to_string (tempg)};
ostr << tempg; for (auto val_char : val)
string const & val (ostr.str()); if (val_char != '-')
/*unsigned size {val.size()}; str [destspot++] = val_char;
size must equal GUID_ENCODING_LENGTH*/
unsigned stringspot{0};
for (unsigned destspot{0}; destspot < GUID_ENCODING_LENGTH; ++destspot, ++stringspot){
switch (stringspot){
/*there are hyphens in boost's output, and we need to skip them in our output*/
case 8:
case 13:
case 18:
case 23:
++stringspot;
}
str[destspot] = val[stringspot];
}
str[GUID_ENCODING_LENGTH] = '\0'; str[GUID_ENCODING_LENGTH] = '\0';
return &str[GUID_ENCODING_LENGTH]; return &str[GUID_ENCODING_LENGTH];
} }
@ -195,9 +188,19 @@ guid_to_string_buff (const GncGUID * guid, gchar *str)
gboolean gboolean
string_to_guid (const char * str, GncGUID * guid) string_to_guid (const char * str, GncGUID * guid)
{ {
if (!guid || !str)
return false;
try
{
static boost::uuids::string_generator strgen; static boost::uuids::string_generator strgen;
boost::uuids::uuid * converted {reinterpret_cast<boost::uuids::uuid*> (guid)}; boost::uuids::uuid * converted {reinterpret_cast<boost::uuids::uuid*> (guid)};
new (converted) boost::uuids::uuid (strgen (str)); new (converted) boost::uuids::uuid (strgen (str));
}
catch (...)
{
return false;
}
return true; return true;
} }
@ -236,11 +239,10 @@ guid_hash_to_guint (gconstpointer ptr)
guint hash {0}; guint hash {0};
unsigned retspot {0}; unsigned retspot {0};
boost::uuids::uuid::const_iterator guidspot {guid->begin ()}; for (auto guidspot : *guid)
while (guidspot != guid->end ()){ {
hash <<= 4; hash <<= 4;
hash |= *guidspot; hash |= guidspot;
++guidspot;
} }
return hash; return hash;
} }

View File

@ -151,8 +151,8 @@ gchar * guid_to_string_buff (const GncGUID * guid, /*@ out @*/ gchar *buff);
* This function accepts both uppor and lower case hex digits. If * This function accepts both uppor and lower case hex digits. If
* letters outside the range of [a-fA-F] are passed, they are silently * letters outside the range of [a-fA-F] are passed, they are silently
* replaced. If non-alphanumeric digits are given, this function will * replaced. If non-alphanumeric digits are given, this function will
either return false or replace those values with others. * either return false or replace those values with others.
. */ */
gboolean string_to_guid(const gchar * string, /*@ out @*/ GncGUID * guid); gboolean string_to_guid(const gchar * string, /*@ out @*/ GncGUID * guid);