ProvSQL C/C++ API
Adding support for provenance and uncertainty management to PostgreSQL databases
Loading...
Searching...
No Matches
provsql_utils_cpp.cpp
Go to the documentation of this file.
1/**
2 * @file provsql_utils_cpp.cpp
3 * @brief C++ UUID utility function implementations.
4 *
5 * Implements the C++ helper functions declared in @c provsql_utils_cpp.h:
6 * - @c uuid2string(): format a @c pg_uuid_t as a 36-char hyphenated hex string.
7 * - @c string2uuid(): parse a UUID string into a @c pg_uuid_t.
8 * - @c UUIDDatum2string(): extract and format a UUID from a PostgreSQL @c Datum.
9 * - @c hash_value(): Boost-compatible hash for @c pg_uuid_t.
10 * - @c operator==(): byte-level equality for @c pg_uuid_t.
11 *
12 * The @c uuid2string and @c string2uuid functions are adapted from
13 * PostgreSQL's own @c uuid.c, which is not exposed as a public API.
14 */
15extern "C" {
16#include "postgres.h"
17#include "utils/uuid.h"
18
19#include "provsql_utils.h"
20}
21
22#include "provsql_utils_cpp.h"
23#include <cassert>
24#include "Circuit.h"
25
26using namespace std;
27
28string uuid2string(pg_uuid_t uuid) {
29/* copied with small changes from uuid.c */
30 static const char hex_chars[] = "0123456789abcdef";
31 string result;
32
33 for (int i = 0; i < UUID_LEN; i++)
34 {
35 if (i == 4 || i == 6 || i == 8 || i == 10)
36 result += '-';
37
38 int hi = uuid.data[i] >> 4;
39 int lo = uuid.data[i] & 0x0F;
40
41 result+=hex_chars[hi];
42 result+=hex_chars[lo];
43 }
44
45 return result;
46}
47
48/**
49 * @brief Parse a UUID string into a @c pg_uuid_t.
50 * @param source UUID string in standard hyphenated hex format.
51 * @return The parsed @c pg_uuid_t value.
52 */
53pg_uuid_t string2uuid(const string &source)
54/* copied with small changes from uuid.c */
55{
56 const char *src = source.c_str();
57 pg_uuid_t uuid;
58 bool braces = false;
59 int i;
60
61 if (src[0] == '{')
62 {
63 src++;
64 braces = true;
65 }
66
67 for (i = 0; i < UUID_LEN; i++)
68 {
69 char str_buf[3];
70
71 if (src[0] == '\0' || src[1] == '\0')
72 goto syntax_error;
73 memcpy(str_buf, src, 2);
74 if (!isxdigit((unsigned char) str_buf[0]) ||
75 !isxdigit((unsigned char) str_buf[1]))
76 goto syntax_error;
77
78 str_buf[2] = '\0';
79 uuid.data[i] = (unsigned char) strtoul(str_buf, NULL, 16);
80 src += 2;
81 if (src[0] == '-' && (i % 2) == 1 && i < UUID_LEN - 1)
82 src++;
83 }
84
85 if (braces)
86 {
87 if (*src != '}')
88 goto syntax_error;
89 src++;
90 }
91
92 if (*src != '\0')
93 goto syntax_error;
94
95 return uuid;
96
97syntax_error:
98 ereport(ERROR,
99 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
100 errmsg("invalid input syntax for type %s: \"%s\"",
101 "uuid", src)));
102}
103
104string UUIDDatum2string(Datum token)
105{
106 pg_uuid_t *uuid = DatumGetUUIDP(token);
107 return uuid2string(*uuid);
108}
109
110std::size_t hash_value(const pg_uuid_t &u)
111{
112 return *reinterpret_cast<const std::size_t*>(&u);
113}
114
115bool operator==(const pg_uuid_t &u, const pg_uuid_t &v)
116{
117 for(int i=0; i<UUID_LEN; ++i)
118 if(u.data[i]!=v.data[i])
119 return false;
120
121 return true;
122}
Generic directed-acyclic-graph circuit template and gate identifier.
Core types, constants, and utilities shared across ProvSQL.
#define UUID_LEN
Number of bytes in a UUID.
pg_uuid_t string2uuid(const string &source)
Parse a UUID string into a pg_uuid_t.
string uuid2string(pg_uuid_t uuid)
Format a pg_uuid_t as a std::string.
std::size_t hash_value(const pg_uuid_t &u)
Compute a hash value for a pg_uuid_t.
string UUIDDatum2string(Datum token)
Convert a PostgreSQL Datum holding a UUID to a std::string.
bool operator==(const pg_uuid_t &u, const pg_uuid_t &v)
Test two pg_uuid_t values for equality.
C++ utility functions for UUID manipulation.
UUID structure.
unsigned char data[UUID_LEN]
Raw 16-byte UUID storage.