LCOV - code coverage report
Current view: top level - ctrl/include - ctrl_simple_changer.inl (source / functions) Hit Total Coverage
Test: crystal-facet-uml_v1.57.0_covts Lines: 0 56 0.0 %
Date: 2024-04-07 11:14:42 Functions: 0 4 0.0 %

          Line data    Source code
       1             : /* File: ctrl_simple_changer.c; Copyright and License: see below */
       2             : 
       3             : #include "ctrl_simple_changer.h"
       4             : #include "u8/u8_trace.h"
       5             : #include "u8/u8_log.h"
       6             : #include <assert.h>
       7             : 
       8           0 : static inline void ctrl_simple_changer_init ( ctrl_simple_changer_t *this_,
       9             :                                               ctrl_controller_t *controller,
      10             :                                               data_database_reader_t *db_reader )
      11             : {
      12           0 :     U8_TRACE_BEGIN();
      13           0 :     assert( NULL != controller );
      14           0 :     assert( NULL != db_reader );
      15             : 
      16             :     /* init member attributes */
      17           0 :     (*this_).controller = controller;
      18           0 :     (*this_).db_reader = db_reader;
      19             : 
      20           0 :     U8_TRACE_END();
      21           0 : }
      22             : 
      23           0 : static inline void ctrl_simple_changer_destroy ( ctrl_simple_changer_t *this_ )
      24             : {
      25           0 :     U8_TRACE_BEGIN();
      26           0 :     assert( NULL != (*this_).controller );
      27           0 :     assert( NULL != (*this_).db_reader );
      28             : 
      29             :     /* destroy member attributes */
      30           0 :     (*this_).controller = NULL;
      31           0 :     (*this_).db_reader = NULL;
      32             : 
      33           0 :     U8_TRACE_END();
      34           0 : }
      35             : 
      36           0 : static inline u8_error_t ctrl_simple_changer_update_classifier_name ( ctrl_simple_changer_t *this_,
      37             :                                                                       data_row_id_t classifier_id,
      38             :                                                                       const char* new_classifier_name,
      39             :                                                                       u8_error_t* out_info )
      40             : {
      41           0 :     U8_TRACE_BEGIN();
      42           0 :     assert( NULL != new_classifier_name );
      43           0 :     assert( NULL != out_info );
      44           0 :     u8_error_t result = U8_ERROR_NONE;
      45             : 
      46           0 :     ctrl_classifier_controller_t *const classifier_ctrl = ctrl_controller_get_classifier_control_ptr( (*this_).controller);
      47             : 
      48             :     /* To not run into TOCTOU problems, we try to change the name immediately and then check for success afterwards: */
      49             :     const u8_error_t initial_err
      50           0 :         = ctrl_classifier_controller_update_classifier_name( classifier_ctrl,
      51             :                                                              classifier_id,
      52             :                                                              new_classifier_name
      53             :                                                            );
      54           0 :     if ( u8_error_contains( initial_err, U8_ERROR_DUPLICATE_NAME ) )
      55             :     {
      56           0 :         *out_info = initial_err;
      57             : 
      58             :         /* find an alternative, unused name */
      59             :         char wish_name_buf[DATA_CLASSIFIER_MAX_NAME_SIZE];
      60           0 :         utf8stringbuf_t wish_name = UTF8STRINGBUF( wish_name_buf );
      61           0 :         result |= utf8stringbuf_copy_str( wish_name, new_classifier_name );  /* error to be reported to caller */
      62             :         {
      63           0 :             bool name_ok = false;
      64             :             static const uint_fast16_t MAX_SEARCH_STEP = 10000;
      65             :             static const uint_fast16_t FIRST_STEP = 2;
      66           0 :             for ( uint_fast16_t search_step = FIRST_STEP; ( search_step < MAX_SEARCH_STEP )&&( ! name_ok )&&( result == U8_ERROR_NONE ); search_step ++ )
      67             :             {
      68             :                 char new_name_buf[DATA_CLASSIFIER_MAX_NAME_SIZE];
      69           0 :                 utf8stringbuf_t new_name = UTF8STRINGBUF( new_name_buf );
      70             :                 const u8_error_t trunc_err
      71           0 :                     = ctrl_simple_changer_private_propose_classifier_name( this_,
      72           0 :                                                                            utf8stringbuf_get_string( wish_name ),
      73             :                                                                            search_step,
      74             :                                                                            new_name
      75             :                                                                          );
      76           0 :                 if ( trunc_err != U8_ERROR_NONE )
      77             :                 {
      78           0 :                     U8_TRACE_INFO_STR("Name truncated at search for alternative:", utf8stringbuf_get_string( new_name ) );
      79             :                 }
      80             :                 const u8_error_t retry_err
      81           0 :                     = ctrl_classifier_controller_update_classifier_name( classifier_ctrl,
      82             :                                                                          classifier_id,
      83           0 :                                                                          utf8stringbuf_get_string( new_name )
      84             :                                                                        );
      85           0 :                 if ( u8_error_contains( retry_err, U8_ERROR_DUPLICATE_NAME ) )
      86             :                 {
      87           0 :                     *out_info |= retry_err;
      88             :                 }
      89             :                 else
      90             :                 {
      91           0 :                     name_ok = ( retry_err == U8_ERROR_NONE );
      92           0 :                     result |= retry_err;
      93             :                 }
      94             :             }
      95             :         }
      96             :     }
      97             :     else
      98             :     {
      99           0 :         result = initial_err;
     100           0 :         *out_info = U8_ERROR_NONE;
     101             :     }
     102             : 
     103           0 :     U8_TRACE_END_ERR( result );
     104           0 :     return result;
     105             : }
     106             : 
     107           0 : static inline u8_error_t ctrl_simple_changer_private_propose_classifier_name ( ctrl_simple_changer_t *this_,
     108             :                                                                                const char* base_classifier_name,
     109             :                                                                                uint_fast16_t iteration,
     110             :                                                                                utf8stringbuf_t out_name )
     111             : {
     112           0 :     U8_TRACE_BEGIN();
     113           0 :     const size_t RESERVED_FOR_NUMBER = 5;
     114           0 :     assert( NULL != base_classifier_name );
     115           0 :     assert( utf8stringbuf_get_size(out_name) > RESERVED_FOR_NUMBER );
     116           0 :     u8_error_t result = U8_ERROR_NONE;
     117             : 
     118             :     /* find an alternative, unused name */
     119             :     /* copy the base_classifier_name to newname_buf */
     120             :     {
     121             :         utf8stringbuf_t shortened_new_name
     122           0 :             = utf8stringbuf_init( utf8stringbuf_get_size(out_name)-RESERVED_FOR_NUMBER, utf8stringbuf_get_string(out_name) );
     123           0 :         result |= utf8stringbuf_copy_str( shortened_new_name, base_classifier_name );
     124             :         /* null termination is guaranteed, also this function does not cut an utf8 code point in the middle. */
     125             :     }
     126             :     /* append a separator and the iteration number */
     127           0 :     result |= utf8stringbuf_append_str( out_name, "-" );
     128           0 :     result |= utf8stringbuf_append_int( out_name, iteration );
     129             : 
     130           0 :     U8_TRACE_END_ERR( result );
     131           0 :     return result;
     132             : }
     133             : 
     134             : 
     135             : /*
     136             : Copyright 2023-2024 Andreas Warnke
     137             : 
     138             : Licensed under the Apache License, Version 2.0 (the "License");
     139             : you may not use this file except in compliance with the License.
     140             : You may obtain a copy of the License at
     141             : 
     142             :     http://www.apache.org/licenses/LICENSE-2.0
     143             : 
     144             : Unless required by applicable law or agreed to in writing, software
     145             : distributed under the License is distributed on an "AS IS" BASIS,
     146             : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     147             : See the License for the specific language governing permissions and
     148             : limitations under the License.
     149             : */

Generated by: LCOV version 1.16