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 8505 : static inline u8_error_t data_uuid_init ( data_uuid_t *this_, utf8string_t *uuid_string ) 12 : { 13 8505 : assert( NULL != uuid_string ); 14 : utf8error_t strerr; 15 8505 : u8_error_t result = U8_ERROR_NONE; 16 : 17 8505 : (*this_).uuid_string = utf8stringbuf_init( sizeof((*this_).private_uuid_string_buffer), 18 8505 : (*this_).private_uuid_string_buffer 19 : ); 20 8505 : strerr = utf8stringbuf_copy_str( (*this_).uuid_string, uuid_string ); 21 8505 : if ( strerr != UTF8ERROR_SUCCESS ) 22 : { 23 0 : U8_LOG_ERROR_INT( "utf8stringbuf_copy_str() failed:", strerr ); 24 0 : result |= U8_ERROR_STRING_BUFFER_EXCEEDED; 25 : } 26 8505 : else if ( utf8stringbuf_get_length( (*this_).uuid_string ) != DATA_UUID_STRING_LENGTH ) 27 : { 28 0 : U8_LOG_ERROR_INT( "uuid_string too short:", utf8stringbuf_get_length( (*this_).uuid_string ) ); 29 0 : result |= U8_ERROR_VALUE_OUT_OF_RANGE; 30 : } 31 : 32 8505 : return result; 33 : } 34 : 35 49 : static inline u8_error_t data_uuid_reinit ( data_uuid_t *this_, utf8string_t *uuid_string ) 36 : { 37 49 : return data_uuid_init( this_, uuid_string ); 38 : } 39 : 40 1886 : static inline void data_uuid_init_new ( data_uuid_t *this_ ) 41 : { 42 1886 : (*this_).uuid_string = utf8stringbuf_init( sizeof((*this_).private_uuid_string_buffer), 43 1886 : (*this_).private_uuid_string_buffer 44 : ); 45 1886 : 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 1886 : clock_t now = clock(); /* integer represents clocks, to be divided by CLOCKS_PER_SEC */ 50 : 51 : universal_simple_random_t rnd; 52 1886 : universal_simple_random_init( &rnd ); 53 : { 54 1886 : utf8error_t strerr = UTF8ERROR_SUCCESS; 55 : 56 : assert( sizeof(int) >= sizeof(uint32_t) ); 57 1886 : const uint32_t rand1 = now ^ universal_simple_random_get_uint32( &rnd ); 58 1886 : const uint16_t rand2 = universal_simple_random_get_uint16( &rnd ); 59 1886 : const uint16_t rand3 = (universal_simple_random_get_uint16( &rnd ) | 0x4000) & 0x4fff; /* version 4 (4 bits) */ 60 1886 : const uint16_t rand4 = (universal_simple_random_get_uint16( &rnd ) | 0x8000) & 0xbfff; /* 2 reserved bits */ 61 1886 : const uint16_t rand5 = universal_simple_random_get_uint16( &rnd ); 62 1886 : const uint32_t rand6 = universal_simple_random_get_uint32( &rnd ); 63 : 64 : char thirtyseven_bytes[DATA_UUID_STRING_LENGTH+1]; 65 1886 : 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 1886 : assert( length == sizeof(thirtyseven_bytes) - sizeof((const char)'\0') ); 75 : data_uuid_unused( length ); 76 1886 : strerr |= utf8stringbuf_append_str( (*this_).uuid_string, &(thirtyseven_bytes[0]) ); 77 1886 : assert( strerr == UTF8ERROR_SUCCESS ); 78 : } 79 1886 : universal_simple_random_destroy( &rnd ); 80 1886 : } 81 : 82 221 : static inline void data_uuid_copy ( data_uuid_t *this_, const data_uuid_t *original ) 83 : { 84 221 : assert( NULL != original ); 85 : 86 221 : (*this_) = (*original); 87 : /* repair the overwritten pointers */ 88 221 : (*this_).uuid_string = utf8stringbuf_init( sizeof((*this_).private_uuid_string_buffer), 89 221 : (*this_).private_uuid_string_buffer 90 : ); 91 221 : } 92 : 93 406 : static inline void data_uuid_replace ( data_uuid_t *this_, const data_uuid_t *that ) 94 : { 95 406 : assert( NULL != that ); 96 : 97 406 : (*this_) = (*that); 98 : /* repair the overwritten pointers */ 99 406 : (*this_).uuid_string = utf8stringbuf_init( sizeof((*this_).private_uuid_string_buffer), 100 406 : (*this_).private_uuid_string_buffer 101 : ); 102 406 : } 103 : 104 919 : static inline void data_uuid_destroy ( data_uuid_t *this_ ) 105 : { 106 919 : } 107 : 108 1086 : static inline utf8string_t * data_uuid_get_string ( const data_uuid_t *this_ ) 109 : { 110 1086 : 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 : */