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