Support: quest -f cjk_ngram
[xapian.git] / xapian-core / common / safeuuid.h
bloba63e3368c8c7341d4ba524b6454fc34211abc2c3
1 /** @file safeuuid.h
2 * @brief #include <uuid/uuid.h>, with alternative implementation for windows.
3 */
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().
37 # ifndef uuid_parse
38 # define uuid_parse(IN, UU) (uuid_parse)(const_cast<char*>(IN), (UU))
39 # endif
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;
52 # endif
54 #else
56 // UUID API on FreeBSD, NetBSD and AIX.
58 # ifdef _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
63 # include <uuid.h>
64 # undef byte
65 # else
66 # include <uuid.h>
67 # endif
69 # include <cstdlib>
70 # include <cstring>
71 # include <exception>
73 typedef unsigned char uuid_t_[16];
75 inline void
76 uuid_generate(uuid_t_ out) {
77 uuid_t uuid;
78 uint32_t status;
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_));
87 inline int
88 uuid_parse(const char * in, uuid_t_ uu)
90 uuid_t uuid;
91 uint32_t status;
92 #ifdef _AIX
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);
97 #else
98 uuid_from_string(in, &uuid, &status);
99 #endif
100 if (status != uuid_s_ok)
101 return -1;
102 std::memcpy(uu, &uuid, sizeof(uuid_t_));
103 return 0;
106 inline void
107 uuid_unparse_lower(const uuid_t_ uu, char * out)
109 uuid_t uuid;
110 uint32_t status;
111 std::memcpy(&uuid, uu, sizeof(uuid_t));
112 #ifdef _AIX
113 // AIX takes unsigned char* not char *.
114 unsigned char * result;
115 #else
116 char * result;
117 #endif
118 uuid_to_string(&uuid, &result, &status);
119 std::memcpy(out, result, 36);
120 std::free(result);
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;
131 inline void
132 uuid_clear(uuid_t_ uu)
134 std::memset(uu, 0, sizeof(uuid_t_));
137 inline int
138 uuid_is_null(const uuid_t_ uu)
140 size_t i = 0;
141 while (i < sizeof(uuid_t_)) {
142 if (uu[i++])
143 return 0;
145 return 1;
148 // Hide incompatible uuid_t from <uuid.h>.
149 # define uuid_t uuid_t_
151 #endif
153 #endif // XAPIAN_INCLUDED_SAFEUUID_H