aboutsummaryrefslogtreecommitdiff
path: root/libbutl/uuid.hxx
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2018-08-22 17:26:08 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2018-08-22 17:36:23 +0200
commitfebb9c275b5247df596876e4eea7fa17b7ec45e7 (patch)
tree214a192cc6b019fb25a659cfdb84601da74438bf /libbutl/uuid.hxx
parentf8fc81a5c9fcd986473797df9286c6c9fef683bf (diff)
Add support for UUID generation
Diffstat (limited to 'libbutl/uuid.hxx')
-rw-r--r--libbutl/uuid.hxx234
1 files changed, 234 insertions, 0 deletions
diff --git a/libbutl/uuid.hxx b/libbutl/uuid.hxx
new file mode 100644
index 0000000..92397f6
--- /dev/null
+++ b/libbutl/uuid.hxx
@@ -0,0 +1,234 @@
+// file : libbutl/uuid.hxx -*- C++ -*-
+// copyright : Copyright (c) 2014-2018 Code Synthesis Ltd
+// license : MIT; see accompanying LICENSE file
+
+#pragma once
+
+#include <array>
+#include <string>
+#include <cstdint>
+#include <functional> // hash
+
+#include <libbutl/export.hxx>
+#include <libbutl/version.hxx>
+
+#ifdef _WIN32
+struct _GUID; // GUID and UUID.
+#endif
+
+namespace butl
+{
+ // Universally-unique identifier (UUID), RFC4122:
+ //
+ // https://tools.ietf.org/html/rfc4122
+
+ // The UUID variant (type). Nil UUID is DCE.
+ //
+ enum class uuid_variant
+ {
+ ncs, // NCS backward compatibility.
+ dce, // DCE 1.1/RFC4122.
+ microsoft, // Microsoft backward compatibility.
+ other // Currently reserved for possible future definition.
+ };
+
+ // The DCE UUID version (sub-type). Nil UUID is random.
+ //
+ enum class uuid_version
+ {
+ time = 1, // Time-based.
+ security = 2, // DCE Security with embedded POSIX UIDs.
+ md5 = 3, // Name-based with MD5 hashing.
+ random = 4, // Randomly or pseudo-randomly generated.
+ sha1 = 5 // Name-based with SHA1 hashing.
+ };
+
+ class LIBBUTL_SYMEXPORT uuid_system_generator;
+
+ struct LIBBUTL_SYMEXPORT uuid
+ {
+ // Normally not accessed directly (see RFC4122 Section 4.1.2).
+ //
+ std::uint32_t time_low;
+ std::uint16_t time_mid;
+ std::uint16_t time_hiv; // hi_and_version
+ std::uint8_t clock_seq_hir; // hi_and_reserved
+ std::uint8_t clock_seq_low;
+ std::uint8_t node[6];
+
+ // System UUID generator. See the uuid_generator interface for details.
+ //
+ // Note: system generator cannot be called during static initialization.
+ //
+ static uuid_system_generator system_generator;
+
+ static uuid
+ generate (bool strong = true);
+
+ // Create a nil UUID (all members are 0).
+ //
+ uuid ();
+
+ bool
+ nil () const;
+
+ explicit operator bool () const;
+
+ // Create a UUID from a 16-octet binary representation with the sizes and
+ // order of the fields as defined in RFC4122 Section 4.1.2 and with each
+ // field encoded with the most significant byte first (also known as
+ // big-endian or network byte order).
+ //
+ using binary_type = std::array<std::uint8_t, 16>;
+
+ explicit
+ uuid (const binary_type&);
+
+ void
+ assign (const binary_type&);
+
+ binary_type
+ binary () const noexcept;
+
+ // Note that this constructor is compatible with libuuid's uuid_t type.
+ //
+ explicit
+ uuid (const std::uint8_t (&)[16]);
+
+ void
+ assign (const std::uint8_t (&)[16]);
+
+#ifdef _WIN32
+ // Create a UUID from Win32 GUID.
+ //
+ uuid (const _GUID&);
+
+ void
+ assign (const _GUID&);
+
+ template <typename G = _GUID>
+ G
+ guid () const;
+#endif
+
+ // Create a UUID from a 36-character string representation in the
+ //
+ // xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
+ //
+ // form which can be in lower or upper case. Throw std::invalid_argument
+ // if the representation is invalid.
+ //
+ // The returned string representation is by default in lower case.
+ //
+ explicit
+ uuid (const std::string&);
+
+ explicit
+ uuid (const char*);
+
+ void
+ assign (const std::string&);
+
+ void
+ assign (const char*);
+
+ std::string
+ string (bool upper = false) const;
+
+ std::array<char, 37>
+ c_string (bool upper = false) const;
+
+ // UUID variant (type) and version (sub-type).
+ //
+ using variant_type = uuid_variant;
+ using version_type = uuid_version;
+
+ variant_type
+ variant () const;
+
+ version_type
+ version () const;
+
+ // UUID comparison.
+ //
+ int
+ compare (const uuid&) const;
+
+ // Swapping and moving. On move we make the moved-from instance nil.
+ //
+ void
+ swap (uuid&);
+
+ uuid (uuid&&);
+ uuid (const uuid&) = default;
+
+ uuid& operator= (uuid&&);
+ uuid& operator= (const uuid&) = default;
+ };
+
+ bool operator== (const uuid&, const uuid&);
+ bool operator!= (const uuid&, const uuid&);
+ bool operator< (const uuid&, const uuid&);
+ bool operator> (const uuid&, const uuid&);
+ bool operator<= (const uuid&, const uuid&);
+ bool operator>= (const uuid&, const uuid&);
+
+ // For iostream operators see uuid-io.hxx.
+
+ // UUID generator interface.
+ //
+ class LIBBUTL_SYMEXPORT uuid_generator
+ {
+ public:
+ virtual
+ ~uuid_generator () = default;
+
+ // Generate a UUID. If strong is true (default), generate a strongly-
+ // unique UUID. Throw std::runtime_error to report errors, including if
+ // strong uniqueness cannot be guaranteed.
+ //
+ // A weak UUID is not guaranteed to be unique, neither universialy nor
+ // locally (that is, on the machine it has been generated).
+ //
+ virtual uuid
+ generate (bool strong = true) = 0;
+ };
+
+ // System UUID generator.
+ //
+ class LIBBUTL_SYMEXPORT uuid_system_generator: public uuid_generator
+ {
+ public:
+ // Throw std::system_error with the generic category and ENOTSUP error
+ // code if strong uniqueness cannot be guaranteed.
+ //
+ virtual uuid
+ generate (bool strong = true) override;
+
+ // Optional explicit initialization and termination. Note that it is not
+ // thread-safe and must only be performed once (normally from main())
+ // before/after any calls to generate(), respectively. Both functions may
+ // throw std::runtime_error to report errors.
+ //
+ static void
+ initialize ();
+
+ static void
+ terminate ();
+ };
+}
+
+namespace std
+{
+ template <>
+ struct hash<butl::uuid>
+ {
+ using argument_type = butl::uuid;
+ using result_type = size_t;
+
+ size_t
+ operator() (const butl::uuid&) const noexcept;
+ };
+}
+
+#include <libbutl/uuid.ixx>