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