4 * Copyright 2016 Red Hat, Inc.
7 * Fam Zheng <famz@redhat.com>
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by the Free
11 * Software Foundation; either version 2 of the License, or (at your option)
16 #include "qemu/osdep.h"
17 #include "qemu/uuid.h"
18 #include "qemu/bswap.h"
20 void qemu_uuid_generate(QemuUUID
*uuid
)
25 QEMU_BUILD_BUG_ON(sizeof(QemuUUID
) != 16);
27 for (i
= 0; i
< 4; ++i
) {
28 tmp
[i
] = g_random_int();
30 memcpy(uuid
, tmp
, sizeof(tmp
));
31 /* Set the two most significant bits (bits 6 and 7) of the
32 clock_seq_hi_and_reserved to zero and one, respectively. */
33 uuid
->data
[8] = (uuid
->data
[8] & 0x3f) | 0x80;
34 /* Set the four most significant bits (bits 12 through 15) of the
35 time_hi_and_version field to the 4-bit version number.
37 uuid
->data
[6] = (uuid
->data
[6] & 0xf) | 0x40;
40 int qemu_uuid_is_null(const QemuUUID
*uu
)
42 static QemuUUID null_uuid
;
43 return qemu_uuid_is_equal(uu
, &null_uuid
);
46 int qemu_uuid_is_equal(const QemuUUID
*lhv
, const QemuUUID
*rhv
)
48 return memcmp(lhv
, rhv
, sizeof(QemuUUID
)) == 0;
51 void qemu_uuid_unparse(const QemuUUID
*uuid
, char *out
)
53 const unsigned char *uu
= &uuid
->data
[0];
54 snprintf(out
, UUID_FMT_LEN
+ 1, UUID_FMT
,
55 uu
[0], uu
[1], uu
[2], uu
[3], uu
[4], uu
[5], uu
[6], uu
[7],
56 uu
[8], uu
[9], uu
[10], uu
[11], uu
[12], uu
[13], uu
[14], uu
[15]);
59 char *qemu_uuid_unparse_strdup(const QemuUUID
*uuid
)
61 const unsigned char *uu
= &uuid
->data
[0];
62 return g_strdup_printf(UUID_FMT
,
63 uu
[0], uu
[1], uu
[2], uu
[3], uu
[4], uu
[5], uu
[6],
64 uu
[7], uu
[8], uu
[9], uu
[10], uu
[11], uu
[12],
65 uu
[13], uu
[14], uu
[15]);
68 static bool qemu_uuid_is_valid(const char *str
)
72 for (i
= 0; i
< strlen(str
); i
++) {
73 const char c
= str
[i
];
74 if (i
== 8 || i
== 13 || i
== 18 || i
== 23) {
79 if ((c
>= '0' && c
<= '9') ||
80 (c
>= 'A' && c
<= 'F') ||
81 (c
>= 'a' && c
<= 'f')) {
90 int qemu_uuid_parse(const char *str
, QemuUUID
*uuid
)
92 unsigned char *uu
= &uuid
->data
[0];
95 if (!qemu_uuid_is_valid(str
)) {
99 ret
= sscanf(str
, UUID_FMT
, &uu
[0], &uu
[1], &uu
[2], &uu
[3],
100 &uu
[4], &uu
[5], &uu
[6], &uu
[7], &uu
[8], &uu
[9],
101 &uu
[10], &uu
[11], &uu
[12], &uu
[13], &uu
[14],
110 /* Swap from UUID format endian (BE) to the opposite or vice versa.
112 QemuUUID
qemu_uuid_bswap(QemuUUID uuid
)
114 bswap32s(&uuid
.fields
.time_low
);
115 bswap16s(&uuid
.fields
.time_mid
);
116 bswap16s(&uuid
.fields
.time_high_and_version
);
120 /* djb2 hash algorithm */
121 uint32_t qemu_uuid_hash(const void *uuid
)
123 QemuUUID
*qid
= (QemuUUID
*) uuid
;
127 for (i
= 0; i
< ARRAY_SIZE(qid
->data
); i
++) {
128 h
= (h
<< 5) + h
+ qid
->data
[i
];