2 * @brief #include <uuid/uuid.h>, with alternative implementation for windows.
4 /* Copyright (C) 2008 Lemur Consulting Ltd
5 * Copyright (C) 2009,2010,2013 Olly Betts
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation; either version 2 of the
10 * License, or (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22 #ifndef XAPIAN_INCLUDED_SAFEUUID_H
23 #define XAPIAN_INCLUDED_SAFEUUID_H
25 #if defined __CYGWIN__ || defined __WIN32__
26 # include "common/win32_uuid.h"
27 #elif defined HAVE_UUID_UUID_H
28 # include <uuid/uuid.h>
30 // Some UUID libraries lack const qualifiers. Solaris is a particular
31 // example which survives today (2009). The libuuid from e2fsprogs (now in
32 // util-linux-ng) gained const qualifiers in 2001. It's hard to cast uuid_t
33 // suitably as it is a typedef for an array in at least some implementations,
34 // but we probably can't safely assume that. We don't need to pass const
35 // uuid_t, but we do need to pass const char *, so fix that with a macro
36 // wrapper for uuid_parse().
38 # define uuid_parse(IN, UU) (uuid_parse)(const_cast<char*>(IN), (UU))
41 # ifndef HAVE_UUID_UNPARSE_LOWER
42 /* Older versions of libuuid (such as that on CentOS 4.7) don't have
43 * uuid_unparse_lower(), only uuid_unparse(). NB uu parameter not const
44 * as uuid_unparse may take a non-const uuid_t parameter. */
45 inline void uuid_unparse_lower(uuid_t uu
, char *out
) {
46 uuid_unparse(uu
, out
);
47 /* Characters in out are either 0-9, a-z, '-', or A-Z. A-Z is mapped to
48 * a-z by bitwise or with 0x20, and the others already have this bit set.
50 for (size_t i
= 0; i
< 36; ++i
) out
[i
] |= 0x20;
56 // UUID API on FreeBSD, NetBSD and AIX.
59 /* AIX uses a byte typedef in its <uuid.h> which collides with ours, so use a
60 * macro to rename theirs out of the way.
62 # define byte xapian_hack_aix_uuid_byte
73 typedef unsigned char uuid_t_
[16];
76 uuid_generate(uuid_t_ out
) {
79 uuid_create(&uuid
, &status
);
80 if (status
!= uuid_s_ok
) {
81 // Can only be uuid_s_no_memory it seems.
82 throw std::bad_alloc();
84 std::memcpy(out
, &uuid
, sizeof(uuid_t_
));
88 uuid_parse(const char * in
, uuid_t_ uu
)
93 // AIX takes unsigned char* not const char *.
94 char * nonconst_in
= const_cast<char*>(in
);
95 unsigned char * unsigned_in
= reinterpret_cast<unsigned char *>(nonconst_in
);
96 uuid_from_string(unsigned_in
, &uuid
, &status
);
98 uuid_from_string(in
, &uuid
, &status
);
100 if (status
!= uuid_s_ok
)
102 std::memcpy(uu
, &uuid
, sizeof(uuid_t_
));
107 uuid_unparse_lower(const uuid_t_ uu
, char * out
)
111 std::memcpy(&uuid
, uu
, sizeof(uuid_t
));
113 // AIX takes unsigned char* not char *.
114 unsigned char * result
;
118 uuid_to_string(&uuid
, &result
, &status
);
119 std::memcpy(out
, result
, 36);
121 if (status
!= uuid_s_ok
) {
122 // Could be uuid_s_bad_version (FIXME) or uuid_s_no_memory it seems.
123 throw std::bad_alloc();
125 /* Characters in out are either 0-9, a-z, '-', or A-Z. A-Z is mapped to
126 * a-z by bitwise or with 0x20, and the others already have this bit set.
128 for (size_t i
= 0; i
< 36; ++i
) out
[i
] |= 0x20;
132 uuid_clear(uuid_t_ uu
)
134 std::memset(uu
, 0, sizeof(uuid_t_
));
138 uuid_is_null(const uuid_t_ uu
)
141 while (i
< sizeof(uuid_t_
)) {
148 // Hide incompatible uuid_t from <uuid.h>.
149 # define uuid_t uuid_t_
153 #endif // XAPIAN_INCLUDED_SAFEUUID_H