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