safeuuid.h
Go to the documentation of this file.
1 
4 /* Copyright (C) 2008 Lemur Consulting Ltd
5  * Copyright (C) 2009,2010,2013,2016 Olly Betts
6  *
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.
11  *
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.
16  *
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
20  */
21 
22 #ifndef XAPIAN_INCLUDED_SAFEUUID_H
23 #define XAPIAN_INCLUDED_SAFEUUID_H
24 
25 #ifdef USE_WIN32_UUID_API
26 # include "common/win32_uuid.h"
27 #elif defined HAVE_UUID_UUID_H
28 # include <uuid/uuid.h>
29 
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
40 
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.
49  */
50  for (size_t i = 0; i < 36; ++i) out[i] |= 0x20;
51 }
52 # endif
53 
54 #elif defined HAVE_UUID_H
55 
56 // UUID API on FreeBSD, NetBSD and AIX.
57 
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.
61  */
62 # define byte xapian_hack_aix_uuid_byte
63 # include <uuid.h>
64 # undef byte
65 # else
66 # include <uuid.h>
67 # endif
68 
69 # include <cstdlib>
70 # include <cstring>
71 # include <exception>
72 
73 typedef unsigned char uuid_t_[16];
74 
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();
83  }
84  std::memcpy(out, &uuid, sizeof(uuid_t_));
85 }
86 
87 inline int
88 uuid_parse(const char * in, uuid_t_ uu)
89 {
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;
104 }
105 
106 inline void
107 uuid_unparse_lower(const uuid_t_ uu, char * out)
108 {
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();
124  }
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.
127  */
128  for (size_t i = 0; i < 36; ++i) out[i] |= 0x20;
129 }
130 
131 inline void
132 uuid_clear(uuid_t_ uu)
133 {
134  std::memset(uu, 0, sizeof(uuid_t_));
135 }
136 
137 inline int
138 uuid_is_null(const uuid_t_ uu)
139 {
140  size_t i = 0;
141  while (i < sizeof(uuid_t_)) {
142  if (uu[i++])
143  return 0;
144  }
145  return 1;
146 }
147 
148 // Hide incompatible uuid_t from <uuid.h>.
149 # define uuid_t uuid_t_
150 
151 #elif defined USE_PROC_FOR_UUID
152 # include "common/proc_uuid.h"
153 #else
154 # error Do not know how to generate UUIDs
155 #endif
156 
157 #endif // XAPIAN_INCLUDED_SAFEUUID_H
unsigned char uuid_t[16]
Definition: proc_uuid.h:25
void uuid_generate(uuid_t uu)
Definition: proc_uuid.cc:49
int uuid_parse(const char *in, uuid_t uu)
Definition: proc_uuid.cc:65
void uuid_clear(uuid_t uu)
Definition: proc_uuid.cc:86
int uuid_is_null(const uuid_t uu)
Definition: proc_uuid.cc:91
void uuid_unparse_lower(const uuid_t uu, char *out)
Definition: proc_uuid.cc:74

Documentation for Xapian (version 1.4.7).
Generated on Fri Jul 20 2018 by Doxygen 1.8.13.