1 /*
2 ** OSSP uuid - Universally Unique Identifier
3 ** Copyright (c) 2004-2008 Ralf S. Engelschall <rse@engelschall.com>
4 ** Copyright (c) 2004-2008 The OSSP Project <http://www.ossp.org/>
5 **
6 ** This file is part of OSSP uuid, a library for the generation
7 ** of UUIDs which can found at http://www.ossp.org/pkg/lib/uuid/
8 **
9 ** Permission to use, copy, modify, and distribute this software for
10 ** any purpose with or without fee is hereby granted, provided that
11 ** the above copyright notice and this permission notice appear in all
12 ** copies.
13 **
14 ** THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
15 ** WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
16 ** MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17 ** IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR
18 ** CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
19 ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
20 ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
21 ** USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
22 ** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
23 ** OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
24 ** OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 ** SUCH DAMAGE.
26 **
27 ** uuid_dce.c: DCE 1.1 compatibility API implementation
28 */
29
30 /* include DCE 1.1 API */
31 #define uuid_t uuid_dce_t
32 #include "uuid_dce.h"
33 #undef uuid_t
34 #undef uuid_create
35 #undef uuid_create_nil
36 #undef uuid_is_nil
37 #undef uuid_compare
38 #undef uuid_equal
39 #undef uuid_from_string
40 #undef uuid_to_string
41 #undef uuid_hash
42
43 /* include regular API */
44 #include "uuid.h"
45
46 /* helper macro */
47 #define LEAVE /*lint -save -e801*/ goto leave /*lint -restore*/
48
49 /* create a UUID (v1 only) */
uuid_dce_create(uuid_dce_t * uuid_dce,int * status)50 void uuid_dce_create(uuid_dce_t *uuid_dce, int *status)
51 {
52 uuid_t *uuid;
53 size_t len;
54 void *vp;
55
56 /* initialize status */
57 if (status != NULL)
58 *status = uuid_s_error;
59
60 /* sanity check argument(s) */
61 if (uuid_dce == NULL)
62 return;
63
64 /* create UUID and export as binary representation */
65 if (uuid_create(&uuid) != UUID_RC_OK)
66 return;
67 if (uuid_make(uuid, UUID_MAKE_V1) != UUID_RC_OK) {
68 uuid_destroy(uuid);
69 return;
70 }
71 vp = uuid_dce;
72 len = UUID_LEN_BIN;
73 if (uuid_export(uuid, UUID_FMT_BIN, &vp, &len) != UUID_RC_OK) {
74 uuid_destroy(uuid);
75 return;
76 }
77 uuid_destroy(uuid);
78
79 /* return successfully */
80 if (status != NULL)
81 *status = uuid_s_ok;
82 return;
83 }
84
85 /* create a Nil UUID */
uuid_dce_create_nil(uuid_dce_t * uuid_dce,int * status)86 void uuid_dce_create_nil(uuid_dce_t *uuid_dce, int *status)
87 {
88 /* initialize status */
89 if (status != NULL)
90 *status = uuid_s_error;
91
92 /* sanity check argument(s) */
93 if (uuid_dce == NULL)
94 return;
95
96 /* short-circuit implementation, because Nil UUID is trivial to
97 create, so no need to use regular OSSP uuid API */
98 memset(uuid_dce, 0, UUID_LEN_BIN);
99
100 /* return successfully */
101 if (status != NULL)
102 *status = uuid_s_ok;
103 return;
104 }
105
106 /* check whether it is Nil UUID */
uuid_dce_is_nil(uuid_dce_t * uuid_dce,int * status)107 int uuid_dce_is_nil(uuid_dce_t *uuid_dce, int *status)
108 {
109 int i;
110 int result;
111 unsigned char *ucp;
112
113 /* initialize status */
114 if (status != NULL)
115 *status = uuid_s_error;
116
117 /* sanity check argument(s) */
118 if (uuid_dce == NULL)
119 return 0;
120
121 /* short-circuit implementation, because Nil UUID is trivial to
122 check, so no need to use regular OSSP uuid API */
123 result = 1;
124 ucp = (unsigned char *)uuid_dce;
125 for (i = 0; i < UUID_LEN_BIN; i++) {
126 if (ucp[i] != '\0') {
127 result = 0;
128 break;
129 }
130 }
131
132 /* return successfully with result */
133 if (status != NULL)
134 *status = uuid_s_ok;
135 return result;
136 }
137
138 /* compare two UUIDs */
uuid_dce_compare(uuid_dce_t * uuid_dce1,uuid_dce_t * uuid_dce2,int * status)139 int uuid_dce_compare(uuid_dce_t *uuid_dce1, uuid_dce_t *uuid_dce2, int *status)
140 {
141 uuid_t *uuid1 = NULL;
142 uuid_t *uuid2 = NULL;
143 int result = 0;
144
145 /* initialize status */
146 if (status != NULL)
147 *status = uuid_s_error;
148
149 /* sanity check argument(s) */
150 if (uuid_dce1 == NULL || uuid_dce2 == NULL)
151 return 0;
152
153 /* import both UUID binary representations and compare them */
154 if (uuid_create(&uuid1) != UUID_RC_OK)
155 LEAVE;
156 if (uuid_create(&uuid2) != UUID_RC_OK)
157 LEAVE;
158 if (uuid_import(uuid1, UUID_FMT_BIN, uuid_dce1, UUID_LEN_BIN) != UUID_RC_OK)
159 LEAVE;
160 if (uuid_import(uuid2, UUID_FMT_BIN, uuid_dce2, UUID_LEN_BIN) != UUID_RC_OK)
161 LEAVE;
162 if (uuid_compare(uuid1, uuid2, &result) != UUID_RC_OK)
163 LEAVE;
164
165 /* indicate successful operation */
166 if (status != NULL)
167 *status = uuid_s_ok;
168
169 /* cleanup and return */
170 leave:
171 if (uuid1 != NULL)
172 uuid_destroy(uuid1);
173 if (uuid2 != NULL)
174 uuid_destroy(uuid2);
175 return result;
176 }
177
178 /* compare two UUIDs (equality only) */
uuid_dce_equal(uuid_dce_t * uuid_dce1,uuid_dce_t * uuid_dce2,int * status)179 int uuid_dce_equal(uuid_dce_t *uuid_dce1, uuid_dce_t *uuid_dce2, int *status)
180 {
181 /* initialize status */
182 if (status != NULL)
183 *status = uuid_s_error;
184
185 /* sanity check argument(s) */
186 if (uuid_dce1 == NULL || uuid_dce2 == NULL)
187 return 0;
188
189 /* pass through to generic compare function */
190 return (uuid_dce_compare(uuid_dce1, uuid_dce2, status) == 0 ? 1 : 0);
191 }
192
193 /* import UUID from string representation */
uuid_dce_from_string(const char * str,uuid_dce_t * uuid_dce,int * status)194 void uuid_dce_from_string(const char *str, uuid_dce_t *uuid_dce, int *status)
195 {
196 uuid_t *uuid = NULL;
197 size_t len;
198 void *vp;
199
200 /* initialize status */
201 if (status != NULL)
202 *status = uuid_s_error;
203
204 /* sanity check argument(s) */
205 if (str == NULL || uuid_dce == NULL)
206 return;
207
208 /* import string representation and export binary representation */
209 if (uuid_create(&uuid) != UUID_RC_OK)
210 LEAVE;
211 if (uuid_import(uuid, UUID_FMT_STR, str, UUID_LEN_STR) != UUID_RC_OK)
212 LEAVE;
213 vp = uuid_dce;
214 len = UUID_LEN_BIN;
215 if (uuid_export(uuid, UUID_FMT_BIN, &vp, &len) != UUID_RC_OK)
216 LEAVE;
217
218 /* indicate successful operation */
219 if (status != NULL)
220 *status = uuid_s_ok;
221
222 /* cleanup and return */
223 leave:
224 if (uuid != NULL)
225 uuid_destroy(uuid);
226 return;
227 }
228
229 /* export UUID to string representation */
uuid_dce_to_string(uuid_dce_t * uuid_dce,char ** str,int * status)230 void uuid_dce_to_string(uuid_dce_t *uuid_dce, char **str, int *status)
231 {
232 uuid_t *uuid = NULL;
233 size_t len;
234 void *vp;
235
236 /* initialize status */
237 if (status != NULL)
238 *status = uuid_s_error;
239
240 /* sanity check argument(s) */
241 if (str == NULL || uuid_dce == NULL)
242 return;
243
244 /* import binary representation and export string representation */
245 if (uuid_create(&uuid) != UUID_RC_OK)
246 LEAVE;
247 if (uuid_import(uuid, UUID_FMT_BIN, uuid_dce, UUID_LEN_BIN) != UUID_RC_OK)
248 LEAVE;
249 vp = str;
250 len = UUID_LEN_STR;
251 if (uuid_export(uuid, UUID_FMT_STR, &vp, &len) != UUID_RC_OK)
252 LEAVE;
253
254 /* indicate successful operation */
255 if (status != NULL)
256 *status = uuid_s_ok;
257
258 /* cleanup and return */
259 leave:
260 if (uuid != NULL)
261 uuid_destroy(uuid);
262 return;
263 }
264
265 /* export UUID into hash value */
uuid_dce_hash(uuid_dce_t * uuid_dce,int * status)266 unsigned int uuid_dce_hash(uuid_dce_t *uuid_dce, int *status)
267 {
268 int i;
269 unsigned char *ucp;
270 unsigned int hash;
271
272 /* initialize status */
273 if (status != NULL)
274 *status = uuid_s_error;
275
276 /* sanity check argument(s) */
277 if (uuid_dce == NULL)
278 return 0;
279
280 /* generate a hash value
281 (DCE 1.1 actually requires 16-bit only) */
282 hash = 0;
283 ucp = (unsigned char *)uuid_dce;
284 for (i = UUID_LEN_BIN-1; i >= 0; i--) {
285 hash <<= 8;
286 hash |= ucp[i];
287 }
288
289 /* return successfully */
290 if (status != NULL)
291 *status = uuid_s_ok;
292 return hash;
293 }
294
295