Euphoria
guid.cc
Go to the documentation of this file.
1 #include "core/guid.h"
2 
3 #include "core/textfileparser.h"
4 
5 
6 #ifdef _WIN32
7  #include <objbase.h>
8 #else
9  #include <uuid/uuid.h>
10 #endif
11 
12 
13 namespace eu::core
14 {
15 #ifndef _WIN32
16  std::optional<Guid> Guid::create()
17  {
18  Guid guid {};
19  uuid_generate(guid.data.data());
20  return guid;
21  }
22 #else
23  std::optional<Guid> Guid::create()
24  {
25  GUID g;
26 
27  if (S_OK != CoCreateGuid(&g))
28  {
29  return std::nullopt;
30  }
31 
32  std::array<uint8_t, 16> data
33  {
34  static_cast<std::uint8_t>((g.Data1 >> 24) & 0xff),
35  static_cast<std::uint8_t>((g.Data1 >> 16) & 0xff),
36  static_cast<std::uint8_t>((g.Data1 >> 8) & 0xff),
37  static_cast<std::uint8_t>((g.Data1 ) & 0xff),
38  static_cast<std::uint8_t>((g.Data2 >> 8 ) & 0xff),
39  static_cast<std::uint8_t>((g.Data2 ) & 0xff),
40  static_cast<std::uint8_t>((g.Data3 >> 8 ) & 0xff),
41  static_cast<std::uint8_t>((g.Data3 ) & 0xff),
42  static_cast<std::uint8_t>( g.Data4[0] ),
43  static_cast<std::uint8_t>( g.Data4[1] ),
44  static_cast<std::uint8_t>( g.Data4[2] ),
45  static_cast<std::uint8_t>( g.Data4[3] ),
46  static_cast<std::uint8_t>( g.Data4[4] ),
47  static_cast<std::uint8_t>( g.Data4[5] ),
48  static_cast<std::uint8_t>( g.Data4[6] ),
49  static_cast<std::uint8_t>( g.Data4[7] )
50  };
51 
52  return Guid{data};
53  }
54 #endif
55 
56  std::optional<Guid> Guid::parse(const std::string& str)
57  {
58  const auto skip = [](TextfileParser* parser, char c)
59  {
60  while(parser->peek_char() == c)
61  {
62  parser->read_char();
63  }
64  };
65  const auto read_hex = [](TextfileParser* parser) -> std::optional<uint8_t>
66  {
67  const auto as_hex = [](char c) -> std::optional<uint8_t>
68  {
69  if ('0' <= c && c <= '9') { return static_cast<uint8_t>(c - '0'); }
70  if ('a' <= c && c <= 'f') { return static_cast<uint8_t>(10 + (c - 'a')); }
71  if ('A' <= c && c <= 'F') { return static_cast<uint8_t>(10 + (c - 'A')); }
72  return std::nullopt;
73  };
74  const auto first = as_hex(parser->read_char());
75  if(first.has_value() == false) { return std::nullopt; }
76 
77  const auto second = as_hex(parser->peek_char());
78  if(second.has_value())
79  {
80  parser->read_char();
81  return static_cast<uint8_t>((*first << 4) | *second);
82  }
83  else
84  {
85  return *first;
86  }
87  };
88  auto parser = TextfileParser::from_string(str);
89  parser.skip_spaces(false);
90  skip(&parser, '{');
91 
92  Guid ret {};
93  for(int index=0; index<16; index+=1)
94  {
95  if(parser.has_more() == false) { return std::nullopt; }
96 
97  auto hex = read_hex(&parser);
98  if(hex.has_value() == false) { return std::nullopt; }
99 
100  ret.data[index] = *hex;
101  parser.skip_spaces(false);
102  skip(&parser, '-');
103  parser.skip_spaces(false);
104  }
105 
106  return ret;
107  }
108 
109  std::string Guid::to_string() const
110  {
111  return fmt::format
112  (
113  "{:02x}{:02x}{:02x}{:02x}-"
114  "{:02x}{:02x}-"
115  "{:02x}{:02x}-"
116  "{:02x}{:02x}-"
117  "{:02x}{:02x}{:02x}{:02x}{:02x}{:02x}",
118  data[0], data[1], data[2], data[3],
119  data[4], data[5],
120  data[6], data[7],
121  data[8], data[9],
122  data[10], data[11], data[12], data[13], data[14], data[15]
123  );
124  }
125 }
Guid()=default
std::string to_string() const
Definition: guid.cc:109
static std::optional< Guid > create()
Definition: guid.cc:16
static std::optional< Guid > parse(const std::string &str)
Definition: guid.cc:56
std::array< uint8_t, 16 > data
Definition: guid.h:11
Parses a text file in memory.
void skip_spaces(bool include_newline)
static TextfileParser from_string(const std::string &str)
char peek_char(int advance=0)
advance = 0 - next char, 1-the one after that, negative values are not allowed