1 /*
2 * Copyright (C) 2014-2017 Codership Oy <info@codership.com>
3 *
4 */
5
6 #ifndef _gu_uuid_hpp_
7 #define _gu_uuid_hpp_
8
9 #include "gu_uuid.h"
10 #include "gu_arch.h" // GU_ASSERT_ALIGNMENT
11 #include "gu_assert.hpp"
12 #include "gu_buffer.hpp"
13 #include "gu_exception.hpp"
14
15 #include <istream>
16 #include <cstring>
17
operator ==(const gu_uuid_t & a,const gu_uuid_t & b)18 inline bool operator==(const gu_uuid_t& a, const gu_uuid_t& b)
19 {
20 return gu_uuid_compare(&a, &b) == 0;
21 }
22
operator !=(const gu_uuid_t & a,const gu_uuid_t & b)23 inline bool operator!=(const gu_uuid_t& a, const gu_uuid_t& b)
24 {
25 return !(a == b);
26 }
27
operator <<(std::ostream & os,const gu_uuid_t & uuid)28 inline std::ostream& operator<<(std::ostream& os, const gu_uuid_t& uuid)
29 {
30 char uuid_buf[GU_UUID_STR_LEN + 1];
31 ssize_t ret(gu_uuid_print(&uuid, uuid_buf, sizeof(uuid_buf)));
32 (void)ret;
33 assert(ret == GU_UUID_STR_LEN);
34 uuid_buf[GU_UUID_STR_LEN] = '\0';
35 return (os << uuid_buf);
36 }
37
38 namespace gu {
39 class UUIDScanException : public Exception
40 {
41 public:
42 UUIDScanException(const std::string& s);
43 };
44 }
45
gu_uuid_from_string(const std::string & s,gu_uuid_t & uuid)46 inline ssize_t gu_uuid_from_string(const std::string& s, gu_uuid_t& uuid)
47 {
48 ssize_t ret(gu_uuid_scan(s.c_str(), s.size(), &uuid));
49 if (gu_unlikely(ret == -1)) throw gu::UUIDScanException(s);
50 return ret;
51 }
52
operator >>(std::istream & is,gu_uuid_t & uuid)53 inline std::istream& operator>>(std::istream& is, gu_uuid_t& uuid)
54 {
55 char str[GU_UUID_STR_LEN + 1];
56 is.width(GU_UUID_STR_LEN + 1);
57 is >> str;
58 gu_uuid_from_string(str, uuid);
59 return is;
60 }
61
gu_uuid_serial_size(const gu_uuid_t & uuid)62 GU_FORCE_INLINE size_t gu_uuid_serial_size(const gu_uuid_t& uuid)
63 {
64 return sizeof(uuid.data);
65 }
66
67 namespace gu {
68 class UUIDSerializeException : public Exception
69 {
70 public:
71 UUIDSerializeException(size_t need, size_t have);
72 };
73 }
74
gu_uuid_serialize(const gu_uuid_t & uuid,gu::byte_t * buf,size_t const buflen,size_t const offset)75 inline size_t gu_uuid_serialize(const gu_uuid_t& uuid, gu::byte_t* buf,
76 size_t const buflen, size_t const offset)
77 {
78 size_t const len(gu_uuid_serial_size(uuid));
79 size_t const end_offset(offset + len);
80
81 if (gu_unlikely(end_offset > buflen))
82 throw gu::UUIDSerializeException(len, buflen - offset);
83
84 ::memcpy(buf + offset, uuid.data, len);
85 return end_offset;
86 }
87
gu_uuid_unserialize(const gu::byte_t * buf,size_t const buflen,size_t const offset,gu_uuid_t & uuid)88 inline size_t gu_uuid_unserialize(const gu::byte_t* buf, size_t const buflen,
89 size_t const offset, gu_uuid_t& uuid)
90 {
91 size_t const len(gu_uuid_serial_size(uuid));
92 size_t const end_offset(offset + len);
93
94 if (gu_unlikely(end_offset > buflen))
95 throw gu::UUIDSerializeException(len, buflen - offset);
96
97 ::memcpy(uuid.data, buf + offset, len);
98 return end_offset;
99 }
100
101 namespace gu {
102 class UUID;
103 }
104
105 class gu::UUID
106 {
107 public:
108
UUID()109 UUID() : uuid_(GU_UUID_NIL) {}
110
UUID(const void * node,const size_t node_len)111 UUID(const void* node, const size_t node_len) : uuid_()
112 {
113 gu_uuid_generate(&uuid_, node, node_len);
114 }
115
UUID(gu_uuid_t uuid)116 UUID(gu_uuid_t uuid) : uuid_(uuid) {}
117
unserialize(const gu::byte_t * buf,const size_t buflen,const size_t offset)118 size_t unserialize(const gu::byte_t* buf,
119 const size_t buflen, const size_t offset)
120 {
121 return gu_uuid_unserialize(buf, buflen, offset, uuid_);
122 }
123
serialize(gu::byte_t * buf,const size_t buflen,const size_t offset) const124 size_t serialize(gu::byte_t* buf,
125 const size_t buflen, const size_t offset) const
126 {
127 return gu_uuid_serialize(uuid_, buf, buflen, offset);
128 }
129
serial_size()130 static size_t serial_size()
131 {
132 return sizeof(gu_uuid_t);
133 }
134
uuid_ptr() const135 const gu_uuid_t* uuid_ptr() const
136 {
137 return &uuid_;
138 }
139
140 GU_FORCE_INLINE
operator =(const UUID & u)141 UUID& operator=(const UUID& u)
142 {
143 gu_uuid_copy(&uuid_, &u.uuid_);
144 return *this;
145 }
146
operator <(const UUID & cmp) const147 bool operator<(const UUID& cmp) const
148 {
149 return (gu_uuid_compare(&uuid_, &cmp.uuid_) < 0);
150 }
151
operator ==(const UUID & cmp) const152 bool operator==(const UUID& cmp) const
153 {
154 return (gu_uuid_compare(&uuid_, &cmp.uuid_) == 0);
155 }
156
operator !=(const UUID & cmp) const157 bool operator!=(const UUID& cmp) const
158 {
159 return !(*this == cmp);
160 }
161
older(const UUID & cmp) const162 bool older(const UUID& cmp) const
163 {
164 return (gu_uuid_older(&uuid_, &cmp.uuid_) > 0);
165 }
166
write_stream(std::ostream & os) const167 void write_stream(std::ostream& os) const
168 {
169 os << uuid_;
170 }
171
read_stream(std::istream & is)172 void read_stream(std::istream& is)
173 {
174 is >> uuid_;
175 }
176
177 protected:
178 gu_uuid_t uuid_;
179 }; // class UUID
180
181 namespace gu
182 {
operator <<(std::ostream & os,const gu::UUID & uuid)183 inline std::ostream& operator<<(std::ostream& os, const gu::UUID& uuid)
184 {
185 uuid.write_stream(os);
186 return os;
187 }
188
operator >>(std::istream & is,gu::UUID & uuid)189 inline std::istream& operator>>(std::istream& is, gu::UUID& uuid)
190 {
191 uuid.read_stream(is);
192 return is;
193 }
194 } // namespace gu
195
196 #endif // _gu_uuid_hpp_
197