foobar2000 SDK  2015-08-03
guid.cpp
Go to the documentation of this file.
1 #include "pfc.h"
2 
3 #ifdef _WIN32
4 #include <Objbase.h>
5 #endif
6 
7 /*
8 6B29FC40-CA47-1067-B31D-00DD010662DA
9 .
10 typedef struct _GUID { // size is 16
11  DWORD Data1;
12  WORD Data2;
13  WORD Data3;
14  BYTE Data4[8];
15 } GUID;
16 
17 // {B296CF59-4D51-466f-8E0B-E57D3F91D908}
18 static const GUID <<name>> =
19 { 0xb296cf59, 0x4d51, 0x466f, { 0x8e, 0xb, 0xe5, 0x7d, 0x3f, 0x91, 0xd9, 0x8 } };
20 
21 */
22 namespace {
23  class _GUID_from_text : public GUID
24  {
25  unsigned read_hex(char c);
26  unsigned read_byte(const char * ptr);
27  unsigned read_word(const char * ptr);
28  unsigned read_dword(const char * ptr);
29  void read_bytes(unsigned char * out,unsigned num,const char * ptr);
30 
31  public:
32  _GUID_from_text(const char * text);
33  };
34 
35  unsigned _GUID_from_text::read_hex(char c)
36  {
37  if (c>='0' && c<='9') return (unsigned)c - '0';
38  else if (c>='a' && c<='f') return 0xa + (unsigned)c - 'a';
39  else if (c>='A' && c<='F') return 0xa + (unsigned)c - 'A';
40  else return 0;
41  }
42 
43  unsigned _GUID_from_text::read_byte(const char * ptr)
44  {
45  return (read_hex(ptr[0])<<4) | read_hex(ptr[1]);
46  }
47  unsigned _GUID_from_text::read_word(const char * ptr)
48  {
49  return (read_byte(ptr)<<8) | read_byte(ptr+2);
50  }
51 
52  unsigned _GUID_from_text::read_dword(const char * ptr)
53  {
54  return (read_word(ptr)<<16) | read_word(ptr+4);
55  }
56 
57  void _GUID_from_text::read_bytes(uint8_t * out,unsigned num,const char * ptr)
58  {
59  for(;num;num--)
60  {
61  *out = read_byte(ptr);
62  out++;ptr+=2;
63  }
64  }
65 
66 
67  _GUID_from_text::_GUID_from_text(const char * text)
68  {
69  if (*text=='{') text++;
70  const char * max;
71 
72  {
73  const char * t = strchr(text,'}');
74  if (t) max = t;
75  else max = text + strlen(text);
76  }
77 
78  (GUID)*this = pfc::guid_null;
79 
80 
81  do {
82  if (text+8>max) break;
83  Data1 = read_dword(text);
84  text += 8;
85  while(*text=='-') text++;
86  if (text+4>max) break;
87  Data2 = read_word(text);
88  text += 4;
89  while(*text=='-') text++;
90  if (text+4>max) break;
91  Data3 = read_word(text);
92  text += 4;
93  while(*text=='-') text++;
94  if (text+4>max) break;
95  read_bytes(Data4,2,text);
96  text += 4;
97  while(*text=='-') text++;
98  if (text+12>max) break;
99  read_bytes(Data4+2,6,text);
100  } while(false);
101  }
102 }
103 
104 namespace pfc {
105 
106 GUID GUID_from_text(const char * text) {
107  return _GUID_from_text( text );
108 }
109 
110 static inline char print_hex_digit(unsigned val)
111 {
112  static const char table[16] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
113  PFC_ASSERT((val & ~0xF) == 0);
114  return table[val];
115 }
116 
117 static void print_hex(unsigned val,char * &out,unsigned bytes)
118 {
119  unsigned n;
120  for(n=0;n<bytes;n++)
121  {
122  unsigned char c = (unsigned char)((val >> ((bytes - 1 - n) << 3)) & 0xFF);
123  *(out++) = print_hex_digit( c >> 4 );
124  *(out++) = print_hex_digit( c & 0xF );
125  }
126  *out = 0;
127 }
128 
129 
130 print_guid::print_guid(const GUID & p_guid)
131 {
132  char * out = m_data;
133  print_hex(p_guid.Data1,out,4);
134  *(out++) = '-';
135  print_hex(p_guid.Data2,out,2);
136  *(out++) = '-';
137  print_hex(p_guid.Data3,out,2);
138  *(out++) = '-';
139  print_hex(p_guid.Data4[0],out,1);
140  print_hex(p_guid.Data4[1],out,1);
141  *(out++) = '-';
142  print_hex(p_guid.Data4[2],out,1);
143  print_hex(p_guid.Data4[3],out,1);
144  print_hex(p_guid.Data4[4],out,1);
145  print_hex(p_guid.Data4[5],out,1);
146  print_hex(p_guid.Data4[6],out,1);
147  print_hex(p_guid.Data4[7],out,1);
148  *out = 0;
149 }
150 
151 
152 void print_hex_raw(const void * buffer,unsigned bytes,char * p_out)
153 {
154  char * out = p_out;
155  const unsigned char * in = (const unsigned char *) buffer;
156  unsigned n;
157  for(n=0;n<bytes;n++)
158  print_hex(in[n],out,1);
159 }
160 
162  GUID out;
163 #ifdef _WIN32
164  if (FAILED(CoCreateGuid( & out ) ) ) crash();
165 #else
166  pfc::nixGetRandomData( &out, sizeof(out) );
167 #endif
168  return out;
169  }
170 
171 }
172 
173 
174 
175 const GUID pfc::guid_null = { 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0 } };
176 
GUID createGUID()
Definition: guid.cpp:161
Definition: pfc.h:71
void nixGetRandomData(void *outPtr, size_t outBytes)
uint8_t Data4[8]
Definition: pfc.h:75
static void print_hex(unsigned val, char *&out, unsigned bytes)
Definition: guid.cpp:117
uint16_t Data3
Definition: pfc.h:74
GUID GUID_from_text(const char *text)
Definition: guid.cpp:106
static char print_hex_digit(unsigned val)
Definition: guid.cpp:110
void crash()
Definition: other.cpp:112
void print_hex_raw(const void *buffer, unsigned bytes, char *p_out)
Definition: guid.cpp:152
uint16_t Data2
Definition: pfc.h:73
const GUID guid_null
Definition: guid.cpp:175
uint32_t Data1
Definition: pfc.h:72