LCOV - code coverage report
Current view: top level - io/source - io_exporter.c (source / functions) Coverage Total Hit
Test: crystal-facet-uml_v1.63.2_covts Lines: 19.6 % 347 68
Test Date: 2025-05-01 10:10:14 Functions: 33.3 % 12 4

            Line data    Source code
       1              : /* File: io_exporter.c; Copyright and License: see below */
       2              : 
       3              : #include "io_exporter.h"
       4              : #include "document/document_css_writer.h"
       5              : #include "json/json_schema_writer.h"
       6              : #include "u8stream/universal_file_output_stream.h"
       7              : #include "u8stream/universal_output_stream.h"
       8              : #include "xmi/xmi_writer_pass.h"
       9              : #include "u8/u8_trace.h"
      10              : #include "u8/u8_log.h"
      11              : #include "io_gtk.h"
      12              : #include <cairo-svg.h>
      13              : #include <cairo-pdf.h>
      14              : #include <cairo-ps.h>
      15              : #include <stdbool.h>
      16              : #include <assert.h>
      17              : 
      18              : enum io_exporter_max_enum {
      19              :     IO_EXPORTER_MAX_DIAGRAM_TREE_DEPTH = 16,
      20              : };
      21              : 
      22            2 : void io_exporter_init ( io_exporter_t *this_,
      23              :                         data_database_reader_t *db_reader )
      24              : {
      25            2 :     U8_TRACE_BEGIN();
      26            2 :     assert( NULL != db_reader );
      27              : 
      28            2 :     (*this_).db_reader = db_reader;
      29              : 
      30            2 :     (*this_).temp_filename = utf8stringbuf_new( (*this_).temp_filename_buf, sizeof((*this_).temp_filename_buf) );
      31            2 :     utf8stringbuf_clear( &((*this_).temp_filename) );
      32              : 
      33            2 :     U8_TRACE_END();
      34            2 : }
      35              : 
      36            2 : void io_exporter_destroy( io_exporter_t *this_ )
      37              : {
      38            2 :     U8_TRACE_BEGIN();
      39              : 
      40            2 :     (*this_).db_reader = NULL;
      41              : 
      42            2 :     U8_TRACE_END();
      43            2 : }
      44              : 
      45            0 : u8_error_t io_exporter_export_files( io_exporter_t *this_,
      46              :                                      io_file_format_t export_type,
      47              :                                      const char *target_folder,
      48              :                                      const char *document_file_path,
      49              :                                      data_stat_t *io_export_stat )
      50              : {
      51            0 :     U8_TRACE_BEGIN();
      52            0 :     assert ( NULL != target_folder );
      53            0 :     assert ( NULL != document_file_path );
      54            0 :     assert ( NULL != io_export_stat );
      55            0 :     u8_error_t export_err = U8_ERROR_NONE;
      56              : 
      57              :     /* transform file path to name */
      58              :     char temp_filename_buf[48];
      59            0 :     utf8stringbuf_t temp_filename = UTF8STRINGBUF(temp_filename_buf);
      60            0 :     u8_error_t err = io_exporter_private_get_filename( this_, document_file_path, temp_filename );
      61            0 :     const char *const document_file_name = (err==0) ? utf8stringbuf_get_string( &temp_filename ) : "document";
      62              : 
      63            0 :     if ( NULL != target_folder )
      64              :     {
      65            0 :         if ( ( export_type & IO_FILE_FORMAT_SVG ) != 0 )
      66              :         {
      67            0 :             export_err |= io_exporter_private_export_image_files( this_, DATA_ID_VOID, IO_EXPORTER_MAX_DIAGRAM_TREE_DEPTH, IO_FILE_FORMAT_SVG, target_folder, io_export_stat );
      68              :         }
      69              : 
      70            0 :         if ( ( export_type & ( IO_FILE_FORMAT_PDF | IO_FILE_FORMAT_DOCBOOK ) ) != 0 )
      71              :         {
      72            0 :             export_err |= io_exporter_private_export_image_files( this_, DATA_ID_VOID, IO_EXPORTER_MAX_DIAGRAM_TREE_DEPTH, IO_FILE_FORMAT_PDF, target_folder, io_export_stat );
      73              :         }
      74              : 
      75            0 :         if ( ( export_type & IO_FILE_FORMAT_PS ) != 0 )
      76              :         {
      77            0 :             export_err |= io_exporter_private_export_image_files( this_, DATA_ID_VOID, IO_EXPORTER_MAX_DIAGRAM_TREE_DEPTH, IO_FILE_FORMAT_PS, target_folder, io_export_stat );
      78              :         }
      79              : 
      80            0 :         if ( ( export_type & ( IO_FILE_FORMAT_PNG | IO_FILE_FORMAT_DOCBOOK | IO_FILE_FORMAT_HTML ) ) != 0 )
      81              :         {
      82            0 :             export_err |= io_exporter_private_export_image_files( this_, DATA_ID_VOID, IO_EXPORTER_MAX_DIAGRAM_TREE_DEPTH, IO_FILE_FORMAT_PNG, target_folder, io_export_stat );
      83              :         }
      84              : 
      85            0 :         if ( ( export_type & IO_FILE_FORMAT_TXT ) != 0 )
      86              :         {
      87            0 :             export_err |= io_exporter_private_export_image_files( this_, DATA_ID_VOID, IO_EXPORTER_MAX_DIAGRAM_TREE_DEPTH, IO_FILE_FORMAT_TXT, target_folder, io_export_stat );
      88              :         }
      89              : 
      90            0 :         if ( ( export_type & IO_FILE_FORMAT_DOCBOOK ) != 0 )
      91              :         {
      92            0 :             export_err |= io_exporter_private_export_document_file( this_, IO_FILE_FORMAT_DOCBOOK, target_folder, document_file_name, io_export_stat );
      93              :         }
      94              : 
      95            0 :         if ( ( export_type & IO_FILE_FORMAT_HTML ) != 0 )
      96              :         {
      97            0 :             export_err |= io_exporter_private_export_document_file( this_,
      98              :                                                                     IO_FILE_FORMAT_HTML,
      99              :                                                                     target_folder,
     100              :                                                                     document_file_name,
     101              :                                                                     io_export_stat
     102              :                                                                   );
     103            0 :             export_err |= io_exporter_private_export_document_file( this_,
     104              :                                                                     IO_FILE_FORMAT_CSS,
     105              :                                                                     target_folder,
     106              :                                                                     document_file_name,
     107              :                                                                     io_export_stat
     108              :                                                                   );
     109              :         }
     110              : 
     111            0 :         if ( ( export_type & IO_FILE_FORMAT_JSON ) != 0 )
     112              :         {
     113            0 :             export_err |= io_exporter_private_export_document_file( this_,
     114              :                                                                     IO_FILE_FORMAT_JSON,
     115              :                                                                     target_folder,
     116              :                                                                     document_file_name,
     117              :                                                                     io_export_stat
     118              :                                                                   );
     119            0 :             export_err |= io_exporter_private_export_document_file( this_,
     120              :                                                                     IO_FILE_FORMAT_SCHEMA,
     121              :                                                                     target_folder,
     122              :                                                                     document_file_name,
     123              :                                                                     io_export_stat
     124              :                                                                   );
     125              :         }
     126              : 
     127            0 :         if ( ( export_type & IO_FILE_FORMAT_XMI2 ) != 0 )
     128              :         {
     129            0 :             export_err |= io_exporter_private_export_document_file( this_, IO_FILE_FORMAT_XMI2, target_folder, document_file_name, io_export_stat );
     130              :         }
     131              :     }
     132              :     else /* target_folder == NULL */
     133              :     {
     134            0 :         U8_LOG_WARNING("selected target folder was NULL.");
     135            0 :         export_err = -1;
     136              :     }
     137              : 
     138            0 :     U8_TRACE_END_ERR(export_err);
     139            0 :     return export_err;
     140              : }
     141              : 
     142            0 : u8_error_t io_exporter_private_get_filename( io_exporter_t *this_,
     143              :                                              const char* path,
     144              :                                              utf8stringbuf_t out_base_filename )
     145              : {
     146            0 :     U8_TRACE_BEGIN();
     147            0 :     assert ( NULL != path );
     148            0 :     u8_error_t err = U8_ERROR_NONE;
     149              : 
     150            0 :     utf8stringview_t path_view = UTF8STRINGVIEW_STR( path );
     151              : 
     152              :     utf8stringview_t before_winpath_sep;
     153              :     utf8stringview_t after_winpath_sep;
     154            0 :     const utf8error_t err_w = utf8stringview_split_at_last_str( &path_view, "\\", &before_winpath_sep, &after_winpath_sep );
     155            0 :     if ( err_w != UTF8ERROR_SUCCESS )
     156              :     {
     157            0 :         after_winpath_sep = path_view;
     158              :     }
     159              :     utf8stringview_t before_unixpath_sep;
     160              :     utf8stringview_t after_unixpath_sep;
     161            0 :     const utf8error_t err_u = utf8stringview_split_at_last_str( &after_winpath_sep, "/", &before_unixpath_sep, &after_unixpath_sep );
     162            0 :     if ( err_u != UTF8ERROR_SUCCESS )
     163              :     {
     164            0 :         after_unixpath_sep = after_winpath_sep;
     165              :     }
     166              :     utf8stringview_t before_dot;
     167              :     utf8stringview_t after_dot;
     168            0 :     const utf8error_t err_d = utf8stringview_split_at_last_str( &after_unixpath_sep, ".", &before_dot, &after_dot );
     169            0 :     if ( ( err_d != UTF8ERROR_SUCCESS )
     170            0 :         || ( utf8stringview_get_length( &before_dot ) == 0 )
     171            0 :         || ( utf8stringview_get_length( &after_dot ) == 0 ) )
     172              :     {
     173              :         /* either no dot found or the filename begins with dot or the filename ends on dot */
     174            0 :         before_dot = after_unixpath_sep;
     175              :     }
     176              : 
     177            0 :     err = utf8stringbuf_copy_view( &out_base_filename, &before_dot );
     178            0 :     if ( utf8stringbuf_get_length( &out_base_filename ) == 0 )
     179              :     {
     180            0 :         err = U8_ERROR_INPUT_EMPTY;
     181              :     }
     182              : 
     183            0 :     U8_TRACE_END_ERR(err);
     184            0 :     return err;
     185              : }
     186              : 
     187            0 : u8_error_t io_exporter_private_export_image_files( io_exporter_t *this_,
     188              :                                                    data_id_t diagram_id,
     189              :                                                    uint32_t max_recursion,
     190              :                                                    io_file_format_t export_type,
     191              :                                                    const char *target_folder,
     192              :                                                    data_stat_t *io_export_stat )
     193              : {
     194            0 :     U8_TRACE_BEGIN();
     195            0 :     assert ( NULL != target_folder );
     196            0 :     assert ( NULL != io_export_stat );
     197            0 :     U8_TRACE_INFO_STR("target_folder:", target_folder );
     198            0 :     const data_row_t diagram_row_id = data_id_get_row_id( &diagram_id );
     199            0 :     u8_error_t result = U8_ERROR_NONE;
     200              : 
     201              :     /* draw current diagram */
     202            0 :     if ( DATA_ROW_VOID != diagram_row_id )
     203              :     {
     204            0 :         assert( data_id_get_table( &diagram_id ) == DATA_TABLE_DIAGRAM );
     205              : 
     206              :         /* determine filename */
     207            0 :         utf8stringbuf_copy_str( &((*this_).temp_filename), target_folder );
     208            0 :         utf8stringbuf_append_str( &((*this_).temp_filename), "/" );
     209            0 :         result |= io_exporter_private_get_filename_for_diagram( this_, diagram_id, utf8stringbuf_get_end( &((*this_).temp_filename) ) );
     210              : 
     211            0 :         if ( IO_FILE_FORMAT_SVG == export_type )
     212              :         {
     213            0 :             utf8stringbuf_append_str( &((*this_).temp_filename), ".svg" );
     214              :         }
     215            0 :         else if ( IO_FILE_FORMAT_PNG == export_type )
     216              :         {
     217            0 :             utf8stringbuf_append_str( &((*this_).temp_filename), ".png" );
     218              :         }
     219            0 :         else if ( IO_FILE_FORMAT_PDF == export_type )
     220              :         {
     221            0 :             utf8stringbuf_append_str( &((*this_).temp_filename), ".pdf" );
     222              :         }
     223            0 :         else if ( IO_FILE_FORMAT_PS == export_type )
     224              :         {
     225            0 :             utf8stringbuf_append_str( &((*this_).temp_filename), ".ps" );
     226              :         }
     227              :         else /* IO_FILE_FORMAT_TXT */
     228              :         {
     229            0 :             utf8stringbuf_append_str( &((*this_).temp_filename), ".txt" );
     230              :         }
     231            0 :         U8_LOG_EVENT_STR( "exporting diagram to file:", utf8stringbuf_get_string( &((*this_).temp_filename) ) );
     232              : 
     233            0 :         result |= io_exporter_export_image_file( this_,
     234              :                                                  diagram_id,
     235              :                                                  export_type,
     236            0 :                                                  utf8stringbuf_get_string( &((*this_).temp_filename) ),
     237              :                                                  io_export_stat
     238              :                                                );
     239              :     }
     240              : 
     241              :     /* recursion to children */
     242            0 :     if (( result == 0 )&&( max_recursion > 0 ))
     243              :     {
     244              :         u8_error_t db_err;
     245              :         data_small_set_t the_set;
     246            0 :         data_small_set_init( &the_set );
     247            0 :         db_err = data_database_reader_get_diagram_ids_by_parent_id ( (*this_).db_reader, diagram_row_id, &the_set );
     248            0 :         if ( db_err != U8_ERROR_NONE )
     249              :         {
     250            0 :             U8_LOG_ERROR("error reading database.");
     251            0 :             result = -1;
     252              :         }
     253              :         else
     254              :         {
     255            0 :             for ( uint32_t pos = 0; pos < data_small_set_get_count( &the_set ); pos ++ )
     256              :             {
     257              :                 data_id_t probe_id;
     258            0 :                 probe_id = data_small_set_get_id( &the_set, pos );
     259              : 
     260            0 :                 result |= io_exporter_private_export_image_files( this_, probe_id, max_recursion-1, export_type, target_folder, io_export_stat );
     261              : 
     262            0 :                 data_id_destroy( &probe_id );
     263              :             }
     264              :         }
     265            0 :         data_small_set_destroy( &the_set );
     266              :     }
     267              : 
     268            0 :     U8_TRACE_END_ERR( result );
     269            0 :     return result;
     270              : }
     271              : 
     272            0 : u8_error_t io_exporter_export_image_file( io_exporter_t *this_,
     273              :                                           data_id_t diagram_id,
     274              :                                           io_file_format_t export_type,
     275              :                                           const char *file_path,
     276              :                                           data_stat_t *io_export_stat )
     277              : {
     278            0 :     U8_TRACE_BEGIN();
     279            0 :     assert ( data_id_is_valid( &diagram_id ) );
     280            0 :     assert ( NULL != file_path );
     281            0 :     assert ( NULL != io_export_stat );
     282            0 :     U8_TRACE_INFO_STR("file_path:", file_path );
     283            0 :     u8_error_t result = U8_ERROR_NONE;
     284              : 
     285              :     /* create surface */
     286            0 :     if (( IO_FILE_FORMAT_SVG == export_type )
     287            0 :         || ( IO_FILE_FORMAT_PDF == export_type )
     288            0 :         || ( IO_FILE_FORMAT_PS == export_type )
     289            0 :         || ( IO_FILE_FORMAT_PNG == export_type ) )
     290              :     {
     291            0 :         image_format_writer_init( &((*this_).temp_image_format_exporter ),
     292              :                                   (*this_).db_reader,
     293              :                                   &((*this_).temp_input_data),
     294              :                                   &((*this_).temp_profile)
     295              :                                 );
     296            0 :         result |= image_format_writer_render_diagram_to_file( &((*this_).temp_image_format_exporter ),
     297              :                                                               diagram_id,
     298              :                                                               export_type,
     299              :                                                               file_path,
     300              :                                                               io_export_stat
     301              :                                                             );
     302            0 :         image_format_writer_destroy( &((*this_).temp_image_format_exporter ) );
     303              :     }
     304              :     else /* IO_FILE_FORMAT_TXT */
     305              :     {
     306              :         universal_file_output_stream_t text_output;
     307            0 :         universal_file_output_stream_init( &text_output );
     308            0 :         universal_output_stream_t *output = universal_file_output_stream_get_output_stream( &text_output );
     309              : 
     310              :         /* open file */
     311            0 :         result |= universal_file_output_stream_open( &text_output, file_path );
     312            0 :         if ( result == 0 )
     313              :         {
     314            0 :             u8_error_t write_err = U8_ERROR_NONE;
     315              : 
     316              :             /* temporarily use the temp_model_traversal */
     317              :             /* write file */
     318            0 :             document_element_writer_init( &((*this_).temp_format_writer ),
     319              :                                           (*this_).db_reader,
     320              :                                           IO_FILE_FORMAT_TXT,
     321              :                                           io_export_stat,
     322              :                                           output
     323              :                                         );
     324            0 :             io_export_diagram_traversal_init( &((*this_).temp_diagram_traversal),
     325              :                                               (*this_).db_reader,
     326              :                                               &((*this_).temp_input_data),
     327              :                                               io_export_stat,
     328              :                                               document_element_writer_get_element_writer( &((*this_).temp_format_writer) )
     329              :                                             );
     330            0 :             write_err |= document_element_writer_write_header( &((*this_).temp_format_writer), "DUMMY_TITLE" );
     331            0 :             write_err |= io_export_diagram_traversal_begin_and_walk_diagram ( &((*this_).temp_diagram_traversal), diagram_id, "NO_IMAGE_FILE" );
     332            0 :             write_err |= io_export_diagram_traversal_end_diagram ( &((*this_).temp_diagram_traversal), diagram_id );
     333            0 :             write_err |= document_element_writer_write_footer( &((*this_).temp_format_writer) );
     334            0 :             io_export_diagram_traversal_destroy( &((*this_).temp_diagram_traversal) );
     335            0 :             document_element_writer_destroy( &((*this_).temp_format_writer ) );
     336              : 
     337            0 :             if ( 0 != write_err )
     338              :             {
     339            0 :                 U8_LOG_ERROR("error writing txt.");
     340            0 :                 result = -1;
     341              :             }
     342              : 
     343              :             /* close file */
     344            0 :             result |= universal_file_output_stream_close( &text_output );
     345              :         }
     346              : 
     347            0 :         result |= universal_file_output_stream_destroy( &text_output );
     348              : 
     349            0 :         data_stat_inc_count ( io_export_stat, DATA_STAT_TABLE_DIAGRAM, DATA_STAT_SERIES_EXPORTED );
     350              :     }
     351              : 
     352            0 :     U8_TRACE_END_ERR( result );
     353            0 :     return result;
     354              : }
     355              : 
     356            0 : u8_error_t io_exporter_private_export_document_file( io_exporter_t *this_,
     357              :                                                      io_file_format_t export_type,
     358              :                                                      const char *target_folder,
     359              :                                                      const char *document_file_name,
     360              :                                                      data_stat_t *io_export_stat )
     361              : {
     362            0 :     U8_TRACE_BEGIN();
     363            0 :     assert ( NULL != target_folder );
     364            0 :     assert ( NULL != document_file_name );
     365            0 :     assert ( NULL != io_export_stat );
     366            0 :     U8_TRACE_INFO_STR("target_folder:", target_folder );
     367            0 :     U8_TRACE_INFO_STR("document_file_name:", document_file_name );
     368            0 :     u8_error_t export_err = U8_ERROR_NONE;
     369              : 
     370              :     /* open file */
     371            0 :     utf8stringbuf_copy_str( &((*this_).temp_filename), target_folder );
     372            0 :     utf8stringbuf_append_str( &((*this_).temp_filename), "/" );
     373            0 :     utf8stringbuf_append_str( &((*this_).temp_filename), document_file_name );
     374            0 :     switch ( export_type )
     375              :     {
     376            0 :         case IO_FILE_FORMAT_DOCBOOK:
     377              :         {
     378            0 :             utf8stringbuf_append_str( &((*this_).temp_filename), ".xml" );
     379              :         }
     380            0 :         break;
     381              : 
     382            0 :         case IO_FILE_FORMAT_HTML:
     383              :         {
     384            0 :             utf8stringbuf_append_str( &((*this_).temp_filename), ".html" );
     385              :         }
     386            0 :         break;
     387              : 
     388            0 :         case IO_FILE_FORMAT_CSS:
     389              :         {
     390            0 :             utf8stringbuf_append_str( &((*this_).temp_filename), ".css" );
     391              :         }
     392            0 :         break;
     393              : 
     394            0 :         case IO_FILE_FORMAT_JSON:
     395              :         {
     396            0 :             utf8stringbuf_append_str( &((*this_).temp_filename), ".json" );
     397              :         }
     398            0 :         break;
     399              : 
     400            0 :         case IO_FILE_FORMAT_SCHEMA:
     401              :         {
     402            0 :             utf8stringbuf_append_str( &((*this_).temp_filename), ".schema" );
     403              :         }
     404            0 :         break;
     405              : 
     406            0 :         case IO_FILE_FORMAT_XMI2:
     407              :         {
     408            0 :             utf8stringbuf_append_str( &((*this_).temp_filename), ".xmi" );
     409              :         }
     410            0 :         break;
     411              : 
     412            0 :         default:
     413              :         {
     414            0 :             utf8stringbuf_append_str( &((*this_).temp_filename), ".unknown_format" );
     415            0 :             U8_LOG_ERROR("error: unknown_format.");
     416              :         }
     417            0 :         break;
     418              :     }
     419            0 :     U8_LOG_EVENT_STR( "exporting diagrams to document file:", utf8stringbuf_get_string( &((*this_).temp_filename) ) );
     420              : 
     421            0 :     export_err |= io_exporter_export_document_file( this_,
     422              :                                                     export_type,
     423              :                                                     document_file_name,
     424            0 :                                                     utf8stringbuf_get_string( &((*this_).temp_filename) ),
     425              :                                                     io_export_stat
     426              :                                                   );
     427              : 
     428            0 :     U8_TRACE_END_ERR( export_err );
     429            0 :     return export_err;
     430              : }
     431              : 
     432            2 : u8_error_t io_exporter_export_document_file( io_exporter_t *this_,
     433              :                                              io_file_format_t export_type,
     434              :                                              const char *document_title,
     435              :                                              const char *file_path,
     436              :                                              data_stat_t *io_export_stat )
     437              : {
     438            2 :     U8_TRACE_BEGIN();
     439            2 :     assert ( NULL != document_title );
     440            2 :     assert ( NULL != file_path );
     441            2 :     assert ( NULL != io_export_stat );
     442            2 :     U8_TRACE_INFO_STR("file_path:", file_path );
     443            2 :     u8_error_t export_err = U8_ERROR_NONE;
     444              :     universal_file_output_stream_t file_output;
     445            2 :     universal_file_output_stream_init( &file_output );
     446            2 :     universal_output_stream_t *output = universal_file_output_stream_get_output_stream( &file_output );
     447              : 
     448            2 :     export_err |= universal_file_output_stream_open( &file_output, file_path );
     449            2 :     if ( export_err == 0 )
     450              :     {
     451              :         /* write file */
     452            2 :         if ( IO_FILE_FORMAT_CSS == export_type )
     453              :         {
     454              :             document_css_writer_t css_writer;
     455            0 :             document_css_writer_init( &css_writer, output );
     456            0 :             export_err |= document_css_writer_write_stylesheet( &css_writer );
     457            0 :             document_css_writer_destroy( &css_writer );
     458              :         }
     459            2 :         else if ( IO_FILE_FORMAT_SCHEMA == export_type )
     460              :         {
     461              :             json_schema_writer_t schema_writer;
     462            0 :             json_schema_writer_init( &schema_writer, output );
     463            0 :             export_err |= json_schema_writer_write_schema( &schema_writer );
     464            0 :             json_schema_writer_destroy( &schema_writer );
     465              :         }
     466            2 :         else if ( IO_FILE_FORMAT_XMI2 == export_type )
     467              :         {
     468            0 :             xmi_element_writer_init( &((*this_).temp_xmi_writer ), io_export_stat, output );
     469              :             /* init the model_traversal */
     470            0 :             io_export_model_traversal_init( &((*this_).temp_model_traversal),
     471              :                                             (*this_).db_reader,
     472              :                                             &((*this_).temp_input_data),
     473              :                                             io_export_stat,
     474              :                                             xmi_element_writer_get_element_writer( &((*this_).temp_xmi_writer) )
     475              :                                           );
     476              :             /* write the document */
     477            0 :             export_err |= xmi_element_writer_write_header( &((*this_).temp_xmi_writer), document_title );
     478            0 :             export_err |= xmi_element_writer_start_main( &((*this_).temp_xmi_writer), document_title );
     479            0 :             xmi_element_writer_set_mode( &((*this_).temp_xmi_writer ), XMI_WRITER_PASS_BASE );
     480            0 :             export_err |= io_export_model_traversal_walk_model_nodes( &((*this_).temp_model_traversal) );
     481            0 :             export_err |= xmi_element_writer_end_main( &((*this_).temp_xmi_writer) );
     482            0 :             xmi_element_writer_set_mode( &((*this_).temp_xmi_writer ), XMI_WRITER_PASS_PROFILE );
     483            0 :             export_err |= io_export_model_traversal_walk_model_nodes( &((*this_).temp_model_traversal) );
     484            0 :             export_err |= xmi_element_writer_write_footer( &((*this_).temp_xmi_writer) );
     485              : 
     486            0 :             io_export_model_traversal_destroy( &((*this_).temp_model_traversal) );
     487            0 :             xmi_element_writer_destroy( &((*this_).temp_xmi_writer ) );
     488              :         }
     489            2 :         else if ( IO_FILE_FORMAT_JSON == export_type )
     490              :         {
     491            2 :             json_element_writer_init( &((*this_).temp_json_writer ), io_export_stat, output );
     492            2 :             export_err |= json_element_writer_write_header( &((*this_).temp_json_writer), document_title );
     493              : 
     494              :             /* init the diagram_traversal */
     495              :             {
     496            2 :                 io_export_diagram_traversal_init( &((*this_).temp_diagram_traversal),
     497              :                                                   (*this_).db_reader,
     498              :                                                   &((*this_).temp_input_data),
     499              :                                                   io_export_stat,
     500              :                                                   json_element_writer_get_element_writer( &((*this_).temp_json_writer) )
     501              :                                                 );
     502              :                 /* write the document */
     503            2 :                 json_element_writer_set_mode( &((*this_).temp_json_writer ), JSON_WRITER_PASS_VIEWS );
     504            2 :                 export_err |= json_element_writer_start_main( &((*this_).temp_json_writer), document_title );
     505            2 :                 export_err |= io_exporter_private_export_document_part( this_, DATA_ID_VOID, IO_EXPORTER_MAX_DIAGRAM_TREE_DEPTH, io_export_stat );
     506            2 :                 export_err |= json_element_writer_end_main( &((*this_).temp_json_writer) );
     507              : 
     508            2 :                 io_export_diagram_traversal_destroy( &((*this_).temp_diagram_traversal) );
     509              :             }
     510              : 
     511              :             /* init the model_traversal */
     512              :             {
     513            2 :                 io_export_flat_traversal_init( &((*this_).temp_flat_traversal),
     514              :                                                (*this_).db_reader,
     515              :                                                io_export_stat,
     516              :                                                json_element_writer_get_element_writer( &((*this_).temp_json_writer) )
     517              :                                              );
     518              :                 /* write the document */
     519            2 :                 json_element_writer_set_mode( &((*this_).temp_json_writer ), JSON_WRITER_PASS_NODES );
     520            2 :                 export_err |= json_element_writer_start_main( &((*this_).temp_json_writer), document_title );
     521            2 :                 export_err |= io_export_flat_traversal_iterate_classifiers( &((*this_).temp_flat_traversal), false );
     522            2 :                 export_err |= json_element_writer_end_main( &((*this_).temp_json_writer) );
     523              : 
     524            2 :                 json_element_writer_set_mode( &((*this_).temp_json_writer ), JSON_WRITER_PASS_EDGES );
     525            2 :                 export_err |= json_element_writer_start_main( &((*this_).temp_json_writer), document_title );
     526            2 :                 export_err |= io_export_flat_traversal_iterate_classifiers( &((*this_).temp_flat_traversal), false );
     527            2 :                 export_err |= json_element_writer_end_main( &((*this_).temp_json_writer) );
     528              : 
     529            2 :                 io_export_flat_traversal_destroy( &((*this_).temp_flat_traversal) );
     530              :             }
     531              : 
     532            2 :             export_err |= json_element_writer_write_footer( &((*this_).temp_json_writer) );
     533            2 :             json_element_writer_destroy( &((*this_).temp_json_writer ) );
     534              :         }
     535              :         else
     536              :         {
     537            0 :             document_element_writer_init( &((*this_).temp_format_writer ),
     538              :                                           (*this_).db_reader,
     539              :                                           export_type,
     540              :                                           io_export_stat,
     541              :                                           output
     542              :                                         );
     543              :             /* init the diagram_traversal */
     544            0 :             io_export_diagram_traversal_init( &((*this_).temp_diagram_traversal),
     545              :                                               (*this_).db_reader,
     546              :                                               &((*this_).temp_input_data),
     547              :                                               io_export_stat,
     548              :                                               document_element_writer_get_element_writer( &((*this_).temp_format_writer) )
     549              :                                             );
     550              :             /* write the document */
     551            0 :             export_err |= document_element_writer_write_header( &((*this_).temp_format_writer), document_title );
     552            0 :             export_err |= document_element_writer_start_toc( &((*this_).temp_format_writer) );
     553            0 :             export_err |= io_exporter_private_export_table_of_contents( this_,
     554            0 :                                                                         DATA_ID_VOID,
     555              :                                                                         IO_EXPORTER_MAX_DIAGRAM_TREE_DEPTH,
     556              :                                                                         &((*this_).temp_format_writer)
     557              :                                                                       );
     558            0 :             export_err |= document_element_writer_end_toc( &((*this_).temp_format_writer) );
     559            0 :             export_err |= document_element_writer_start_main( &((*this_).temp_format_writer), document_title );
     560            0 :             export_err |= io_exporter_private_export_document_part( this_, DATA_ID_VOID,
     561              :                                                                     IO_EXPORTER_MAX_DIAGRAM_TREE_DEPTH,
     562              :                                                                     io_export_stat
     563              :                                                                   );
     564            0 :             export_err |= document_element_writer_end_main( &((*this_).temp_format_writer) );
     565            0 :             export_err |= document_element_writer_write_footer( &((*this_).temp_format_writer) );
     566              : 
     567            0 :             io_export_diagram_traversal_destroy( &((*this_).temp_diagram_traversal) );
     568            0 :             document_element_writer_destroy( &((*this_).temp_format_writer ) );
     569              :         }
     570              : 
     571              :         /* close file */
     572            2 :         export_err |= universal_file_output_stream_close( &file_output );
     573              :     }
     574              : 
     575            2 :     export_err |= universal_file_output_stream_destroy( &file_output );
     576              : 
     577            2 :     U8_TRACE_END_ERR( export_err );
     578            2 :     return export_err;
     579              : }
     580              : 
     581            2 : u8_error_t io_exporter_private_export_document_part( io_exporter_t *this_,
     582              :                                                      data_id_t diagram_id,
     583              :                                                      uint32_t max_recursion,
     584              :                                                      data_stat_t *io_export_stat )
     585              : {
     586            2 :     U8_TRACE_BEGIN();
     587            2 :     assert ( NULL != io_export_stat );
     588            2 :     const data_row_t diagram_row_id = data_id_get_row_id( &diagram_id );
     589            2 :     u8_error_t export_err = U8_ERROR_NONE;
     590              : 
     591              :     /* write part for current diagram */
     592            2 :     if ( DATA_ROW_VOID != diagram_row_id )
     593              :     {
     594            0 :         assert( data_id_get_table( &diagram_id ) == DATA_TABLE_DIAGRAM );
     595              : 
     596              :         /* determine filename */
     597            0 :         export_err |= io_exporter_private_get_filename_for_diagram( this_, diagram_id, (*this_).temp_filename );
     598              : 
     599              : 
     600              :         /* write doc part */
     601            0 :         export_err |= io_export_diagram_traversal_begin_and_walk_diagram( &((*this_).temp_diagram_traversal),
     602              :                                                                           diagram_id,
     603            0 :                                                                           utf8stringbuf_get_string( &((*this_).temp_filename) )
     604              :                                                                         );
     605              :     }
     606              : 
     607              :     /* recursion to children */
     608            2 :     if (( export_err == 0 )&&( max_recursion > 0 ))
     609              :     {
     610              :         u8_error_t db_err;
     611              :         data_small_set_t the_set;
     612            2 :         data_small_set_init( &the_set );
     613            2 :         db_err = data_database_reader_get_diagram_ids_by_parent_id ( (*this_).db_reader, diagram_row_id, &the_set );
     614            2 :         if ( db_err != U8_ERROR_NONE )
     615              :         {
     616            0 :             U8_LOG_ERROR("error reading database.");
     617            0 :             export_err |= -1;
     618              :         }
     619              :         else
     620              :         {
     621            2 :             const uint32_t child_count = data_small_set_get_count( &the_set );
     622            2 :             for ( uint32_t pos = 0; pos < child_count; pos ++ )
     623              :             {
     624            0 :                 data_id_t probe_id = data_small_set_get_id( &the_set, pos );
     625              : 
     626            0 :                 export_err |= io_exporter_private_export_document_part( this_, probe_id, max_recursion-1, io_export_stat );
     627              : 
     628            0 :                 data_id_destroy( &probe_id );
     629              :             }
     630              :         }
     631            2 :         data_small_set_destroy( &the_set );
     632              :     }
     633              : 
     634              :     /* end diagram section */
     635            2 :     if ( DATA_ROW_VOID != diagram_row_id )
     636              :     {
     637              :         /* write doc part */
     638            0 :         export_err |= io_export_diagram_traversal_end_diagram( &((*this_).temp_diagram_traversal), diagram_id );
     639              :     }
     640              : 
     641            2 :     U8_TRACE_END_ERR( export_err );
     642            2 :     return export_err;
     643              : }
     644              : 
     645            0 : u8_error_t io_exporter_private_export_table_of_contents( io_exporter_t *this_,
     646              :                                                          data_id_t diagram_id,
     647              :                                                          uint32_t max_recursion,
     648              :                                                          document_element_writer_t *format_writer )
     649              : {
     650            0 :     U8_TRACE_BEGIN();
     651            0 :     assert ( NULL != format_writer );
     652            0 :     const data_row_t diagram_row_id = data_id_get_row_id( &diagram_id );
     653            0 :     u8_error_t export_err = U8_ERROR_NONE;
     654              : 
     655              :     /* write entry for current diagram */
     656            0 :     if ( DATA_ROW_VOID != diagram_row_id )
     657              :     {
     658            0 :         assert( data_id_get_table( &diagram_id ) == DATA_TABLE_DIAGRAM );
     659              : 
     660            0 :         export_err |= document_element_writer_start_toc_entry( format_writer );
     661              : 
     662              :         /* load data to be drawn */
     663              :         u8_error_t db_err;
     664            0 :         db_err = data_database_reader_get_diagram_by_id ( (*this_).db_reader, diagram_row_id, &((*this_).temp_diagram) );
     665            0 :         if ( db_err != U8_ERROR_NONE )
     666              :         {
     667            0 :             U8_LOG_ERROR("error reading database.");
     668            0 :             export_err |= -1;
     669              :         }
     670              :         else
     671              :         {
     672            0 :             export_err |= document_element_writer_write_toc_entry ( format_writer, &((*this_).temp_diagram) );
     673            0 :             data_diagram_destroy( &((*this_).temp_diagram) );
     674              :         }
     675              :     }
     676              : 
     677              :     /* recursion to children */
     678            0 :     if (( export_err == 0 )&&( max_recursion > 0 ))
     679              :     {
     680              :         u8_error_t db_err;
     681              :         data_small_set_t the_set;
     682            0 :         data_small_set_init( &the_set );
     683            0 :         db_err = data_database_reader_get_diagram_ids_by_parent_id ( (*this_).db_reader, diagram_row_id, &the_set );
     684            0 :         if ( db_err != U8_ERROR_NONE )
     685              :         {
     686            0 :             U8_LOG_ERROR("error reading database.");
     687            0 :             export_err |= -1;
     688              :         }
     689              :         else
     690              :         {
     691            0 :             const uint32_t child_count = data_small_set_get_count( &the_set );
     692            0 :             if ( child_count != 0 )
     693              :             {
     694            0 :                 export_err |= document_element_writer_start_toc_sublist( format_writer );
     695            0 :                 for ( uint32_t pos = 0; pos < child_count; pos ++ )
     696              :                 {
     697            0 :                     data_id_t probe_id = data_small_set_get_id( &the_set, pos );
     698              : 
     699            0 :                     export_err |= io_exporter_private_export_table_of_contents( this_, probe_id, max_recursion-1, format_writer );
     700              : 
     701            0 :                     data_id_destroy( &probe_id );
     702              :                 }
     703            0 :                 export_err |= document_element_writer_end_toc_sublist ( format_writer );
     704              :             }
     705              :         }
     706            0 :         data_small_set_destroy( &the_set );
     707              :     }
     708              : 
     709              :     /* end toc entry */
     710            0 :     if ( DATA_ROW_VOID != diagram_row_id )
     711              :     {
     712            0 :         export_err |= document_element_writer_end_toc_entry( format_writer );
     713              :     }
     714              : 
     715            0 :     U8_TRACE_END_ERR( export_err );
     716            0 :     return export_err;
     717              : }
     718              : 
     719            0 : u8_error_t io_exporter_private_get_filename_for_diagram( io_exporter_t *this_,
     720              :                                                          data_id_t diagram_id,
     721              :                                                          utf8stringbuf_t filename )
     722              : {
     723            0 :     U8_TRACE_BEGIN();
     724            0 :     assert( data_id_get_table( &diagram_id ) == DATA_TABLE_DIAGRAM );
     725            0 :     u8_error_t result = U8_ERROR_NONE;
     726            0 :     utf8stringbuf_clear( &filename );
     727              : 
     728              :     u8_error_t db_err;
     729            0 :     db_err = data_database_reader_get_diagram_by_id ( (*this_).db_reader, data_id_get_row_id( &diagram_id ), &((*this_).temp_diagram) );
     730            0 :     if ( db_err != U8_ERROR_NONE )
     731              :     {
     732            0 :         U8_LOG_ERROR("error reading database.");
     733            0 :         result |= -1;
     734              :     }
     735              :     else
     736              :     {
     737              :         const char *diag_name;
     738            0 :         diag_name = data_diagram_get_name_const( &((*this_).temp_diagram) );
     739              : 
     740              :         /* determine filename */
     741            0 :         data_id_to_utf8stringbuf( &diagram_id, filename );
     742            0 :         utf8stringbuf_append_str( &filename, "_" );
     743            0 :         io_exporter_private_append_valid_chars_to_filename( this_, diag_name, filename );
     744            0 :         data_diagram_destroy( &((*this_).temp_diagram) );
     745              :     }
     746              : 
     747            0 :     U8_TRACE_END_ERR( result );
     748            0 :     return result;
     749              : }
     750              : 
     751            0 : void io_exporter_private_append_valid_chars_to_filename( io_exporter_t *this_,
     752              :                                                          const char* name,
     753              :                                                          utf8stringbuf_t filename )
     754              : {
     755            0 :     U8_TRACE_BEGIN();
     756            0 :     assert( NULL != name );
     757            0 :     U8_TRACE_INFO_STR( "name:", name );
     758              : 
     759            0 :     bool finished = false;
     760              :     static const int MAX_APPEND_CHARS = 64;
     761            0 :     for ( int pos = 0; ( pos < MAX_APPEND_CHARS ) && ( ! finished ); pos ++ )
     762              :     {
     763            0 :         char probe = name[pos];
     764            0 :         if ( probe == '\0' )
     765              :         {
     766            0 :             finished = true;
     767              :         }
     768            0 :         else if (( 'A' <= probe ) && ( probe <= 'Z' ))
     769              :         {
     770            0 :             utf8stringbuf_append_char( &filename, probe );
     771              :         }
     772            0 :         else if (( 'a' <= probe ) && ( probe <= 'z' ))
     773              :         {
     774            0 :             utf8stringbuf_append_char( &filename, probe );
     775              :         }
     776            0 :         else if (( '0' <= probe ) && ( probe <= '9' ))
     777              :         {
     778            0 :             utf8stringbuf_append_char( &filename, probe );
     779              :         }
     780            0 :         else if ( '-' == probe )
     781              :         {
     782            0 :             utf8stringbuf_append_char( &filename, probe );
     783              :         }
     784            0 :         else if ( '_' == probe )
     785              :         {
     786            0 :             utf8stringbuf_append_char( &filename, probe );
     787              :         }
     788            0 :         else if ( ' ' == probe )
     789              :         {
     790            0 :             utf8stringbuf_append_char( &filename, '_' );
     791              :         }
     792              :     }
     793              : 
     794            0 :     U8_TRACE_END();
     795            0 : }
     796              : 
     797              : 
     798              : /*
     799              : Copyright 2016-2025 Andreas Warnke
     800              : 
     801              : Licensed under the Apache License, Version 2.0 (the "License");
     802              : you may not use this file except in compliance with the License.
     803              : You may obtain a copy of the License at
     804              : 
     805              :     http://www.apache.org/licenses/LICENSE-2.0
     806              : 
     807              : Unless required by applicable law or agreed to in writing, software
     808              : distributed under the License is distributed on an "AS IS" BASIS,
     809              : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     810              : See the License for the specific language governing permissions and
     811              : limitations under the License.
     812              : */
        

Generated by: LCOV version 2.0-1