Line data Source code
1 : /* File: data_uuid.c; Copyright and License: see below */ 2 : 3 : #include "u8stream/universal_simple_random.h" 4 : #include "u8/u8_trace.h" 5 : #include "u8/u8_log.h" 6 : #include <time.h> 7 : #include <assert.h> 8 : 9 : #define data_uuid_unused(variable) ((void)(variable)) 10 : 11 13835 : static inline u8_error_t data_uuid_init ( data_uuid_t *this_, utf8string_t *uuid_string ) 12 : { 13 13835 : assert( NULL != uuid_string ); 14 : utf8error_t strerr; 15 13835 : u8_error_t result = U8_ERROR_NONE; 16 : 17 13835 : (*this_).uuid_string = utf8stringbuf_init( sizeof((*this_).private_uuid_string_buffer), 18 13835 : (*this_).private_uuid_string_buffer 19 : ); 20 13835 : strerr = utf8stringbuf_copy_str( (*this_).uuid_string, uuid_string ); 21 13835 : if ( strerr != UTF8ERROR_SUCCESS ) 22 : { 23 5 : U8_LOG_ERROR_INT( "utf8stringbuf_copy_str() failed:", strerr ); 24 5 : result |= U8_ERROR_STRING_BUFFER_EXCEEDED; 25 : } 26 13830 : else if ( utf8stringbuf_get_length( (*this_).uuid_string ) != DATA_UUID_STRING_LENGTH ) 27 : { 28 5 : U8_LOG_ERROR_INT( "uuid_string too short:", utf8stringbuf_get_length( (*this_).uuid_string ) ); 29 5 : result |= U8_ERROR_VALUE_OUT_OF_RANGE; 30 : } 31 : 32 13835 : return result; 33 : } 34 : 35 64 : static inline u8_error_t data_uuid_reinit ( data_uuid_t *this_, utf8string_t *uuid_string ) 36 : { 37 64 : return data_uuid_init( this_, uuid_string ); 38 : } 39 : 40 2731 : static inline void data_uuid_init_new ( data_uuid_t *this_ ) 41 : { 42 2731 : (*this_).uuid_string = utf8stringbuf_init( sizeof((*this_).private_uuid_string_buffer), 43 2731 : (*this_).private_uuid_string_buffer 44 : ); 45 2731 : utf8stringbuf_clear( (*this_).uuid_string ); 46 : 47 : /* Get current time to enrich the universal_random_t by additional entropy. */ 48 : /* Otherwise the pseudo-random number only depends on the initial seed and number of samples already produced. */ 49 2731 : clock_t now = clock(); /* integer represents clocks, to be divided by CLOCKS_PER_SEC */ 50 : 51 : universal_simple_random_t rnd; 52 2731 : universal_simple_random_init( &rnd ); 53 : { 54 2731 : utf8error_t strerr = UTF8ERROR_SUCCESS; 55 : 56 : assert( sizeof(int) >= sizeof(uint32_t) ); 57 2731 : const uint32_t rand1 = now ^ universal_simple_random_get_uint32( &rnd ); 58 2731 : const uint16_t rand2 = universal_simple_random_get_uint16( &rnd ); 59 2731 : const uint16_t rand3 = (universal_simple_random_get_uint16( &rnd ) | 0x4000) & 0x4fff; /* version 4 (4 bits) */ 60 2731 : const uint16_t rand4 = (universal_simple_random_get_uint16( &rnd ) | 0x8000) & 0xbfff; /* 2 reserved bits */ 61 2731 : const uint16_t rand5 = universal_simple_random_get_uint16( &rnd ); 62 2731 : const uint32_t rand6 = universal_simple_random_get_uint32( &rnd ); 63 : 64 : char thirtyseven_bytes[DATA_UUID_STRING_LENGTH+1]; 65 2731 : const int length = sprintf( &(thirtyseven_bytes[0]), 66 : "%08x-%04x-%04x-%04x-%04x%08x", 67 : rand1, 68 : rand2, 69 : rand3, 70 : rand4, 71 : rand5, 72 : rand6 73 : ); 74 2731 : assert( length == sizeof(thirtyseven_bytes) - sizeof((const char)'\0') ); 75 : data_uuid_unused( length ); 76 2731 : strerr |= utf8stringbuf_append_str( (*this_).uuid_string, &(thirtyseven_bytes[0]) ); 77 2731 : assert( strerr == UTF8ERROR_SUCCESS ); 78 : } 79 2731 : universal_simple_random_destroy( &rnd ); 80 2731 : } 81 : 82 1765 : static inline void data_uuid_copy ( data_uuid_t *this_, const data_uuid_t *original ) 83 : { 84 1765 : assert( NULL != original ); 85 : 86 1765 : (*this_) = (*original); 87 : /* repair the overwritten pointers */ 88 1765 : (*this_).uuid_string = utf8stringbuf_init( sizeof((*this_).private_uuid_string_buffer), 89 1765 : (*this_).private_uuid_string_buffer 90 : ); 91 1765 : } 92 : 93 413 : static inline void data_uuid_replace ( data_uuid_t *this_, const data_uuid_t *that ) 94 : { 95 413 : assert( NULL != that ); 96 : 97 413 : (*this_) = (*that); 98 : /* repair the overwritten pointers */ 99 413 : (*this_).uuid_string = utf8stringbuf_init( sizeof((*this_).private_uuid_string_buffer), 100 413 : (*this_).private_uuid_string_buffer 101 : ); 102 413 : } 103 : 104 5931 : static inline void data_uuid_destroy ( data_uuid_t *this_ ) 105 : { 106 5931 : } 107 : 108 4894 : static inline utf8string_t * data_uuid_get_string ( const data_uuid_t *this_ ) 109 : { 110 4894 : return utf8stringbuf_get_string( (*this_).uuid_string ); 111 : } 112 : 113 : static inline void data_uuid_trace ( const data_uuid_t *this_ ) 114 : { 115 : U8_TRACE_INFO_STR( "data_uuid_t", utf8stringbuf_get_string( (*this_).uuid_string ) ); 116 : } 117 : 118 : 119 : /* 120 : Copyright 2021-2024 Andreas Warnke 121 : 122 : Licensed under the Apache License, Version 2.0 (the "License"); 123 : you may not use this file except in compliance with the License. 124 : You may obtain a copy of the License at 125 : 126 : http://www.apache.org/licenses/LICENSE-2.0 127 : 128 : Unless required by applicable law or agreed to in writing, software 129 : distributed under the License is distributed on an "AS IS" BASIS, 130 : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 131 : See the License for the specific language governing permissions and 132 : limitations under the License. 133 : */