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 8531 : static inline u8_error_t data_uuid_init ( data_uuid_t *this_, utf8string_t *uuid_string )
12 : {
13 8531 : assert( NULL != uuid_string );
14 : utf8error_t strerr;
15 8531 : u8_error_t result = U8_ERROR_NONE;
16 :
17 8531 : (*this_).uuid_string = utf8stringbuf_new( (*this_).private_uuid_string_buffer,
18 : sizeof((*this_).private_uuid_string_buffer)
19 : );
20 8531 : strerr = utf8stringbuf_copy_str( &((*this_).uuid_string), uuid_string );
21 8531 : 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 8526 : 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 8531 : return result;
33 : }
34 :
35 98 : static inline u8_error_t data_uuid_reinit ( data_uuid_t *this_, utf8string_t *uuid_string )
36 : {
37 98 : return data_uuid_init( this_, uuid_string );
38 : }
39 :
40 2909 : static inline void data_uuid_init_new ( data_uuid_t *this_ )
41 : {
42 2909 : (*this_).uuid_string = utf8stringbuf_new( (*this_).private_uuid_string_buffer,
43 : sizeof((*this_).private_uuid_string_buffer)
44 : );
45 2909 : 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 2909 : clock_t now = clock(); /* integer represents clocks, to be divided by CLOCKS_PER_SEC */
50 :
51 : universal_simple_random_t rnd;
52 2909 : universal_simple_random_init( &rnd );
53 : {
54 2909 : utf8error_t strerr = UTF8ERROR_SUCCESS;
55 :
56 : assert( sizeof(int) >= sizeof(uint32_t) );
57 2909 : const uint32_t rand1 = now ^ universal_simple_random_get_uint32( &rnd );
58 2909 : const uint16_t rand2 = universal_simple_random_get_uint16( &rnd );
59 2909 : const uint16_t rand3 = (universal_simple_random_get_uint16( &rnd ) | 0x4000) & 0x4fff; /* version 4 (4 bits) */
60 2909 : const uint16_t rand4 = (universal_simple_random_get_uint16( &rnd ) | 0x8000) & 0xbfff; /* 2 reserved bits */
61 2909 : const uint16_t rand5 = universal_simple_random_get_uint16( &rnd );
62 2909 : const uint32_t rand6 = universal_simple_random_get_uint32( &rnd );
63 :
64 : char thirtyseven_bytes[DATA_UUID_STRING_LENGTH+1];
65 2909 : 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 2909 : assert( length == sizeof(thirtyseven_bytes) - sizeof((const char)'\0') );
75 : data_uuid_unused( length );
76 2909 : strerr |= utf8stringbuf_append_str( &((*this_).uuid_string), &(thirtyseven_bytes[0]) );
77 2909 : assert( strerr == UTF8ERROR_SUCCESS );
78 : (void) strerr; /* in RELEASE mode, ignore strerr */
79 : }
80 2909 : universal_simple_random_destroy( &rnd );
81 2909 : }
82 :
83 1213 : static inline void data_uuid_copy ( data_uuid_t *this_, const data_uuid_t *original )
84 : {
85 1213 : assert( NULL != original );
86 :
87 1213 : (*this_) = (*original);
88 : /* repair the overwritten pointers */
89 1213 : (*this_).uuid_string = utf8stringbuf_new( (*this_).private_uuid_string_buffer,
90 : sizeof((*this_).private_uuid_string_buffer)
91 : );
92 1213 : }
93 :
94 516 : static inline void data_uuid_replace ( data_uuid_t *this_, const data_uuid_t *that )
95 : {
96 516 : assert( NULL != that );
97 :
98 516 : (*this_) = (*that);
99 : /* repair the overwritten pointers */
100 516 : (*this_).uuid_string = utf8stringbuf_new( (*this_).private_uuid_string_buffer,
101 : sizeof((*this_).private_uuid_string_buffer)
102 : );
103 516 : }
104 :
105 4013 : static inline void data_uuid_destroy ( data_uuid_t *this_ )
106 : {
107 4013 : }
108 :
109 3451 : static inline utf8string_t * data_uuid_get_string ( const data_uuid_t *this_ )
110 : {
111 3451 : return utf8stringbuf_get_string( &((*this_).uuid_string) );
112 : }
113 :
114 : static inline void data_uuid_trace ( const data_uuid_t *this_ )
115 : {
116 : U8_TRACE_INFO_STR( "data_uuid_t", utf8stringbuf_get_string( &((*this_).uuid_string) ) );
117 : }
118 :
119 :
120 : /*
121 : Copyright 2021-2026 Andreas Warnke
122 :
123 : Licensed under the Apache License, Version 2.0 (the "License");
124 : you may not use this file except in compliance with the License.
125 : You may obtain a copy of the License at
126 :
127 : http://www.apache.org/licenses/LICENSE-2.0
128 :
129 : Unless required by applicable law or agreed to in writing, software
130 : distributed under the License is distributed on an "AS IS" BASIS,
131 : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
132 : See the License for the specific language governing permissions and
133 : limitations under the License.
134 : */
|