guid.cpp 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. /*
  2. * Copyright (c) 2012-2018 Daniele Bartolini and individual contributors.
  3. * License: https://github.com/dbartolini/crown/blob/master/LICENSE
  4. */
  5. #include "core/error/error.h"
  6. #include "core/guid.h"
  7. #include "core/platform.h"
  8. #include <stdio.h> // sscanf
  9. #if CROWN_PLATFORM_POSIX
  10. #include <fcntl.h>
  11. #include <unistd.h>
  12. #include <errno.h>
  13. #elif CROWN_PLATFORM_WINDOWS
  14. #include <objbase.h>
  15. #endif // CROWN_PLATFORM_POSIX
  16. namespace crown
  17. {
  18. namespace guid_globals
  19. {
  20. #if CROWN_PLATFORM_POSIX
  21. static int _fd = -1;
  22. #endif
  23. void init()
  24. {
  25. #if CROWN_PLATFORM_POSIX
  26. _fd = ::open("/dev/urandom", O_RDONLY);
  27. CE_ASSERT(_fd != -1, "open: errno = %d", errno);
  28. #endif // CROWN_PLATFORM_POSIX
  29. }
  30. void shutdown()
  31. {
  32. #if CROWN_PLATFORM_POSIX
  33. ::close(_fd);
  34. #endif // CROWN_PLATFORM_POSIX
  35. }
  36. } // namespace guid_globals
  37. namespace guid
  38. {
  39. Guid new_guid()
  40. {
  41. Guid guid;
  42. #if CROWN_PLATFORM_POSIX
  43. CE_ASSERT(guid_globals::_fd != -1, "new_guid: library uninitialized");
  44. ssize_t rb = read(guid_globals::_fd, &guid, sizeof(guid));
  45. CE_ENSURE(rb == sizeof(guid));
  46. CE_UNUSED(rb);
  47. guid.data3 = (guid.data3 & 0x4fffu) | 0x4000u;
  48. guid.data4 = (guid.data4 & 0x3fffffffffffffffu) | 0x8000000000000000u;
  49. #elif CROWN_PLATFORM_WINDOWS
  50. HRESULT hr = CoCreateGuid((GUID*)&guid);
  51. CE_ASSERT(hr == S_OK, "CoCreateGuid: error");
  52. CE_UNUSED(hr);
  53. #endif // CROWN_PLATFORM_POSIX
  54. return guid;
  55. }
  56. Guid parse(const char* str)
  57. {
  58. Guid guid;
  59. try_parse(guid, str);
  60. return guid;
  61. }
  62. bool try_parse(Guid& guid, const char* str)
  63. {
  64. CE_ENSURE(NULL != str);
  65. u32 a, b, c, d, e, f;
  66. int num = sscanf(str, "%8x-%4x-%4x-%4x-%4x%8x", &a, &b, &c, &d, &e, &f);
  67. guid.data1 = a;
  68. guid.data2 = (u16)(b & 0x0000ffffu);
  69. guid.data3 = (u16)(c & 0x0000ffffu);
  70. guid.data4 = (u64)(d & 0x0000ffffu) << 48 | (u64)(e & 0x0000ffffu) << 32 | (u64)f;
  71. return num == 6;
  72. }
  73. void to_string(char* buf, u32 len, const Guid& guid)
  74. {
  75. snprintf(buf, len, "%.8x-%.4x-%.4x-%.4x-%.4x%.8x"
  76. , guid.data1
  77. , guid.data2
  78. , guid.data3
  79. , (u16)((guid.data4 & 0xffff000000000000u) >> 48)
  80. , (u16)((guid.data4 & 0x0000ffff00000000u) >> 32)
  81. , (u32)((guid.data4 & 0x00000000ffffffffu) >> 0)
  82. );
  83. }
  84. } // namespace guid
  85. } // namespace crown