diff --git a/util/misc/uuid.cc b/util/misc/uuid.cc index 64f4e97e..a460550a 100644 --- a/util/misc/uuid.cc +++ b/util/misc/uuid.cc @@ -18,45 +18,37 @@ #include "base/basictypes.h" #include "base/strings/stringprintf.h" -#include "util/stdlib/cxx.h" - -#if CXX_LIBRARY_VERSION >= 2011 -#include -#endif +#include "base/sys_byteorder.h" namespace crashpad { -#if CXX_LIBRARY_VERSION >= 2011 -COMPILE_ASSERT(std::is_standard_layout::value, - UUID_must_be_standard_layout); -#endif - -UUID::UUID() : data() { +UUID::UUID() : data_1(0), data_2(0), data_3(0), data_4(), data_5() { } UUID::UUID(const uint8_t* bytes) { - memcpy(data, bytes, sizeof(data)); + InitializeFromBytes(bytes); +} + +void UUID::InitializeFromBytes(const uint8_t* bytes) { + memcpy(this, bytes, sizeof(*this)); + data_1 = base::NetToHost32(data_1); + data_2 = base::NetToHost16(data_2); + data_3 = base::NetToHost16(data_3); } std::string UUID::ToString() const { - return base::StringPrintf( - "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x", - data[0], - data[1], - data[2], - data[3], - data[4], - data[5], - data[6], - data[7], - data[8], - data[9], - data[10], - data[11], - data[12], - data[13], - data[14], - data[15]); + return base::StringPrintf("%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x", + data_1, + data_2, + data_3, + data_4[0], + data_4[1], + data_5[0], + data_5[1], + data_5[2], + data_5[3], + data_5[4], + data_5[5]); } } // namespace crashpad diff --git a/util/misc/uuid.h b/util/misc/uuid.h index 260d8db9..25b2dbb1 100644 --- a/util/misc/uuid.h +++ b/util/misc/uuid.h @@ -27,25 +27,34 @@ namespace crashpad { //! primarily by Microsoft. //! //! A %UUID is a unique 128-bit number specified by RFC 4122. -//! -//! This is a standard-layout structure, and it is acceptable to use `memcpy()` -//! to set its value. struct UUID { //! \brief Initializes the %UUID to zero. UUID(); + //! \copydoc InitializeFromBytes() + explicit UUID(const uint8_t* bytes); + //! \brief Initializes the %UUID from a sequence of bytes. //! + //! \a bytes is taken as a %UUID laid out in big-endian format in memory. On + //! little-endian machines, appropriate byte-swapping will be performed to + //! initialize an object’s data members. + //! //! \param[in] bytes A buffer of exactly 16 bytes that will be assigned to the //! %UUID. - explicit UUID(const uint8_t* bytes); + void InitializeFromBytes(const uint8_t* bytes); //! \brief Formats the %UUID per RFC 4122 §3. //! //! \return A string of the form `"00112233-4455-6677-8899-aabbccddeeff"`. std::string ToString() const; - uint8_t data[16]; + // These fields are laid out according to RFC 4122 §4.1.2. + uint32_t data_1; + uint16_t data_2; + uint16_t data_3; + uint8_t data_4[2]; + uint8_t data_5[6]; }; } // namespace crashpad diff --git a/util/misc/uuid_test.cc b/util/misc/uuid_test.cc index 2737e7cc..9664f7ea 100644 --- a/util/misc/uuid_test.cc +++ b/util/misc/uuid_test.cc @@ -27,9 +27,17 @@ using namespace crashpad; TEST(UUID, UUID) { UUID uuid_zero; - for (size_t index = 0; index < 16; ++index) { - EXPECT_EQ(0u, uuid_zero.data[index]); - } + EXPECT_EQ(0u, uuid_zero.data_1); + EXPECT_EQ(0u, uuid_zero.data_2); + EXPECT_EQ(0u, uuid_zero.data_3); + EXPECT_EQ(0u, uuid_zero.data_4[0]); + EXPECT_EQ(0u, uuid_zero.data_4[1]); + EXPECT_EQ(0u, uuid_zero.data_5[0]); + EXPECT_EQ(0u, uuid_zero.data_5[1]); + EXPECT_EQ(0u, uuid_zero.data_5[2]); + EXPECT_EQ(0u, uuid_zero.data_5[3]); + EXPECT_EQ(0u, uuid_zero.data_5[4]); + EXPECT_EQ(0u, uuid_zero.data_5[5]); EXPECT_EQ("00000000-0000-0000-0000-000000000000", uuid_zero.ToString()); const uint8_t kBytes[16] = {0x00, @@ -49,12 +57,19 @@ TEST(UUID, UUID) { 0x0e, 0x0f}; UUID uuid(kBytes); - for (size_t index = 0; index < arraysize(kBytes); ++index) { - EXPECT_EQ(kBytes[index], uuid.data[index]); - } + EXPECT_EQ(0x00010203u, uuid.data_1); + EXPECT_EQ(0x0405u, uuid.data_2); + EXPECT_EQ(0x0607u, uuid.data_3); + EXPECT_EQ(0x08u, uuid.data_4[0]); + EXPECT_EQ(0x09u, uuid.data_4[1]); + EXPECT_EQ(0x0au, uuid.data_5[0]); + EXPECT_EQ(0x0bu, uuid.data_5[1]); + EXPECT_EQ(0x0cu, uuid.data_5[2]); + EXPECT_EQ(0x0du, uuid.data_5[3]); + EXPECT_EQ(0x0eu, uuid.data_5[4]); + EXPECT_EQ(0x0fu, uuid.data_5[5]); EXPECT_EQ("00010203-0405-0607-0809-0a0b0c0d0e0f", uuid.ToString()); - // UUID is a standard-layout structure. It is valid to memcpy to it. const uint8_t kMoreBytes[16] = {0xff, 0xee, 0xdd, @@ -71,7 +86,18 @@ TEST(UUID, UUID) { 0x22, 0x11, 0x00}; - memcpy(&uuid, kMoreBytes, sizeof(kMoreBytes)); + uuid.InitializeFromBytes(kMoreBytes); + EXPECT_EQ(0xffeeddccu, uuid.data_1); + EXPECT_EQ(0xbbaau, uuid.data_2); + EXPECT_EQ(0x9988u, uuid.data_3); + EXPECT_EQ(0x77u, uuid.data_4[0]); + EXPECT_EQ(0x66u, uuid.data_4[1]); + EXPECT_EQ(0x55u, uuid.data_5[0]); + EXPECT_EQ(0x44u, uuid.data_5[1]); + EXPECT_EQ(0x33u, uuid.data_5[2]); + EXPECT_EQ(0x22u, uuid.data_5[3]); + EXPECT_EQ(0x11u, uuid.data_5[4]); + EXPECT_EQ(0x00u, uuid.data_5[5]); EXPECT_EQ("ffeeddcc-bbaa-9988-7766-554433221100", uuid.ToString()); }