GComm  0.2.3
uuid.hpp
1 /*
2  * Copyright (C) 2009 Codership Oy <info@codership.com>
3  */
4 
5 #ifndef _GCOMM_UUID_HPP_
6 #define _GCOMM_UUID_HPP_
7 
8 #include "gcomm/exception.hpp"
9 #include "gcomm/types.hpp"
10 
11 #include "gu_utils.hpp"
12 #include "gu_assert.hpp"
13 #include "gu_byteswap.h"
14 
15 #include "gu_uuid.h"
16 
17 #include <ostream>
18 #include <iomanip>
19 
20 namespace gcomm
21 {
22  class UUID;
23  std::ostream& operator<<(std::ostream&, const UUID&);
24 }
25 
27 {
28 public:
29 
30  UUID() : uuid_(GU_UUID_NIL) {}
31 
32  UUID(const void* node, const size_t node_len) : uuid_()
33  {
34  gu_uuid_generate(&uuid_, node, node_len);
35  }
36 
37  UUID(const int32_t idx) : uuid_()
38  {
39  assert(idx > 0);
40  uuid_ = GU_UUID_NIL;
41  memcpy(&uuid_, &idx, sizeof(idx));
42  }
43 
44  static const UUID& nil()
45  {
46  return uuid_nil_;
47  }
48 
49  size_t unserialize(const gu::byte_t* buf, const size_t buflen, const size_t offset)
50  {
51  if (buflen < offset + sizeof(gu_uuid_t))
52  gu_throw_error (EMSGSIZE) << sizeof(gu_uuid_t) << " > "
53  << (buflen - offset);
54 
55  memcpy(&uuid_, buf + offset, sizeof(gu_uuid_t));
56 
57  return offset + sizeof(gu_uuid_t);
58  }
59 
60  size_t serialize(gu::byte_t* buf, const size_t buflen, const size_t offset) const
61  {
62  if (buflen < offset + sizeof(gu_uuid_t))
63  gu_throw_error (EMSGSIZE) << sizeof(gu_uuid_t) << " > "
64  << (buflen - offset);
65 
66  memcpy(buf + offset, &uuid_, sizeof(gu_uuid_t));
67 
68  return offset + sizeof(gu_uuid_t);
69  }
70 
71  static size_t serial_size()
72  {
73  return sizeof(gu_uuid_t);
74  }
75 
76  const gu_uuid_t* uuid_ptr() const
77  {
78  return &uuid_;
79  }
80 
81  bool operator<(const UUID& cmp) const
82  {
83  return (gu_uuid_compare(&uuid_, &cmp.uuid_) < 0);
84  }
85 
86  bool operator==(const UUID& cmp) const
87  {
88  return (gu_uuid_compare(&uuid_, &cmp.uuid_) == 0);
89  }
90 
91  bool older(const UUID& cmp) const
92  {
93  return (gu_uuid_older(&uuid_, &cmp.uuid_) > 0);
94  }
95 
96  std::ostream& to_stream(std::ostream& os) const
97  {
98  static const char buf[37] = { 0, };
99  const uint32_t* i = reinterpret_cast<const uint32_t*>(uuid_.data);
100 
101  if (i[0] != 0 &&
102  memcmp(i + 1, buf, sizeof(uuid_) - sizeof(*i)) == 0)
103  {
104  // if all of UUID is contained in the first 4 bytes
105  os << i[0]; // should this be converted to certain endianness?
106  }
107  else
108  {
109  const uint16_t* s = reinterpret_cast<const uint16_t*>(uuid_.data);
110 
111  std::ios_base::fmtflags saved = os.flags();
112 
113  os << std::hex
114  << std::setfill('0') << std::setw(8) << gu_be32(i[0]) << '-'
115  << std::setfill('0') << std::setw(4) << gu_be16(s[2]) << '-'
116  << std::setfill('0') << std::setw(4) << gu_be16(s[3]) << '-'
117  << std::setfill('0') << std::setw(4) << gu_be16(s[4]) << '-'
118  << std::setfill('0') << std::setw(4) << gu_be16(s[5])
119  << std::setfill('0') << std::setw(8) << gu_be32(i[3]);
120 
121  os.flags(saved);
122  }
123 
124  return os;
125  }
126 
127  // Prefer the above function over this one
128  std::string _str() const
129  {
130  std::ostringstream os;
131  to_stream(os);
132  return os.str();
133  }
134 
135 private:
136 
137  gu_uuid_t uuid_;
138  static const UUID uuid_nil_;
139  UUID(gu_uuid_t uuid) : uuid_(uuid) {}
140 };
141 
142 
143 
144 inline std::ostream& gcomm::operator<<(std::ostream& os, const UUID& uuid)
145 {
146  return uuid.to_stream (os);
147 }
148 
149 #endif // _GCOMM_UUID_HPP_
GComm exception definitions.
Definition: uuid.hpp:26