summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonathan Bradley <jcb@pikum.xyz>2025-03-27 16:13:10 -0400
committerJonathan Bradley <jcb@pikum.xyz>2025-03-27 16:13:10 -0400
commitc65204648f0a81cce25c12c6dcd58d76810ac303 (patch)
tree4634f98672d00e321ab19d51629af130f1a27fbf
parentbe07962dc264b732f9facafec7bbe4019bf91ad2 (diff)
pkuuid: add << and >> for const char *
-rw-r--r--pkuuid.h76
-rw-r--r--test/pkuuid.c36
-rw-r--r--test/pkuuid.cpp74
3 files changed, 161 insertions, 25 deletions
diff --git a/pkuuid.h b/pkuuid.h
index 0de7f6b..6a89e77 100644
--- a/pkuuid.h
+++ b/pkuuid.h
@@ -19,12 +19,15 @@ void pk_uuid_teardown();
struct pk_uuid pk_uuid_new_v7();
bool pk_uuid_equals(struct pk_uuid lhs, struct pk_uuid rhs);
+bool pk_uuid_parse(const char *s, struct pk_uuid *uuid);
#if defined(__cplusplus)
#include <ostream>
#include <iomanip>
std::ostream& operator<<(std::ostream &o, const struct pk_uuid& uuid);
std::istream& operator>>(std::istream &i, struct pk_uuid& uuid);
+const char* operator>>(const char *s, struct pk_uuid& uuid);
+struct pk_uuid& operator<<(struct pk_uuid& uuid, const char *s);
bool operator==(const pk_uuid &lhs, const pk_uuid &rhs);
bool operator!=(const pk_uuid &lhs, const pk_uuid &rhs);
#endif
@@ -33,7 +36,8 @@ bool operator!=(const pk_uuid &lhs, const pk_uuid &rhs);
#ifdef PK_IMPL_UUID
-#include <stdatomic.h>
+#include "./pkstn.h" /* deleteme */
+
#include <stdlib.h>
#include <stdint.h>
@@ -147,8 +151,34 @@ bool pk_uuid_equals(struct pk_uuid lhs, struct pk_uuid rhs)
return true;
}
+bool pk_uuid_parse(const char *s, struct pk_uuid *uuid)
+{
+ // ffffffff-ffff-ffff-ffff-ffffffffffff
+ // 0 8 13 18 23 35
+ char c[3] = {'\0','\0','\0'};
+ unsigned char k, kk;
+ if (s == nullptr) goto err_out;
+ for (k = 0, kk = 0; k < 36; k+=2, ++kk) {
+ if (s[k] == '\0' || s[k+1] == '\0') goto err_out;
+ if (k == 8 || k == 13 || k == 18 || k == 23) {
+ if (s[k] != '-') goto err_out;
+ k -= 1;
+ kk -= 1;
+ continue;
+ }
+ c[0] = s[k];
+ c[1] = s[k+1];
+ if (pk_stn_uint8_t(&uuid->uuid[kk], c, 16) != PK_STN_RES_SUCCESS) {
+ goto err_out;
+ }
+ }
+ return true;
+err_out:
+ *uuid = pk_uuid_zed;
+ return false;
+}
+
#if defined(__cplusplus)
-#include "./pkstn.h" /* deleteme */
std::ostream&
operator<<(std::ostream &o, const struct pk_uuid& uuid)
{
@@ -188,33 +218,35 @@ operator<<(std::ostream &o, const struct pk_uuid& uuid)
std::istream&
operator>>(std::istream &i, struct pk_uuid& uuid)
{
- char c[3];
- char k = 0;
- char offset = 0;
- c[2] = '\0';
- for (k = 0; k < 20; ++k) {
- if (k == 4 || k == 7 || k == 10 || k == 13) {
- offset += 1;
- c[0] = i.peek();
- if (c[0] != '-') {
- goto err_out;
- }
- i.get(); // burn
- continue;
- }
- i.get(c[0]);
- i.get(c[1]);
- if (pk_stn_uint8_t(&uuid.uuid[k - offset], c, 16) != PK_STN_RES_SUCCESS) {
- goto err_out;
- }
+ char u[36];
+ i.read(u, 36);
+ if (i.rdstate() & std::ios::failbit) {
+ goto err_out;
+ } else if (pk_uuid_parse(u, &uuid) == false) {
+ goto err_out;
}
return i;
err_out:
- i.seekg(-(((k + 1) * 2) + offset), std::ios_base::cur);
uuid = pk_uuid_zed;
+ i.seekg(-36, std::ios_base::cur);
+ i.setstate(std::ios::failbit);
return i;
}
+const char * operator>>(const char *s, struct pk_uuid& uuid)
+{
+ if (pk_uuid_parse(s, &uuid)) {
+ return s+36;
+ }
+ return s;
+}
+
+struct pk_uuid& operator<<(struct pk_uuid& uuid, const char *s)
+{
+ pk_uuid_parse(s, &uuid);
+ return uuid;
+}
+
bool operator==(const pk_uuid &lhs, const pk_uuid &rhs) { return pk_uuid_equals(lhs, rhs); }
bool operator!=(const pk_uuid &lhs, const pk_uuid &rhs) { return !pk_uuid_equals(lhs, rhs); }
diff --git a/test/pkuuid.c b/test/pkuuid.c
index 42cf3e4..3491ea3 100644
--- a/test/pkuuid.c
+++ b/test/pkuuid.c
@@ -110,6 +110,42 @@ main(int argc, char *argv[])
fprintf(stdout, "\n");
}
+ // test parse
+ {
+ bool res;
+ unsigned char i;
+ struct pk_uuid idm;
+ struct pk_uuid idz;
+ struct pk_uuid id;
+ struct pk_uuid id_expected = { .uuid = { 0x67, 0xe5, 0x98, 0x5c, 0x82, 0xb7, 0x72, 0x69, 0x94, 0xda, 0x81, 0x9c, 0x18, 0xa7, 0xec, 0xe8 } };
+ const char * s_idm = "ffffffff-ffff-ffff-ffff-ffffffffffff";
+ const char * s_idz = "00000000-0000-0000-0000-000000000000";
+ const char * s_id = "67e5985c-82b7-7269-94da-819c18a7ece8";
+
+ fprintf(stdout, "[%s] test parse.\n", __FILE__);
+ res = pk_uuid_parse(s_idm, &idm);
+ fprintf(stdout, "[%s] expected: " pk_uuid_printf_format "\n", __FILE__, pk_uuid_printf_var(pk_uuid_max));
+ fprintf(stdout, "[%s] parsed : " pk_uuid_printf_format "\n", __FILE__, pk_uuid_printf_var(idm));
+ if (res == false) exit(1);
+
+ res = pk_uuid_parse(s_idz, &idz);
+ fprintf(stdout, "[%s] expected: " pk_uuid_printf_format "\n", __FILE__, pk_uuid_printf_var(pk_uuid_zed));
+ fprintf(stdout, "[%s] parsed : " pk_uuid_printf_format "\n", __FILE__, pk_uuid_printf_var(idz));
+ if (res == false) exit(1);
+
+ res = pk_uuid_parse(s_id, &id);
+ fprintf(stdout, "[%s] expected: " pk_uuid_printf_format "\n", __FILE__, pk_uuid_printf_var(id_expected));
+ fprintf(stdout, "[%s] parsed : " pk_uuid_printf_format "\n", __FILE__, pk_uuid_printf_var(id));
+ if (res == false) exit(1);
+
+ for (i = 0; i < 16; ++i) {
+ if (idm.uuid[i] != 0xFF) exit(1);
+ if (idz.uuid[i] != 0x00) exit(1);
+ if (id.uuid[i] != id_expected.uuid[i]) exit(1);
+ }
+ fprintf(stdout, "\n");
+ }
+
{
double ms;
const int count = 1000;
diff --git a/test/pkuuid.cpp b/test/pkuuid.cpp
index da59264..35c099f 100644
--- a/test/pkuuid.cpp
+++ b/test/pkuuid.cpp
@@ -144,11 +144,29 @@ main(int argc, char *argv[])
// >>
{
- struct pk_uuid id;
- std::istringstream ssi("017f22e2-79b0-7cc3-98c4-dc0c0c07398f");
+ struct pk_uuid id = pk_uuid_max;
+ std::istringstream ssi("017f22e2-79b0-7cc3-98c4-dc0c0c07398fX");
ssi >> id;
+
+ fprintf(stdout, "\n");
+ fprintf(stdout, "[%s] leftovers: ", __FILE__);
ssi >> std::cout.rdbuf();
+ std::cout << std::endl;
+ fprintf(stdout, "[%s] excpected: 017f22e2-79b0-7cc3-98c4-dc0c0c07398f\n", __FILE__);
+ fprintf(stdout, "[%s] result : " pk_uuid_printf_format "\n", __FILE__, pk_uuid_printf_var(id));
+
+ for (int i = 0; i < 16; ++i) {
+ if (example_id.uuid[i] != id.uuid[i]) return 1;
+ }
+ }
+
+ // >>
+ {
+ struct pk_uuid id = pk_uuid_max;
+ const char *ssi = "017f22e2-79b0-7cc3-98c4-dc0c0c07398f";
+
+ ssi >> id;
fprintf(stdout, "\n");
fprintf(stdout, "[%s] excpected: 017f22e2-79b0-7cc3-98c4-dc0c0c07398f\n", __FILE__);
@@ -159,9 +177,59 @@ main(int argc, char *argv[])
}
}
- // >> err
+ // <<
{
struct pk_uuid id;
+ const char *ssi = "017f22e2-79b0-7cc3-98c4-dc0c0c07398f";
+
+ id << ssi;
+
+ fprintf(stdout, "\n");
+ fprintf(stdout, "[%s] excpected: 017f22e2-79b0-7cc3-98c4-dc0c0c07398f\n", __FILE__);
+ fprintf(stdout, "[%s] result : " pk_uuid_printf_format "\n", __FILE__, pk_uuid_printf_var(id));
+
+ for (int i = 0; i < 16; ++i) {
+ if (example_id.uuid[i] != id.uuid[i]) return 1;
+ }
+ }
+
+ // >>
+ {
+ struct pk_uuid id = pk_uuid_max;
+ const char *ssi = "017f22e2-79b0-7cc3-98c4-dc0c0c07398fX";
+
+ const char *res = ssi >> id;
+
+ fprintf(stdout, "\n");
+ fprintf(stdout, "[%s] leftovers: %.2s\n", __FILE__, res);
+ fprintf(stdout, "[%s] excpected: 017f22e2-79b0-7cc3-98c4-dc0c0c07398f\n", __FILE__);
+ fprintf(stdout, "[%s] result : " pk_uuid_printf_format "\n", __FILE__, pk_uuid_printf_var(id));
+
+ if (res[0] != 'X') exit(1);
+ for (int i = 0; i < 16; ++i) {
+ if (example_id.uuid[i] != id.uuid[i]) return 1;
+ }
+ }
+
+ // >> err
+ {
+ struct pk_uuid id = example_id;
+ const char *ssi = "gnud";
+
+ ssi >> id;
+
+ fprintf(stdout, "\n");
+ fprintf(stdout, "[%s] excpected: 00000000-0000-0000-0000-000000000000\n", __FILE__);
+ fprintf(stdout, "[%s] result : " pk_uuid_printf_format "\n", __FILE__, pk_uuid_printf_var(id));
+
+ for (int i = 0; i < 16; ++i) {
+ if (pk_uuid_zed.uuid[i] != id.uuid[i]) return 1;
+ }
+ }
+
+ // >> err
+ {
+ struct pk_uuid id = example_id;
std::istringstream ssi("gnud");
ssi >> id;