xref: /aoo4110/main/sal/rtl/source/uuid.cxx (revision b1cdbd2c)
1*b1cdbd2cSJim Jagielski /**************************************************************
2*b1cdbd2cSJim Jagielski  *
3*b1cdbd2cSJim Jagielski  * Licensed to the Apache Software Foundation (ASF) under one
4*b1cdbd2cSJim Jagielski  * or more contributor license agreements.  See the NOTICE file
5*b1cdbd2cSJim Jagielski  * distributed with this work for additional information
6*b1cdbd2cSJim Jagielski  * regarding copyright ownership.  The ASF licenses this file
7*b1cdbd2cSJim Jagielski  * to you under the Apache License, Version 2.0 (the
8*b1cdbd2cSJim Jagielski  * "License"); you may not use this file except in compliance
9*b1cdbd2cSJim Jagielski  * with the License.  You may obtain a copy of the License at
10*b1cdbd2cSJim Jagielski  *
11*b1cdbd2cSJim Jagielski  *   http://www.apache.org/licenses/LICENSE-2.0
12*b1cdbd2cSJim Jagielski  *
13*b1cdbd2cSJim Jagielski  * Unless required by applicable law or agreed to in writing,
14*b1cdbd2cSJim Jagielski  * software distributed under the License is distributed on an
15*b1cdbd2cSJim Jagielski  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*b1cdbd2cSJim Jagielski  * KIND, either express or implied.  See the License for the
17*b1cdbd2cSJim Jagielski  * specific language governing permissions and limitations
18*b1cdbd2cSJim Jagielski  * under the License.
19*b1cdbd2cSJim Jagielski  *
20*b1cdbd2cSJim Jagielski  *************************************************************/
21*b1cdbd2cSJim Jagielski 
22*b1cdbd2cSJim Jagielski 
23*b1cdbd2cSJim Jagielski 
24*b1cdbd2cSJim Jagielski // MARKER(update_precomp.py): autogen include statement, do not remove
25*b1cdbd2cSJim Jagielski #include "precompiled_sal.hxx"
26*b1cdbd2cSJim Jagielski 
27*b1cdbd2cSJim Jagielski #include <string.h>
28*b1cdbd2cSJim Jagielski #include <stdlib.h>
29*b1cdbd2cSJim Jagielski 
30*b1cdbd2cSJim Jagielski #include <osl/mutex.hxx>
31*b1cdbd2cSJim Jagielski #include <rtl/random.h>
32*b1cdbd2cSJim Jagielski #include <rtl/uuid.h>
33*b1cdbd2cSJim Jagielski #include <rtl/digest.h>
34*b1cdbd2cSJim Jagielski 
35*b1cdbd2cSJim Jagielski #define SWAP_INT32_TO_NETWORK(x)\
36*b1cdbd2cSJim Jagielski                { sal_uInt32 y = x;\
37*b1cdbd2cSJim Jagielski 				 sal_uInt8 *p = (sal_uInt8 * )&(x); \
38*b1cdbd2cSJim Jagielski 				 p[0] = (sal_uInt8) ( ( y >> 24 ) & 0xff );\
39*b1cdbd2cSJim Jagielski                  p[1] = (sal_uInt8) ( ( y >> 16 ) & 0xff );\
40*b1cdbd2cSJim Jagielski                  p[2] = (sal_uInt8) ( ( y >> 8 )  & 0xff );\
41*b1cdbd2cSJim Jagielski                  p[3] = (sal_uInt8) ( ( y ) & 0xff);\
42*b1cdbd2cSJim Jagielski                }
43*b1cdbd2cSJim Jagielski #define SWAP_INT16_TO_NETWORK(x)\
44*b1cdbd2cSJim Jagielski                { sal_uInt16 y = x;\
45*b1cdbd2cSJim Jagielski 				 sal_uInt8 *p = (sal_uInt8 * )&(x); \
46*b1cdbd2cSJim Jagielski                  p[0] = (sal_uInt8) ( ( y >> 8 )  & 0xff );\
47*b1cdbd2cSJim Jagielski                  p[1] = (sal_uInt8) ( ( y ) & 0xff);\
48*b1cdbd2cSJim Jagielski                }
49*b1cdbd2cSJim Jagielski 
50*b1cdbd2cSJim Jagielski #define SWAP_NETWORK_TO_INT16(x)\
51*b1cdbd2cSJim Jagielski                { sal_uInt16 y = x;\
52*b1cdbd2cSJim Jagielski 				 sal_uInt8 *p = (sal_uInt8 * )&(y);\
53*b1cdbd2cSJim Jagielski                  x = ( ( ((sal_uInt16)p[0]) & 0xff) << 8 ) |\
54*b1cdbd2cSJim Jagielski                      ( (  (sal_uInt16)p[1]) & 0xff);\
55*b1cdbd2cSJim Jagielski                }
56*b1cdbd2cSJim Jagielski #define SWAP_NETWORK_TO_INT32(x)\
57*b1cdbd2cSJim Jagielski                { sal_uInt32 y = x;\
58*b1cdbd2cSJim Jagielski 				 sal_uInt8 *p = (sal_uInt8 * )&(y); \
59*b1cdbd2cSJim Jagielski                  x = ( ( ((sal_uInt32)p[0]) & 0xff) << 24 ) |\
60*b1cdbd2cSJim Jagielski                      ( ( ((sal_uInt32)p[1]) & 0xff) << 16 ) |\
61*b1cdbd2cSJim Jagielski                      ( ( ((sal_uInt32)p[2]) & 0xff) << 8  ) |\
62*b1cdbd2cSJim Jagielski                      ( (  (sal_uInt32)p[3]) & 0xff);\
63*b1cdbd2cSJim Jagielski                }
64*b1cdbd2cSJim Jagielski 
65*b1cdbd2cSJim Jagielski typedef struct _UUID
66*b1cdbd2cSJim Jagielski {
67*b1cdbd2cSJim Jagielski       sal_uInt32          time_low;
68*b1cdbd2cSJim Jagielski       sal_uInt16          time_mid;
69*b1cdbd2cSJim Jagielski       sal_uInt16          time_hi_and_version;
70*b1cdbd2cSJim Jagielski       sal_uInt8           clock_seq_hi_and_reserved;
71*b1cdbd2cSJim Jagielski       sal_uInt8           clock_seq_low;
72*b1cdbd2cSJim Jagielski       sal_uInt8           node[6];
73*b1cdbd2cSJim Jagielski } UUID;
74*b1cdbd2cSJim Jagielski 
write_v3(sal_uInt8 * pUuid)75*b1cdbd2cSJim Jagielski static  void write_v3( sal_uInt8 *pUuid  )
76*b1cdbd2cSJim Jagielski {
77*b1cdbd2cSJim Jagielski     UUID uuid;
78*b1cdbd2cSJim Jagielski 	// copy to avoid alignment problems
79*b1cdbd2cSJim Jagielski     memcpy( &uuid , pUuid , 16 );
80*b1cdbd2cSJim Jagielski 
81*b1cdbd2cSJim Jagielski 	SWAP_NETWORK_TO_INT32( uuid.time_low );
82*b1cdbd2cSJim Jagielski 	SWAP_NETWORK_TO_INT16( uuid.time_mid );
83*b1cdbd2cSJim Jagielski 	SWAP_NETWORK_TO_INT16( uuid.time_hi_and_version );
84*b1cdbd2cSJim Jagielski 
85*b1cdbd2cSJim Jagielski     /* put in the variant and version bits */
86*b1cdbd2cSJim Jagielski 	uuid.time_hi_and_version       &= 0x0FFF;
87*b1cdbd2cSJim Jagielski 	uuid.time_hi_and_version       |= (3 << 12);
88*b1cdbd2cSJim Jagielski 	uuid.clock_seq_hi_and_reserved &= 0x3F;
89*b1cdbd2cSJim Jagielski 	uuid.clock_seq_hi_and_reserved |= 0x80;
90*b1cdbd2cSJim Jagielski 
91*b1cdbd2cSJim Jagielski 	SWAP_INT32_TO_NETWORK( uuid.time_low );
92*b1cdbd2cSJim Jagielski 	SWAP_INT16_TO_NETWORK( uuid.time_mid );
93*b1cdbd2cSJim Jagielski 	SWAP_INT16_TO_NETWORK( uuid.time_hi_and_version );
94*b1cdbd2cSJim Jagielski 
95*b1cdbd2cSJim Jagielski 	memcpy( pUuid , &uuid , 16 );
96*b1cdbd2cSJim Jagielski }
97*b1cdbd2cSJim Jagielski 
98*b1cdbd2cSJim Jagielski 
rtl_createUuid(sal_uInt8 * pTargetUUID,const sal_uInt8 *,sal_Bool)99*b1cdbd2cSJim Jagielski extern "C" void SAL_CALL rtl_createUuid( sal_uInt8 *pTargetUUID ,
100*b1cdbd2cSJim Jagielski                                          const sal_uInt8 *, sal_Bool )
101*b1cdbd2cSJim Jagielski {
102*b1cdbd2cSJim Jagielski     {
103*b1cdbd2cSJim Jagielski         osl::MutexGuard g(osl::Mutex::getGlobalMutex());
104*b1cdbd2cSJim Jagielski         static rtlRandomPool pool = NULL;
105*b1cdbd2cSJim Jagielski         if (pool == NULL) {
106*b1cdbd2cSJim Jagielski             pool = rtl_random_createPool();
107*b1cdbd2cSJim Jagielski             if (pool == NULL) {
108*b1cdbd2cSJim Jagielski                 abort();
109*b1cdbd2cSJim Jagielski                     // only possible way to signal failure here (rtl_createUuid
110*b1cdbd2cSJim Jagielski                     // being part of a fixed C API)
111*b1cdbd2cSJim Jagielski             }
112*b1cdbd2cSJim Jagielski         }
113*b1cdbd2cSJim Jagielski         if (rtl_random_getBytes(pool, pTargetUUID, 16) != rtl_Random_E_None) {
114*b1cdbd2cSJim Jagielski             abort();
115*b1cdbd2cSJim Jagielski                 // only possible way to signal failure here (rtl_createUuid
116*b1cdbd2cSJim Jagielski                 // being part of a fixed C API)
117*b1cdbd2cSJim Jagielski         }
118*b1cdbd2cSJim Jagielski     }
119*b1cdbd2cSJim Jagielski     // See ITU-T Recommendation X.667:
120*b1cdbd2cSJim Jagielski     pTargetUUID[6] &= 0x0F;
121*b1cdbd2cSJim Jagielski     pTargetUUID[6] |= 0x40;
122*b1cdbd2cSJim Jagielski     pTargetUUID[8] &= 0x3F;
123*b1cdbd2cSJim Jagielski     pTargetUUID[8] |= 0x80;
124*b1cdbd2cSJim Jagielski }
125*b1cdbd2cSJim Jagielski 
126*b1cdbd2cSJim Jagielski 
rtl_createNamedUuid(sal_uInt8 * pTargetUUID,const sal_uInt8 * pNameSpaceUUID,const rtl_String * pName)127*b1cdbd2cSJim Jagielski extern "C" void SAL_CALL rtl_createNamedUuid( sal_uInt8  *pTargetUUID,
128*b1cdbd2cSJim Jagielski                                               const sal_uInt8  *pNameSpaceUUID,
129*b1cdbd2cSJim Jagielski                                               const rtl_String *pName )
130*b1cdbd2cSJim Jagielski {
131*b1cdbd2cSJim Jagielski 	rtlDigest digest = rtl_digest_createMD5  ();
132*b1cdbd2cSJim Jagielski 
133*b1cdbd2cSJim Jagielski 	rtl_digest_updateMD5( digest, pNameSpaceUUID , 16 );
134*b1cdbd2cSJim Jagielski 	rtl_digest_updateMD5( digest, pName->buffer , pName->length );
135*b1cdbd2cSJim Jagielski 
136*b1cdbd2cSJim Jagielski 	rtl_digest_getMD5( digest, pTargetUUID , 16 );
137*b1cdbd2cSJim Jagielski 	rtl_digest_destroyMD5 (digest);
138*b1cdbd2cSJim Jagielski 
139*b1cdbd2cSJim Jagielski 	write_v3(pTargetUUID);
140*b1cdbd2cSJim Jagielski }
141*b1cdbd2cSJim Jagielski 
142*b1cdbd2cSJim Jagielski 
143*b1cdbd2cSJim Jagielski 
rtl_compareUuid(const sal_uInt8 * pUUID1,const sal_uInt8 * pUUID2)144*b1cdbd2cSJim Jagielski extern "C" sal_Int32 SAL_CALL rtl_compareUuid( const sal_uInt8 *pUUID1 , const sal_uInt8 *pUUID2 )
145*b1cdbd2cSJim Jagielski {
146*b1cdbd2cSJim Jagielski     int i;
147*b1cdbd2cSJim Jagielski 	UUID u1;
148*b1cdbd2cSJim Jagielski 	UUID u2;
149*b1cdbd2cSJim Jagielski 	memcpy( &u1 , pUUID1 , 16 );
150*b1cdbd2cSJim Jagielski 	memcpy( &u2 , pUUID2 , 16 );
151*b1cdbd2cSJim Jagielski 
152*b1cdbd2cSJim Jagielski 	SWAP_NETWORK_TO_INT32( u1.time_low );
153*b1cdbd2cSJim Jagielski 	SWAP_NETWORK_TO_INT16( u1.time_mid );
154*b1cdbd2cSJim Jagielski 	SWAP_NETWORK_TO_INT16( u1.time_hi_and_version );
155*b1cdbd2cSJim Jagielski 
156*b1cdbd2cSJim Jagielski 	SWAP_NETWORK_TO_INT32( u2.time_low );
157*b1cdbd2cSJim Jagielski 	SWAP_NETWORK_TO_INT16( u2.time_mid );
158*b1cdbd2cSJim Jagielski 	SWAP_NETWORK_TO_INT16( u2.time_hi_and_version );
159*b1cdbd2cSJim Jagielski 
160*b1cdbd2cSJim Jagielski #define CHECK(f1, f2) if (f1 != f2) return f1 < f2 ? -1 : 1;
161*b1cdbd2cSJim Jagielski     CHECK(u1.time_low, u2.time_low);
162*b1cdbd2cSJim Jagielski     CHECK(u1.time_mid, u2.time_mid);
163*b1cdbd2cSJim Jagielski     CHECK(u1.time_hi_and_version, u2.time_hi_and_version);
164*b1cdbd2cSJim Jagielski     CHECK(u1.clock_seq_hi_and_reserved, u2.clock_seq_hi_and_reserved);
165*b1cdbd2cSJim Jagielski     CHECK(u1.clock_seq_low, u2.clock_seq_low);
166*b1cdbd2cSJim Jagielski     for (i = 0; i < 6; i++)
167*b1cdbd2cSJim Jagielski 	{
168*b1cdbd2cSJim Jagielski         if (u1.node[i] < u2.node[i])
169*b1cdbd2cSJim Jagielski 			return -1;
170*b1cdbd2cSJim Jagielski         if (u1.node[i] > u2.node[i])
171*b1cdbd2cSJim Jagielski 			return 1;
172*b1cdbd2cSJim Jagielski 	}
173*b1cdbd2cSJim Jagielski     return 0;
174*b1cdbd2cSJim Jagielski 
175*b1cdbd2cSJim Jagielski }
176*b1cdbd2cSJim Jagielski 
177