LCOV - code coverage report
Current view: top level - io/source/json - json_element_writer.c (source / functions) Hit Total Coverage
Test: crystal-facet-uml_v1.65.6_covts Lines: 96 432 22.2 %
Date: 2025-09-25 21:07:53 Functions: 8 26 30.8 %

          Line data    Source code
       1             : /* File: json_element_writer.inl; Copyright and License: see below */
       2             : 
       3             : #include <json/json_element_writer.h>
       4             : #include "json/json_constants.h"
       5             : #include "meta/meta_info.h"
       6             : #include "meta/meta_version.h"
       7             : #include "u8/u8_trace.h"
       8             : #include "u8/u8_log.h"
       9             : #include <assert.h>
      10             : 
      11             : #define io_element_writer_impl_t json_element_writer_t
      12             : /*!
      13             :  *  \brief A struct of function pointers which is the interface of an io_element_writer
      14             :  *
      15             :  *  To avoid typecasts, this struct provides function pointers with the exact right signatures
      16             :  *  provided via io_element_writer_impl_t
      17             :  */
      18             : struct json_element_writer_io_element_writer_if_struct {
      19             : #include "io_element_writer_if.inl"
      20             : };
      21             : #undef io_element_writer_impl_t
      22             : 
      23             : /* the vmt implementing the interface */
      24             : static const struct json_element_writer_io_element_writer_if_struct json_element_writer_private_io_element_writer_if
      25             :     = {
      26             :         .write_header = &json_element_writer_write_header,
      27             :         .start_main = &json_element_writer_start_main,
      28             :         .can_classifier_nest_classifier = &json_element_writer_can_classifier_nest_classifier,
      29             :         .can_classifier_nest_relationship = &json_element_writer_can_classifier_nest_relationship,
      30             :         .start_classifier = &json_element_writer_start_classifier,
      31             :         .assemble_classifier = &json_element_writer_assemble_classifier,
      32             :         .end_classifier = &json_element_writer_end_classifier,
      33             :         .start_feature = &json_element_writer_start_feature,
      34             :         .assemble_feature = &json_element_writer_assemble_feature,
      35             :         .end_feature = &json_element_writer_end_feature,
      36             :         .start_relationship = &json_element_writer_start_relationship,
      37             :         .assemble_relationship = &json_element_writer_assemble_relationship,
      38             :         .end_relationship = &json_element_writer_end_relationship,
      39             :         .start_diagram = &json_element_writer_start_diagram,
      40             :         .assemble_diagram = &json_element_writer_assemble_diagram,
      41             :         .end_diagram = &json_element_writer_end_diagram_fake,
      42             :         .start_diagramelement = &json_element_writer_start_diagramelement,
      43             :         .assemble_diagramelement = &json_element_writer_assemble_diagramelement,
      44             :         .end_diagramelement = &json_element_writer_end_diagramelement,
      45             :         .end_main = &json_element_writer_end_main,
      46             :         .write_footer = &json_element_writer_write_footer
      47             :     };
      48             : 
      49           2 : void json_element_writer_init( json_element_writer_t *this_,
      50             :                                data_stat_t *io_export_stat,
      51             :                                universal_output_stream_t *output)
      52             : {
      53           2 :     U8_TRACE_BEGIN();
      54           2 :     assert( io_export_stat != NULL );
      55           2 :     assert( output != NULL );
      56             : 
      57           2 :     io_element_writer_private_init( &((*this_).element_writer),
      58             :                                     (io_element_writer_if_t*) &json_element_writer_private_io_element_writer_if,
      59             :                                     this_
      60             :                                   );
      61             : 
      62           2 :     json_writer_init( &((*this_).json_writer), output );
      63             : 
      64           2 :     json_type_name_map_init( &((*this_).type_map) );
      65             : 
      66           2 :     (*this_).in_outer_array = false;
      67           2 :     (*this_).is_outer_first = false;
      68           2 :     (*this_).in_inner_array = false;
      69           2 :     (*this_).is_inner_first = false;
      70             : 
      71           2 :     (*this_).mode = JSON_WRITER_PASS_NODES;
      72           2 :     (*this_).export_stat = io_export_stat;
      73             : 
      74           2 :     U8_TRACE_END();
      75           2 : }
      76             : 
      77           2 : void json_element_writer_destroy( json_element_writer_t *this_ )
      78             : {
      79           2 :     U8_TRACE_BEGIN();
      80             : 
      81           2 :     json_type_name_map_destroy( &((*this_).type_map) );
      82             : 
      83           2 :     json_writer_destroy( &((*this_).json_writer) );
      84             : 
      85           2 :     io_element_writer_private_destroy( &((*this_).element_writer) );
      86           2 :     (*this_).export_stat = NULL;
      87             : 
      88           2 :     U8_TRACE_END();
      89           2 : }
      90             : 
      91           4 : io_element_writer_t * json_element_writer_get_element_writer( json_element_writer_t *this_ )
      92             : {
      93           4 :     U8_TRACE_BEGIN();
      94             : 
      95           4 :     io_element_writer_t * base = &((*this_).element_writer);
      96             : 
      97           4 :     U8_TRACE_END();
      98           4 :     return base;
      99             : }
     100             : 
     101           6 : void json_element_writer_set_mode( json_element_writer_t *this_, json_writer_pass_t mode )
     102             : {
     103           6 :     U8_TRACE_BEGIN();
     104             : 
     105           6 :     (*this_).mode = mode;
     106             : 
     107           6 :     U8_TRACE_END();
     108           6 : }
     109             : 
     110           2 : u8_error_t json_element_writer_write_header( json_element_writer_t *this_, const char *document_title )
     111             : {
     112           2 :     U8_TRACE_BEGIN();
     113           2 :     assert( document_title != NULL );
     114           2 :     assert( (*this_).in_outer_array == false );
     115           2 :     assert( (*this_).in_inner_array == false );
     116           2 :     u8_error_t out_err = U8_ERROR_NONE;
     117             : 
     118           2 :     out_err |= json_writer_write_plain( &((*this_).json_writer),
     119             :                                         JSON_CONSTANTS_BEGIN_OBJECT_NL
     120             :                                         JSON_CONSTANTS_TAB
     121             :                                         JSON_CONSTANTS_QUOTE
     122             :                                         JSON_CONSTANTS_KEY_HEAD
     123             :                                         JSON_CONSTANTS_QUOTE
     124             :                                         JSON_CONSTANTS_DEF
     125             :                                         JSON_CONSTANTS_BEGIN_OBJECT_NL
     126             :                                       );
     127             : 
     128           2 :     out_err |= json_writer_write_member_string( &((*this_).json_writer), 2, "encoding", "utf-8", true );
     129             :     /* hexadecimal escapes are complex: */
     130             :     /* a single 6-byte sequence can only encode a codepoint of the the basic multilingual plane, */
     131             :     /* two of these 6-byte sequences may form a surrogate pair */
     132           2 :     out_err |= json_writer_write_member_string( &((*this_).json_writer), 2, "structure_format", "rfc-8259 w/o hexadecimal escapes", true );
     133           2 :     out_err |= json_writer_write_member_string( &((*this_).json_writer), 2, "format", "cfu-json", true );
     134             :     /* version 1.1 stores stereotypes for diagrams and relationships */
     135           2 :     out_err |= json_writer_write_member_int( &((*this_).json_writer), 2, "major_version", 1, true );
     136           2 :     out_err |= json_writer_write_member_int( &((*this_).json_writer), 2, "minor_version", 2, true );
     137           2 :     out_err |= json_writer_write_member_string( &((*this_).json_writer), 2, "generator_name", META_INFO_PROGRAM_ID_STR, true );
     138           2 :     out_err |= json_writer_write_member_string( &((*this_).json_writer), 2, "generator_version", META_VERSION_STR, false );
     139             : 
     140           2 :     out_err |= json_writer_write_plain( &((*this_).json_writer),
     141             :                                         JSON_CONSTANTS_TAB
     142             :                                         JSON_CONSTANTS_END_OBJECT
     143             :                                         JSON_CONSTANTS_NL
     144             :                                       );
     145             : 
     146             : 
     147           2 :     if ( out_err != 0 )
     148             :     {
     149           0 :         U8_LOG_ERROR( "output buffer exceeded." );
     150             :     }
     151             : 
     152           2 :     U8_TRACE_END_ERR(out_err);
     153           2 :     return out_err;
     154             : }
     155             : 
     156           6 : u8_error_t json_element_writer_start_main( json_element_writer_t *this_, const char *document_title )
     157             : {
     158           6 :     U8_TRACE_BEGIN();
     159           6 :     assert( document_title != NULL );
     160           6 :     assert( (*this_).in_outer_array == false );
     161           6 :     assert( (*this_).in_inner_array == false );
     162           6 :     u8_error_t out_err = U8_ERROR_NONE;
     163             : 
     164           6 :     out_err |= json_writer_write_plain( &((*this_).json_writer),
     165             :                                         JSON_CONSTANTS_TAB
     166             :                                         JSON_CONSTANTS_NEXT_NL
     167             :                                         JSON_CONSTANTS_TAB
     168             :                                         JSON_CONSTANTS_QUOTE
     169             :                                       );
     170             : 
     171             : 
     172           6 :     switch( (*this_).mode )
     173             :     {
     174           2 :         case JSON_WRITER_PASS_VIEWS:
     175             :         {
     176           2 :             out_err |= json_writer_write_plain( &((*this_).json_writer), JSON_CONSTANTS_KEY_VIEWS );
     177             :         }
     178           2 :         break;
     179             : 
     180           2 :         case JSON_WRITER_PASS_NODES:
     181             :         {
     182           2 :             out_err |= json_writer_write_plain( &((*this_).json_writer), JSON_CONSTANTS_KEY_NODES );
     183             :         }
     184           2 :         break;
     185             : 
     186           2 :         case JSON_WRITER_PASS_EDGES:
     187             :         {
     188           2 :             out_err |= json_writer_write_plain( &((*this_).json_writer), JSON_CONSTANTS_KEY_EDGES );
     189             :         }
     190           2 :         break;
     191             : 
     192           0 :         default:
     193             :         {
     194           0 :             assert( false );
     195             :         }
     196             :         break;
     197             :     }
     198             : 
     199           6 :     out_err |= json_writer_write_plain( &((*this_).json_writer),
     200             :                                         JSON_CONSTANTS_QUOTE
     201             :                                         JSON_CONSTANTS_DEF_NL
     202             :                                         JSON_CONSTANTS_TAB
     203             :                                         JSON_CONSTANTS_BEGIN_ARRAY
     204             :                                       );
     205             : 
     206           6 :     if ( out_err != 0 )
     207             :     {
     208           0 :         U8_LOG_ERROR( "output buffer exceeded." );
     209             :     }
     210             : 
     211           6 :     (*this_).in_outer_array = true;
     212           6 :     (*this_).is_outer_first = true;
     213             : 
     214           6 :     U8_TRACE_END_ERR(out_err);
     215           6 :     return out_err;
     216             : }
     217             : 
     218           0 : bool json_element_writer_can_classifier_nest_classifier( json_element_writer_t *this_,
     219             :                                                          data_classifier_type_t host_type,
     220             :                                                          data_classifier_type_t child_type )
     221             : {
     222           0 :     U8_TRACE_BEGIN();
     223           0 :     const bool can_nest = false;
     224           0 :     U8_TRACE_END();
     225           0 :     return can_nest;
     226             : }
     227             : 
     228           0 : bool json_element_writer_can_classifier_nest_relationship( json_element_writer_t *this_,
     229             :                                                            data_classifier_type_t host_type,
     230             :                                                            data_relationship_type_t child_type )
     231             : {
     232           0 :     U8_TRACE_BEGIN();
     233           0 :     const bool can_nest = true;
     234           0 :     U8_TRACE_END();
     235           0 :     return can_nest;
     236             : }
     237             : 
     238           0 : u8_error_t json_element_writer_start_classifier( json_element_writer_t *this_,
     239             :                                                  data_classifier_type_t host_type,
     240             :                                                  const data_classifier_t *classifier_ptr )
     241             : {
     242           0 :     U8_TRACE_BEGIN();
     243           0 :     assert( classifier_ptr != NULL );
     244           0 :     u8_error_t out_err = U8_ERROR_NONE;
     245             : 
     246           0 :     if ( (*this_).mode == JSON_WRITER_PASS_NODES )
     247             :     {
     248             :         /* separate objects in array if not first */
     249           0 :         if ( (*this_).is_outer_first )
     250             :         {
     251           0 :             (*this_).is_outer_first = false;
     252           0 :             out_err |= json_writer_write_plain( &((*this_).json_writer), JSON_CONSTANTS_NL );
     253             :         }
     254             :         else
     255             :         {
     256           0 :             out_err |= json_writer_write_plain( &((*this_).json_writer), JSON_CONSTANTS_NEXT_NL );
     257             :         }
     258             : 
     259             :         /* begin classifier */
     260           0 :         out_err |= json_writer_write_plain( &((*this_).json_writer),
     261             :                                             JSON_CONSTANTS_TAB
     262             :                                             JSON_CONSTANTS_TAB
     263             :                                             JSON_CONSTANTS_BEGIN_OBJECT
     264             :                                             JSON_CONSTANTS_NL
     265             :                                             JSON_CONSTANTS_TAB
     266             :                                             JSON_CONSTANTS_TAB
     267             :                                             JSON_CONSTANTS_TAB
     268             :                                             JSON_CONSTANTS_QUOTE
     269             :                                             JSON_CONSTANTS_KEY_CLASSIFIER
     270             :                                             JSON_CONSTANTS_QUOTE
     271             :                                             JSON_CONSTANTS_DEF
     272             :                                             JSON_CONSTANTS_BEGIN_OBJECT_NL );
     273             :     }
     274             : 
     275           0 :     U8_TRACE_END_ERR(out_err);
     276           0 :     return out_err;
     277             : }
     278             : 
     279           0 : u8_error_t json_element_writer_assemble_classifier( json_element_writer_t *this_,
     280             :                                                     data_classifier_type_t host_type,
     281             :                                                     const data_classifier_t *classifier_ptr )
     282             : {
     283           0 :     U8_TRACE_BEGIN();
     284           0 :     assert( classifier_ptr != NULL );
     285           0 :     u8_error_t out_err = U8_ERROR_NONE;
     286             : 
     287           0 :     if ( (*this_).mode == JSON_WRITER_PASS_NODES )
     288             :     {
     289           0 :         assert( (*this_).in_outer_array == true );
     290           0 :         assert( (*this_).in_inner_array == false );
     291             : 
     292             :         /* id */
     293           0 :         out_err |= json_writer_write_member_int( &((*this_).json_writer),
     294             :                                                  4,
     295             :                                                  JSON_CONSTANTS_KEY_CLASSIFIER_ID,
     296             :                                                  data_classifier_get_row_id( classifier_ptr ),
     297             :                                                  true
     298             :                                                );
     299             : 
     300             :         /* type */
     301             :         const char *const type_name
     302           0 :             = json_type_name_map_get_classifier_type( &((*this_).type_map),
     303             :                                                       data_classifier_get_main_type( classifier_ptr )
     304             :                                                     );
     305           0 :         out_err |= json_writer_write_member_enum( &((*this_).json_writer),
     306             :                                                   4,
     307             :                                                   JSON_CONSTANTS_KEY_CLASSIFIER_MAIN_TYPE_NAME,
     308             :                                                   type_name,
     309             :                                                   JSON_CONSTANTS_KEY_CLASSIFIER_MAIN_TYPE,
     310           0 :                                                   data_classifier_get_main_type( classifier_ptr ),
     311             :                                                   true
     312             :                                                 );
     313             : 
     314             :         /* stereotype */
     315           0 :         if ( data_classifier_has_stereotype( classifier_ptr ) )
     316             :         {
     317           0 :             out_err |= json_writer_write_member_string( &((*this_).json_writer),
     318             :                                                         4,
     319             :                                                         JSON_CONSTANTS_KEY_CLASSIFIER_STEREOTYPE,
     320           0 :                                                         data_classifier_get_stereotype_const( classifier_ptr ),
     321             :                                                         true
     322             :                                                       );
     323             :         }
     324             : 
     325             :         /* name */
     326           0 :         out_err |= json_writer_write_member_string( &((*this_).json_writer),
     327             :                                                     4,
     328             :                                                     JSON_CONSTANTS_KEY_CLASSIFIER_NAME,
     329           0 :                                                     data_classifier_get_name_const( classifier_ptr ),
     330             :                                                     true
     331             :                                                   );
     332             : 
     333             :         /* description */
     334           0 :         out_err |= json_writer_write_member_string_array( &((*this_).json_writer) ,
     335             :                                                           4,
     336             :                                                           JSON_CONSTANTS_KEY_CLASSIFIER_DESCRIPTION,
     337           0 :                                                           data_classifier_get_description_const( classifier_ptr ),
     338             :                                                           true
     339             :                                                         );
     340             : 
     341             :         /* x_order */
     342           0 :         out_err |= json_writer_write_member_int( &((*this_).json_writer),
     343             :                                                  4,
     344             :                                                  JSON_CONSTANTS_KEY_CLASSIFIER_X_ORDER,
     345           0 :                                                  data_classifier_get_x_order( classifier_ptr ),
     346             :                                                  true
     347             :                                                );
     348             : 
     349             :         /* y_order */
     350           0 :         out_err |= json_writer_write_member_int( &((*this_).json_writer),
     351             :                                                  4,
     352             :                                                  JSON_CONSTANTS_KEY_CLASSIFIER_Y_ORDER,
     353           0 :                                                  data_classifier_get_y_order( classifier_ptr ),
     354             :                                                  true
     355             :                                                );
     356             : 
     357             :         /* list_order */
     358           0 :         out_err |= json_writer_write_member_int( &((*this_).json_writer),
     359             :                                                  4,
     360             :                                                  JSON_CONSTANTS_KEY_CLASSIFIER_LIST_ORDER,
     361           0 :                                                  data_classifier_get_list_order( classifier_ptr ),
     362             :                                                  true
     363             :                                                );
     364             : 
     365             :         /* uuid */
     366           0 :         out_err |= json_writer_write_member_string( &((*this_).json_writer),
     367             :                                                     4,
     368             :                                                     JSON_CONSTANTS_KEY_UUID,
     369           0 :                                                     data_classifier_get_uuid_const( classifier_ptr ),
     370             :                                                     true
     371             :                                                   );
     372             : 
     373             :         /* array of features */
     374           0 :         out_err |= json_writer_write_plain( &((*this_).json_writer),
     375             :                                             JSON_CONSTANTS_TAB
     376             :                                             JSON_CONSTANTS_TAB
     377             :                                             JSON_CONSTANTS_TAB
     378             :                                             JSON_CONSTANTS_TAB
     379             :                                             JSON_CONSTANTS_QUOTE
     380             :                                             JSON_CONSTANTS_KEY_CLASSIFIER_FEATURES
     381             :                                             JSON_CONSTANTS_QUOTE
     382             :                                             JSON_CONSTANTS_DEF_NL
     383             :                                             JSON_CONSTANTS_TAB
     384             :                                             JSON_CONSTANTS_TAB
     385             :                                             JSON_CONSTANTS_TAB
     386             :                                             JSON_CONSTANTS_TAB
     387             :                                             JSON_CONSTANTS_BEGIN_ARRAY
     388             :                                           );
     389             : 
     390           0 :         (*this_).in_inner_array = true;
     391           0 :         (*this_).is_inner_first = true;
     392             : 
     393             :         /* update export statistics */
     394           0 :         data_stat_inc_count ( (*this_).export_stat, DATA_STAT_TABLE_CLASSIFIER, DATA_STAT_SERIES_EXPORTED );
     395             :     }
     396             : 
     397           0 :     U8_TRACE_END_ERR(out_err);
     398           0 :     return out_err;
     399             : }
     400             : 
     401           0 : u8_error_t json_element_writer_end_classifier( json_element_writer_t *this_,
     402             :                                                data_classifier_type_t host_type,
     403             :                                                const data_classifier_t *classifier_ptr )
     404             : {
     405           0 :     U8_TRACE_BEGIN();
     406           0 :     assert( classifier_ptr != NULL );
     407           0 :     u8_error_t out_err = U8_ERROR_NONE;
     408             : 
     409           0 :     if ( (*this_).mode == JSON_WRITER_PASS_NODES )
     410             :     {
     411           0 :         assert( (*this_).in_outer_array == true );
     412           0 :         assert( (*this_).in_inner_array == true );
     413           0 :         (*this_).in_inner_array = false;
     414           0 :         (*this_).is_inner_first = false;
     415             : 
     416           0 :         out_err |= json_writer_write_plain( &((*this_).json_writer),
     417             :                                             JSON_CONSTANTS_NL
     418             :                                           );
     419             : 
     420           0 :         out_err |= json_writer_write_plain( &((*this_).json_writer),
     421             :                                             JSON_CONSTANTS_TAB
     422             :                                             JSON_CONSTANTS_TAB
     423             :                                             JSON_CONSTANTS_TAB
     424             :                                             JSON_CONSTANTS_TAB
     425             :                                             JSON_CONSTANTS_END_ARRAY
     426             :                                             JSON_CONSTANTS_NL
     427             :                                           );
     428             : 
     429             :         /* end classifier */
     430           0 :         out_err |= json_writer_write_plain( &((*this_).json_writer),
     431             :                                             JSON_CONSTANTS_TAB
     432             :                                             JSON_CONSTANTS_TAB
     433             :                                             JSON_CONSTANTS_TAB
     434             :                                             JSON_CONSTANTS_END_OBJECT_NL
     435             :                                             JSON_CONSTANTS_TAB
     436             :                                             JSON_CONSTANTS_TAB
     437             :                                             JSON_CONSTANTS_END_OBJECT
     438             :                                           );
     439             : 
     440           0 :         if ( out_err != 0 )
     441             :         {
     442           0 :             U8_LOG_ERROR( "output buffer exceeded." );
     443             :         }
     444             :     }
     445             : 
     446           0 :     U8_TRACE_END_ERR(out_err);
     447           0 :     return out_err;
     448             : }
     449             : 
     450           0 : u8_error_t json_element_writer_start_feature( json_element_writer_t *this_,
     451             :                                               data_classifier_type_t parent_type,
     452             :                                               const data_feature_t *feature_ptr )
     453             : {
     454           0 :     U8_TRACE_BEGIN();
     455           0 :     assert( feature_ptr != NULL );
     456           0 :     u8_error_t out_err = U8_ERROR_NONE;
     457             : 
     458           0 :     if ( (*this_).mode == JSON_WRITER_PASS_NODES )
     459             :     {
     460             :         /* separate objects in array if not first */
     461           0 :         if ( (*this_).is_inner_first )
     462             :         {
     463           0 :             (*this_).is_inner_first = false;
     464           0 :             out_err |= json_writer_write_plain( &((*this_).json_writer),
     465             :                                                 JSON_CONSTANTS_NL
     466             :                                               );
     467             :         }
     468             :         else
     469             :         {
     470           0 :             out_err |= json_writer_write_plain( &((*this_).json_writer),
     471             :                                                 JSON_CONSTANTS_NEXT_NL
     472             :                                               );
     473             :         }
     474             : 
     475             :         /* begin feature */
     476           0 :         out_err |= json_writer_write_plain( &((*this_).json_writer),
     477             :                                             JSON_CONSTANTS_TAB
     478             :                                             JSON_CONSTANTS_TAB
     479             :                                             JSON_CONSTANTS_TAB
     480             :                                             JSON_CONSTANTS_TAB
     481             :                                             JSON_CONSTANTS_TAB
     482             :                                             JSON_CONSTANTS_BEGIN_OBJECT_NL
     483             :                                           );
     484             :     }
     485             : 
     486           0 :     U8_TRACE_END_ERR(out_err);
     487           0 :     return out_err;
     488             : }
     489             : 
     490           0 : u8_error_t json_element_writer_assemble_feature( json_element_writer_t *this_,
     491             :                                                  const data_classifier_t *parent,
     492             :                                                  const data_feature_t *feature_ptr )
     493             : {
     494           0 :     U8_TRACE_BEGIN();
     495           0 :     assert( feature_ptr != NULL );
     496           0 :     assert( parent != NULL );
     497           0 :     u8_error_t out_err = U8_ERROR_NONE;
     498             : 
     499           0 :     if ( (*this_).mode == JSON_WRITER_PASS_NODES )
     500             :     {
     501           0 :         assert( (*this_).in_outer_array == true );
     502           0 :         assert( (*this_).in_inner_array == true );
     503             : 
     504             :         /* id */
     505           0 :         out_err |= json_writer_write_member_int( &((*this_).json_writer),
     506             :                                                  6,
     507             :                                                  JSON_CONSTANTS_KEY_FEATURE_ID,
     508             :                                                  data_feature_get_row_id( feature_ptr ),
     509             :                                                  true
     510             :                                                );
     511             : 
     512             :         /* type */
     513             :         const char *const type_name
     514           0 :             = json_type_name_map_get_feature_type( &((*this_).type_map),
     515             :                                                    data_feature_get_main_type( feature_ptr )
     516             :                                                  );
     517           0 :         out_err |= json_writer_write_member_enum( &((*this_).json_writer),
     518             :                                                   6,
     519             :                                                   JSON_CONSTANTS_KEY_FEATURE_MAIN_TYPE_NAME,
     520             :                                                   type_name,
     521             :                                                   JSON_CONSTANTS_KEY_FEATURE_MAIN_TYPE,
     522           0 :                                                   data_feature_get_main_type( feature_ptr ),
     523             :                                                   true
     524             :                                                 );
     525             : 
     526             :         /* key */
     527           0 :         out_err |= json_writer_write_member_string( &((*this_).json_writer),
     528             :                                                     6,
     529             :                                                     JSON_CONSTANTS_KEY_FEATURE_KEY,
     530           0 :                                                     data_feature_get_key_const( feature_ptr ),
     531             :                                                     true
     532             :                                                   );
     533             : 
     534             :         /* value */
     535           0 :         if ( data_feature_has_value( feature_ptr ) )
     536             :         {
     537           0 :             out_err |= json_writer_write_member_string( &((*this_).json_writer),
     538             :                                                         6,
     539             :                                                         JSON_CONSTANTS_KEY_FEATURE_VALUE,
     540           0 :                                                         data_feature_get_value_const( feature_ptr ),
     541             :                                                         true
     542             :                                                       );
     543             :         }
     544             : 
     545             :         /* description */
     546           0 :         out_err |= json_writer_write_member_string_array( &((*this_).json_writer) ,
     547             :                                                           6,
     548             :                                                           JSON_CONSTANTS_KEY_FEATURE_DESCRIPTION,
     549           0 :                                                           data_feature_get_description_const( feature_ptr ),
     550             :                                                           true
     551             :                                                         );
     552             : 
     553             :         /* list_order */
     554           0 :         out_err |= json_writer_write_member_int( &((*this_).json_writer),
     555             :                                                  6,
     556             :                                                  JSON_CONSTANTS_KEY_FEATURE_LIST_ORDER,
     557           0 :                                                  data_feature_get_list_order( feature_ptr ),
     558             :                                                  true
     559             :                                                );
     560             : 
     561             :         /* uuid */
     562           0 :         out_err |= json_writer_write_member_string( &((*this_).json_writer),
     563             :                                                     6,
     564             :                                                     JSON_CONSTANTS_KEY_UUID,
     565           0 :                                                     data_feature_get_uuid_const( feature_ptr ),
     566             :                                                     false  /* LAST, no NEXT */
     567             :                                                   );
     568             : 
     569             :         /* update export statistics */
     570           0 :         const data_feature_type_t feat_type = data_feature_get_main_type( feature_ptr );
     571           0 :         const data_stat_table_t feat_or_lifeline
     572           0 :             = ( feat_type == DATA_FEATURE_TYPE_LIFELINE ) ? DATA_STAT_TABLE_LIFELINE : DATA_STAT_TABLE_FEATURE;
     573           0 :         data_stat_inc_count ( (*this_).export_stat, feat_or_lifeline, DATA_STAT_SERIES_EXPORTED );
     574             :     }
     575             : 
     576           0 :     U8_TRACE_END_ERR(out_err);
     577           0 :     return out_err;
     578             : }
     579             : 
     580           0 : u8_error_t json_element_writer_end_feature( json_element_writer_t *this_,
     581             :                                             data_classifier_type_t parent_type,
     582             :                                             const data_feature_t *feature_ptr )
     583             : {
     584           0 :     U8_TRACE_BEGIN();
     585           0 :     assert( feature_ptr != NULL );
     586           0 :     u8_error_t out_err = U8_ERROR_NONE;
     587             : 
     588           0 :     if ( (*this_).mode == JSON_WRITER_PASS_NODES )
     589             :     {
     590             :         /* end feature */
     591           0 :         out_err |= json_writer_write_plain( &((*this_).json_writer),
     592             :                                             JSON_CONSTANTS_TAB
     593             :                                             JSON_CONSTANTS_TAB
     594             :                                             JSON_CONSTANTS_TAB
     595             :                                             JSON_CONSTANTS_TAB
     596             :                                             JSON_CONSTANTS_TAB
     597             :                                             JSON_CONSTANTS_END_OBJECT
     598             :                                           );
     599             : 
     600           0 :         if ( out_err != 0 )
     601             :         {
     602           0 :             U8_LOG_ERROR( "output buffer exceeded." );
     603             :         }
     604             :     }
     605             : 
     606           0 :     U8_TRACE_END_ERR(out_err);
     607           0 :     return out_err;
     608             : }
     609             : 
     610           0 : u8_error_t json_element_writer_start_relationship( json_element_writer_t *this_,
     611             :                                                    data_classifier_type_t host_type,
     612             :                                                    const data_relationship_t *relation_ptr )
     613             : {
     614           0 :     U8_TRACE_BEGIN();
     615           0 :     assert( relation_ptr != NULL );
     616           0 :     u8_error_t out_err = U8_ERROR_NONE;
     617             : 
     618           0 :     if ( (*this_).mode == JSON_WRITER_PASS_EDGES )
     619             :     {
     620             :         /* separate objects if not first */
     621           0 :         if ( (*this_).is_outer_first )
     622             :         {
     623           0 :             (*this_).is_outer_first = false;
     624           0 :             out_err |= json_writer_write_plain( &((*this_).json_writer),
     625             :                                                 JSON_CONSTANTS_NL
     626             :                                               );
     627             :         }
     628             :         else
     629             :         {
     630           0 :             out_err |= json_writer_write_plain( &((*this_).json_writer),
     631             :                                                 JSON_CONSTANTS_NEXT_NL
     632             :                                               );
     633             :         }
     634             : 
     635             :         /* begin relationship */
     636           0 :         out_err |= json_writer_write_plain( &((*this_).json_writer),
     637             :                                             JSON_CONSTANTS_TAB
     638             :                                             JSON_CONSTANTS_TAB
     639             :                                             JSON_CONSTANTS_BEGIN_OBJECT
     640             :                                             JSON_CONSTANTS_NL
     641             :                                             JSON_CONSTANTS_TAB
     642             :                                             JSON_CONSTANTS_TAB
     643             :                                             JSON_CONSTANTS_TAB
     644             :                                             JSON_CONSTANTS_QUOTE
     645             :                                             JSON_CONSTANTS_KEY_RELATIONSHIP
     646             :                                             JSON_CONSTANTS_QUOTE
     647             :                                             JSON_CONSTANTS_DEF
     648             :                                             JSON_CONSTANTS_BEGIN_OBJECT_NL
     649             :                                           );
     650             :     }
     651             : 
     652           0 :     U8_TRACE_END_ERR(out_err);
     653           0 :     return out_err;
     654             : }
     655             : 
     656           0 : u8_error_t json_element_writer_assemble_relationship( json_element_writer_t *this_,
     657             :                                                       const data_classifier_t *host,
     658             :                                                       const data_relationship_t *relation_ptr,
     659             :                                                       const data_classifier_t *from_c,
     660             :                                                       const data_feature_t *from_f,
     661             :                                                       const data_classifier_t *to_c,
     662             :                                                       const data_feature_t *to_f )
     663             : {
     664           0 :     U8_TRACE_BEGIN();
     665           0 :     assert( relation_ptr != NULL );
     666           0 :     u8_error_t out_err = U8_ERROR_NONE;
     667             : 
     668           0 :     if ( (*this_).mode == JSON_WRITER_PASS_EDGES )
     669             :     {
     670           0 :         assert( from_c != NULL );
     671           0 :         assert( to_c != NULL );
     672           0 :         assert( (*this_).in_outer_array == true );
     673           0 :         assert( (*this_).in_inner_array == false );
     674             : 
     675           0 :         const bool from_f_valid = ( from_f == NULL ) ? false : data_feature_is_valid( from_f );
     676           0 :         const bool from_c_valid = ( from_c == NULL ) ? false : data_classifier_is_valid( from_c );
     677           0 :         const bool to_f_valid = ( to_f == NULL ) ? false : data_feature_is_valid( to_f );
     678           0 :         const bool to_c_valid = ( to_c == NULL ) ? false : data_classifier_is_valid( to_c );
     679             : 
     680             :         /* id */
     681           0 :         out_err |= json_writer_write_member_int( &((*this_).json_writer),
     682             :                                                  4,
     683             :                                                  JSON_CONSTANTS_KEY_RELATIONSHIP_ID,
     684             :                                                  data_relationship_get_row_id( relation_ptr ),
     685             :                                                  true
     686             :                                                );
     687             : 
     688             :         /* type */
     689             :         const char *const type_name
     690           0 :             = json_type_name_map_get_relationship_type( &((*this_).type_map),
     691             :                                                         data_relationship_get_main_type( relation_ptr )
     692             :                                                       );
     693           0 :         out_err |= json_writer_write_member_enum( &((*this_).json_writer),
     694             :                                                   4,
     695             :                                                   JSON_CONSTANTS_KEY_RELATIONSHIP_MAIN_TYPE_NAME,
     696             :                                                   type_name,
     697             :                                                   JSON_CONSTANTS_KEY_RELATIONSHIP_MAIN_TYPE,
     698           0 :                                                   data_relationship_get_main_type( relation_ptr ),
     699             :                                                   true
     700             :                                                 );
     701             : 
     702             :         /* stereotype */
     703           0 :         if ( data_relationship_has_stereotype( relation_ptr ) )
     704             :         {
     705           0 :             out_err |= json_writer_write_member_string( &((*this_).json_writer),
     706             :                                                         4,
     707             :                                                         JSON_CONSTANTS_KEY_RELATIONSHIP_STEREOTYPE,
     708           0 :                                                         data_relationship_get_stereotype_const( relation_ptr ),
     709             :                                                         true
     710             :                                                       );
     711             :         }
     712             : 
     713             :         /* name */
     714           0 :         out_err |= json_writer_write_member_string( &((*this_).json_writer),
     715             :                                                     4,
     716             :                                                     JSON_CONSTANTS_KEY_RELATIONSHIP_NAME,
     717           0 :                                                     data_relationship_get_name_const( relation_ptr ),
     718             :                                                     true
     719             :                                                   );
     720             : 
     721             :         /* description */
     722           0 :         out_err |= json_writer_write_member_string_array( &((*this_).json_writer) ,
     723             :                                                           4,
     724             :                                                           JSON_CONSTANTS_KEY_RELATIONSHIP_DESCRIPTION,
     725           0 :                                                           data_relationship_get_description_const( relation_ptr ),
     726             :                                                           true
     727             :                                                         );
     728             : 
     729             :         /* list_order */
     730           0 :         out_err |= json_writer_write_member_int( &((*this_).json_writer),
     731             :                                                  4,
     732             :                                                  JSON_CONSTANTS_KEY_RELATIONSHIP_LIST_ORDER,
     733           0 :                                                  data_relationship_get_list_order( relation_ptr ),
     734             :                                                  true
     735             :                                                );
     736             : 
     737             :         /* from_classifier_name */
     738           0 :         const char *const from_c_name = from_c_valid ? data_classifier_get_name_const( from_c ) : "";
     739           0 :         out_err |= json_writer_write_plain( &((*this_).json_writer),
     740             :                                             JSON_CONSTANTS_TAB
     741             :                                             JSON_CONSTANTS_TAB
     742             :                                             JSON_CONSTANTS_TAB
     743             :                                             JSON_CONSTANTS_TAB
     744             :                                             JSON_CONSTANTS_QUOTE
     745             :                                             JSON_CONSTANTS_KEY_RELATIONSHIP_FROM_CLASSIFIER_NAME
     746             :                                             JSON_CONSTANTS_QUOTE
     747             :                                             JSON_CONSTANTS_DEF
     748             :                                             JSON_CONSTANTS_QUOTE
     749             :                                           );
     750           0 :         out_err |= json_writer_write_string_enc( &((*this_).json_writer), from_c_name );
     751           0 :         out_err |= json_writer_write_plain( &((*this_).json_writer),
     752             :                                             JSON_CONSTANTS_QUOTE
     753             :                                             JSON_CONSTANTS_NEXT_NL
     754             :                                           );
     755             : 
     756             :         /* from_feature_key */
     757           0 :         if ( from_f_valid )
     758             :         {
     759           0 :             out_err |= json_writer_write_plain( &((*this_).json_writer),
     760             :                                                 JSON_CONSTANTS_TAB
     761             :                                                 JSON_CONSTANTS_TAB
     762             :                                                 JSON_CONSTANTS_TAB
     763             :                                                 JSON_CONSTANTS_TAB
     764             :                                                 JSON_CONSTANTS_QUOTE
     765             :                                                 JSON_CONSTANTS_KEY_RELATIONSHIP_FROM_FEATURE_KEY
     766             :                                                 JSON_CONSTANTS_QUOTE
     767             :                                                 JSON_CONSTANTS_DEF
     768             :                                                 JSON_CONSTANTS_QUOTE
     769             :                                               );
     770           0 :             out_err |= json_writer_write_string_enc( &((*this_).json_writer),
     771           0 :                                                      data_feature_get_key_const( from_f )
     772             :                                                    );
     773           0 :             out_err |= json_writer_write_plain( &((*this_).json_writer),
     774             :                                                 JSON_CONSTANTS_QUOTE
     775             :                                                 JSON_CONSTANTS_NEXT_NL
     776             :                                               );
     777             :         }
     778             : 
     779             :         /* to_classifier_name */
     780           0 :         const char *const to_c_name = to_c_valid ? data_classifier_get_name_const( to_c ) : "";
     781           0 :         out_err |= json_writer_write_plain( &((*this_).json_writer),
     782             :                                             JSON_CONSTANTS_TAB
     783             :                                             JSON_CONSTANTS_TAB
     784             :                                             JSON_CONSTANTS_TAB
     785             :                                             JSON_CONSTANTS_TAB
     786             :                                             JSON_CONSTANTS_QUOTE
     787             :                                             JSON_CONSTANTS_KEY_RELATIONSHIP_TO_CLASSIFIER_NAME
     788             :                                             JSON_CONSTANTS_QUOTE
     789             :                                             JSON_CONSTANTS_DEF
     790             :                                             JSON_CONSTANTS_QUOTE
     791             :                                           );
     792           0 :         out_err |= json_writer_write_string_enc( &((*this_).json_writer), to_c_name );
     793           0 :         out_err |= json_writer_write_plain( &((*this_).json_writer),
     794             :                                             JSON_CONSTANTS_QUOTE
     795             :                                             JSON_CONSTANTS_NEXT_NL
     796             :                                           );
     797             : 
     798             :         /* to_feature_key */
     799           0 :         if ( to_f_valid )
     800             :         {
     801           0 :             out_err |= json_writer_write_plain( &((*this_).json_writer),
     802             :                                                 JSON_CONSTANTS_TAB
     803             :                                                 JSON_CONSTANTS_TAB
     804             :                                                 JSON_CONSTANTS_TAB
     805             :                                                 JSON_CONSTANTS_TAB
     806             :                                                 JSON_CONSTANTS_QUOTE
     807             :                                                 JSON_CONSTANTS_KEY_RELATIONSHIP_TO_FEATURE_KEY
     808             :                                                 JSON_CONSTANTS_QUOTE
     809             :                                                 JSON_CONSTANTS_DEF
     810             :                                                 JSON_CONSTANTS_QUOTE
     811             :                                               );
     812           0 :             out_err |= json_writer_write_string_enc( &((*this_).json_writer),
     813           0 :                                                      data_feature_get_key_const( to_f )
     814             :                                                    );
     815           0 :             out_err |= json_writer_write_plain( &((*this_).json_writer),
     816             :                                                 JSON_CONSTANTS_QUOTE
     817             :                                                 JSON_CONSTANTS_NEXT_NL
     818             :                                               );
     819             :         }
     820             : 
     821             :         /* from node ref_uuid */
     822           0 :         const char *const from_node_ref
     823             :             = ( from_f_valid )
     824           0 :             ? data_feature_get_uuid_const( from_f )
     825           0 :             : ( from_c_valid )
     826           0 :             ? data_classifier_get_uuid_const( from_c )
     827           0 :             : "";
     828           0 :         out_err |= json_writer_write_member_string( &((*this_).json_writer),
     829             :                                                     4,
     830             :                                                     JSON_CONSTANTS_KEY_RELATIONSHIP_FROM_NODE,
     831             :                                                     from_node_ref,
     832             :                                                     true
     833             :                                                   );
     834             : 
     835             :         /* to node ref_uuid */
     836           0 :         const char *const to_node_ref
     837             :             = ( to_f_valid )
     838           0 :             ? data_feature_get_uuid_const( to_f )
     839           0 :             : ( to_c_valid )
     840           0 :             ? data_classifier_get_uuid_const( to_c )
     841           0 :             : "";
     842           0 :         out_err |= json_writer_write_member_string( &((*this_).json_writer),
     843             :                                                     4,
     844             :                                                     JSON_CONSTANTS_KEY_RELATIONSHIP_TO_NODE,
     845             :                                                     to_node_ref,
     846             :                                                     true
     847             :                                                   );
     848             : 
     849             :         /* uuid */
     850           0 :         out_err |= json_writer_write_member_string( &((*this_).json_writer),
     851             :                                                     4,
     852             :                                                     JSON_CONSTANTS_KEY_UUID,
     853           0 :                                                     data_relationship_get_uuid_const( relation_ptr ),
     854             :                                                     false  /* LAST, no NEXT */
     855             :                                                   );
     856             : 
     857             :         /* update export statistics */
     858           0 :         data_stat_inc_count ( (*this_).export_stat, DATA_STAT_TABLE_RELATIONSHIP, DATA_STAT_SERIES_EXPORTED );
     859             :     }
     860             : 
     861           0 :     U8_TRACE_END_ERR(out_err);
     862           0 :     return out_err;
     863             : }
     864             : 
     865           0 : u8_error_t json_element_writer_end_relationship( json_element_writer_t *this_,
     866             :                                                  data_classifier_type_t host_type,
     867             :                                                  const data_relationship_t *relation_ptr )
     868             : {
     869           0 :     U8_TRACE_BEGIN();
     870           0 :     assert( relation_ptr != NULL );
     871           0 :     u8_error_t out_err = U8_ERROR_NONE;
     872             : 
     873           0 :     if ( (*this_).mode == JSON_WRITER_PASS_EDGES )
     874             :     {
     875             :         /* end relationship */
     876           0 :         out_err |= json_writer_write_plain( &((*this_).json_writer),
     877             :                                             JSON_CONSTANTS_TAB
     878             :                                             JSON_CONSTANTS_TAB
     879             :                                             JSON_CONSTANTS_TAB
     880             :                                             JSON_CONSTANTS_END_OBJECT_NL
     881             :                                             JSON_CONSTANTS_TAB
     882             :                                             JSON_CONSTANTS_TAB
     883             :                                             JSON_CONSTANTS_END_OBJECT
     884             :                                           );
     885             : 
     886           0 :         if ( out_err != 0 )
     887             :         {
     888           0 :             U8_LOG_ERROR( "output buffer exceeded." );
     889             :         }
     890             :     }
     891             : 
     892           0 :     U8_TRACE_END_ERR(out_err);
     893           0 :     return out_err;
     894             : }
     895             : 
     896           0 : u8_error_t json_element_writer_start_diagram( json_element_writer_t *this_, const data_diagram_t *diag_ptr )
     897             : {
     898           0 :     U8_TRACE_BEGIN();
     899           0 :     assert( diag_ptr != NULL );
     900           0 :     u8_error_t out_err = U8_ERROR_NONE;
     901             : 
     902           0 :     if ( (*this_).mode == JSON_WRITER_PASS_VIEWS )
     903             :     {
     904             :         /* separate objects if not first */
     905           0 :         if ( (*this_).is_outer_first )
     906             :         {
     907           0 :             (*this_).is_outer_first = false;
     908           0 :             out_err |= json_writer_write_plain( &((*this_).json_writer),  JSON_CONSTANTS_NL );
     909             :         }
     910             :         else
     911             :         {
     912             :             /* print diagram end here because the official end requires hierarcical diagram containments */
     913           0 :             out_err |= json_element_writer_private_end_diagram( this_ );
     914             : 
     915           0 :             out_err |= json_writer_write_plain( &((*this_).json_writer), JSON_CONSTANTS_NEXT_NL  );
     916             :         }
     917             : 
     918           0 :         assert( (*this_).in_outer_array == true );
     919           0 :         assert( (*this_).in_inner_array == false );
     920             : 
     921             :         /* begin diagram */
     922           0 :         out_err |= json_writer_write_plain( &((*this_).json_writer),
     923             :                                             JSON_CONSTANTS_TAB
     924             :                                             JSON_CONSTANTS_TAB
     925             :                                             JSON_CONSTANTS_BEGIN_OBJECT
     926             :                                             JSON_CONSTANTS_NL
     927             :                                             JSON_CONSTANTS_TAB
     928             :                                             JSON_CONSTANTS_TAB
     929             :                                             JSON_CONSTANTS_TAB
     930             :                                             JSON_CONSTANTS_QUOTE
     931             :                                             JSON_CONSTANTS_KEY_DIAGRAM
     932             :                                             JSON_CONSTANTS_QUOTE
     933             :                                             JSON_CONSTANTS_DEF
     934             :                                             JSON_CONSTANTS_BEGIN_OBJECT_NL
     935             :                                           );
     936             :     }
     937             : 
     938           0 :     U8_TRACE_END_ERR(out_err);
     939           0 :     return out_err;
     940             : }
     941             : 
     942           0 : u8_error_t json_element_writer_assemble_diagram( json_element_writer_t *this_,
     943             :                                                  const data_diagram_t *parent,
     944             :                                                  const data_diagram_t *diag_ptr,
     945             :                                                  const char *diagram_file_base_name )
     946             : {
     947           0 :     U8_TRACE_BEGIN();
     948           0 :     assert( diag_ptr != NULL );
     949           0 :     assert( diagram_file_base_name != NULL );
     950           0 :     u8_error_t out_err = U8_ERROR_NONE;
     951             : 
     952           0 :     if ( (*this_).mode == JSON_WRITER_PASS_VIEWS )
     953             :     {
     954             :         /* id */
     955           0 :         out_err |= json_writer_write_member_int( &((*this_).json_writer),
     956             :                                                  4,
     957             :                                                  JSON_CONSTANTS_KEY_DIAGRAM_ID,
     958             :                                                  data_diagram_get_row_id( diag_ptr ),
     959             :                                                  true
     960             :                                                );
     961             : 
     962             :         /* diagram type */
     963             :         const char *const type_name
     964           0 :             = json_type_name_map_get_diagram_type( &((*this_).type_map),
     965             :                                                    data_diagram_get_diagram_type( diag_ptr )
     966             :                                                  );
     967           0 :         out_err |= json_writer_write_member_enum( &((*this_).json_writer),
     968             :                                                   4,
     969             :                                                   JSON_CONSTANTS_KEY_DIAGRAM_DIAGRAM_TYPE_NAME,
     970             :                                                   type_name,
     971             :                                                   JSON_CONSTANTS_KEY_DIAGRAM_DIAGRAM_TYPE,
     972           0 :                                                   data_diagram_get_diagram_type( diag_ptr ),
     973             :                                                   true
     974             :                                                 );
     975             : 
     976             :         /* stereotype */
     977           0 :         if ( data_diagram_has_stereotype( diag_ptr ) )
     978             :         {
     979           0 :             out_err |= json_writer_write_member_string( &((*this_).json_writer),
     980             :                                                         4,
     981             :                                                         JSON_CONSTANTS_KEY_DIAGRAM_STEREOTYPE,
     982           0 :                                                         data_diagram_get_stereotype_const( diag_ptr ),
     983             :                                                         true
     984             :                                                       );
     985             :         }
     986             : 
     987             :         /* name */
     988           0 :         out_err |= json_writer_write_member_string( &((*this_).json_writer),
     989             :                                                     4,
     990             :                                                     JSON_CONSTANTS_KEY_DIAGRAM_NAME,
     991           0 :                                                     data_diagram_get_name_const( diag_ptr ),
     992             :                                                     true
     993             :                                                   );
     994             : 
     995             :         /* description */
     996           0 :         out_err |= json_writer_write_member_string_array( &((*this_).json_writer) ,
     997             :                                                           4,
     998             :                                                           JSON_CONSTANTS_KEY_DIAGRAM_DESCRIPTION,
     999           0 :                                                           data_diagram_get_description_const( diag_ptr ),
    1000             :                                                           true
    1001             :                                                         );
    1002             : 
    1003             :         /* list_order */
    1004           0 :         out_err |= json_writer_write_member_int( &((*this_).json_writer),
    1005             :                                                  4,
    1006             :                                                  JSON_CONSTANTS_KEY_DIAGRAM_LIST_ORDER,
    1007           0 :                                                  data_diagram_get_list_order( diag_ptr ),
    1008             :                                                  true
    1009             :                                                );
    1010             : 
    1011             :         /* display_tags (flag names) + display_flags */
    1012           0 :         if ( data_diagram_get_display_flags( diag_ptr ) != DATA_DIAGRAM_FLAG_NONE )
    1013             :         {
    1014             :             const char *const tag_names
    1015           0 :                 = json_type_name_map_get_diagram_tags( &((*this_).type_map),
    1016             :                                                        data_diagram_get_display_flags( diag_ptr )
    1017             :                                                      );
    1018             : 
    1019           0 :             out_err |= json_writer_write_member_enum( &((*this_).json_writer),
    1020             :                                                       4,
    1021             :                                                       JSON_CONSTANTS_KEY_DIAGRAM_DISPLAY_FLAG_NAMES,
    1022             :                                                       tag_names,
    1023             :                                                       JSON_CONSTANTS_KEY_DIAGRAM_DISPLAY_FLAGS,
    1024           0 :                                                       data_diagram_get_display_flags( diag_ptr ),
    1025             :                                                       true
    1026             :                                                     );
    1027             :         }
    1028             : 
    1029           0 :         const bool parent_valid = ( parent == NULL ) ? false : data_diagram_is_valid( parent );
    1030             : 
    1031             :         /* parent_name */
    1032           0 :         if( parent_valid )
    1033             :         {
    1034           0 :             out_err |= json_writer_write_member_string( &((*this_).json_writer),
    1035             :                                                         4,
    1036             :                                                         JSON_CONSTANTS_KEY_DIAGRAM_PARENT_NAME,
    1037           0 :                                                         data_diagram_get_name_const( parent ),
    1038             :                                                         true
    1039             :                                                     );
    1040             :         }
    1041             : 
    1042             :         /* parent uuid */
    1043           0 :         if ( parent_valid )
    1044             :         {
    1045           0 :             out_err |= json_writer_write_member_string( &((*this_).json_writer),
    1046             :                                                         4,
    1047             :                                                         JSON_CONSTANTS_KEY_DIAGRAM_PARENT,
    1048           0 :                                                         data_diagram_get_uuid_const( parent ),
    1049             :                                                         true
    1050             :                                                       );
    1051             :         }
    1052             : 
    1053             :         /* uuid */
    1054           0 :         out_err |= json_writer_write_member_string( &((*this_).json_writer),
    1055             :                                                     4,
    1056             :                                                     JSON_CONSTANTS_KEY_UUID,
    1057           0 :                                                     data_diagram_get_uuid_const( diag_ptr ),
    1058             :                                                     true  /* NEXT, not LAST */
    1059             :                                                   );
    1060             : 
    1061             :         /* array of features */
    1062           0 :         out_err |= json_writer_write_plain( &((*this_).json_writer),
    1063             :                                             JSON_CONSTANTS_TAB
    1064             :                                             JSON_CONSTANTS_TAB
    1065             :                                             JSON_CONSTANTS_TAB
    1066             :                                             JSON_CONSTANTS_TAB
    1067             :                                             JSON_CONSTANTS_QUOTE
    1068             :                                             JSON_CONSTANTS_KEY_DIAGRAM_ELEMENTS
    1069             :                                             JSON_CONSTANTS_QUOTE
    1070             :                                             JSON_CONSTANTS_DEF_NL
    1071             :                                             JSON_CONSTANTS_TAB
    1072             :                                             JSON_CONSTANTS_TAB
    1073             :                                             JSON_CONSTANTS_TAB
    1074             :                                             JSON_CONSTANTS_TAB
    1075             :                                             JSON_CONSTANTS_BEGIN_ARRAY
    1076             :                                           );
    1077             : 
    1078           0 :         (*this_).in_inner_array = true;
    1079           0 :         (*this_).is_inner_first = true;
    1080             : 
    1081             :         /* update export statistics */
    1082           0 :         data_stat_inc_count ( (*this_).export_stat, DATA_STAT_TABLE_DIAGRAM, DATA_STAT_SERIES_EXPORTED );
    1083             :     }
    1084             : 
    1085           0 :     U8_TRACE_END_ERR(out_err);
    1086           0 :     return out_err;
    1087             : }
    1088             : 
    1089           0 : u8_error_t json_element_writer_end_diagram_fake( json_element_writer_t *this_, const data_diagram_t *diag_ptr )
    1090             : {
    1091           0 :     U8_TRACE_BEGIN();
    1092           0 :     assert( diag_ptr != NULL );
    1093           0 :     u8_error_t out_err = U8_ERROR_NONE;
    1094             : 
    1095             :     /* The JSON export does not encapsulate one diagram into another. */
    1096             :     /* Therefore, diagrams are ended already when the next starts. */
    1097             : 
    1098           0 :     U8_TRACE_END_ERR(out_err);
    1099           0 :     return out_err;
    1100             : }
    1101             : 
    1102           0 : u8_error_t json_element_writer_private_end_diagram( json_element_writer_t *this_ )
    1103             : {
    1104           0 :     U8_TRACE_BEGIN();
    1105           0 :     u8_error_t out_err = U8_ERROR_NONE;
    1106             : 
    1107           0 :     if ( (*this_).mode == JSON_WRITER_PASS_VIEWS )
    1108             :     {
    1109           0 :         (*this_).in_inner_array = false;
    1110           0 :         (*this_).is_inner_first = false;
    1111             : 
    1112           0 :         out_err |= json_writer_write_plain( &((*this_).json_writer),
    1113             :                                             JSON_CONSTANTS_NL
    1114             :                                           );
    1115             : 
    1116           0 :         out_err |= json_writer_write_plain( &((*this_).json_writer),
    1117             :                                             JSON_CONSTANTS_TAB
    1118             :                                             JSON_CONSTANTS_TAB
    1119             :                                             JSON_CONSTANTS_TAB
    1120             :                                             JSON_CONSTANTS_TAB
    1121             :                                             JSON_CONSTANTS_END_ARRAY
    1122             :                                             JSON_CONSTANTS_NL
    1123             :                                           );
    1124             : 
    1125             :         /* end diagram */
    1126           0 :         out_err |= json_writer_write_plain( &((*this_).json_writer),
    1127             :                                             JSON_CONSTANTS_TAB
    1128             :                                             JSON_CONSTANTS_TAB
    1129             :                                             JSON_CONSTANTS_TAB
    1130             :                                             JSON_CONSTANTS_END_OBJECT_NL
    1131             :                                             JSON_CONSTANTS_TAB
    1132             :                                             JSON_CONSTANTS_TAB
    1133             :                                             JSON_CONSTANTS_END_OBJECT
    1134             :                                           );
    1135             :     }
    1136             : 
    1137           0 :     U8_TRACE_END_ERR(out_err);
    1138           0 :     return out_err;
    1139             : }
    1140             : 
    1141           0 : u8_error_t json_element_writer_start_diagramelement( json_element_writer_t *this_,
    1142             :                                                      const data_diagram_t *parent,
    1143             :                                                      const data_diagramelement_t *diagramelement_ptr )
    1144             : {
    1145           0 :     U8_TRACE_BEGIN();
    1146           0 :     assert( diagramelement_ptr != NULL );
    1147           0 :     assert( parent != NULL );
    1148           0 :     u8_error_t out_err = U8_ERROR_NONE;
    1149             : 
    1150           0 :     if ( (*this_).mode == JSON_WRITER_PASS_VIEWS )
    1151             :     {
    1152             :         /* separate objects in array if not first */
    1153           0 :         if ( (*this_).is_inner_first )
    1154             :         {
    1155           0 :             (*this_).is_inner_first = false;
    1156           0 :             out_err |= json_writer_write_plain( &((*this_).json_writer),
    1157             :                                                 JSON_CONSTANTS_NL
    1158             :                                               );
    1159             :         }
    1160             :         else
    1161             :         {
    1162           0 :             out_err |= json_writer_write_plain( &((*this_).json_writer),
    1163             :                                                 JSON_CONSTANTS_NEXT_NL
    1164             :                                               );
    1165             :         }
    1166             : 
    1167             :         /* begin diagramelement */
    1168           0 :         out_err |= json_writer_write_plain( &((*this_).json_writer),
    1169             :                                             JSON_CONSTANTS_TAB
    1170             :                                             JSON_CONSTANTS_TAB
    1171             :                                             JSON_CONSTANTS_TAB
    1172             :                                             JSON_CONSTANTS_TAB
    1173             :                                             JSON_CONSTANTS_TAB
    1174             :                                             JSON_CONSTANTS_BEGIN_OBJECT_NL
    1175             :                                           );
    1176             : 
    1177           0 :         if ( out_err != 0 )
    1178             :         {
    1179           0 :             U8_LOG_ERROR( "output buffer exceeded." );
    1180             :         }
    1181             :     }
    1182             : 
    1183           0 :     U8_TRACE_END_ERR(out_err);
    1184           0 :     return out_err;
    1185             : }
    1186             : 
    1187           0 : u8_error_t json_element_writer_assemble_diagramelement( json_element_writer_t *this_,
    1188             :                                                         const data_diagram_t *parent,
    1189             :                                                         const data_diagramelement_t *diagramelement_ptr,
    1190             :                                                         const data_classifier_t *occurrence,
    1191             :                                                         const data_feature_t *feat_occur )
    1192             : {
    1193           0 :     U8_TRACE_BEGIN();
    1194           0 :     assert( parent != NULL );
    1195           0 :     assert( diagramelement_ptr != NULL );
    1196           0 :     assert( occurrence != NULL );
    1197             :     /* feat_occur may be NULL */
    1198           0 :     u8_error_t out_err = U8_ERROR_NONE;
    1199             : 
    1200           0 :     if ( (*this_).mode == JSON_WRITER_PASS_VIEWS )
    1201             :     {
    1202           0 :         assert( (*this_).in_outer_array == true );
    1203           0 :         assert( (*this_).in_inner_array == true );
    1204             : 
    1205             :         /* id */
    1206           0 :         out_err |= json_writer_write_member_int( &((*this_).json_writer),
    1207             :                                                  6,
    1208             :                                                  JSON_CONSTANTS_KEY_DIAGRAMELEMENT_ID,
    1209             :                                                  data_diagramelement_get_row_id( diagramelement_ptr ),
    1210             :                                                  true
    1211             :                                                );
    1212             : 
    1213             :         /* display_tags (flag names) + display_flags */
    1214           0 :         if ( data_diagramelement_get_display_flags( diagramelement_ptr ) != DATA_DIAGRAMELEMENT_FLAG_NONE )
    1215             :         {
    1216             :             const char *const tag_names
    1217           0 :                 = json_type_name_map_get_diagramelement_tags( &((*this_).type_map),
    1218             :                                                               data_diagramelement_get_display_flags( diagramelement_ptr )
    1219             :                                                             );
    1220           0 :             out_err |= json_writer_write_member_enum( &((*this_).json_writer),
    1221             :                                                       6,
    1222             :                                                       JSON_CONSTANTS_KEY_DIAGRAMELEMENT_DISPLAY_FLAG_NAMES,
    1223             :                                                       tag_names,
    1224             :                                                       JSON_CONSTANTS_KEY_DIAGRAMELEMENT_DISPLAY_FLAGS,
    1225           0 :                                                       data_diagramelement_get_display_flags( diagramelement_ptr ),
    1226             :                                                       true
    1227             :                                                     );
    1228             :         }
    1229             : 
    1230             :         /* classifier_name */
    1231           0 :         out_err |= json_writer_write_member_string( &((*this_).json_writer),
    1232             :                                                     6,
    1233             :                                                     JSON_CONSTANTS_KEY_DIAGRAMELEMENT_CLASSIFIER_NAME,
    1234           0 :                                                     data_classifier_get_name_const( occurrence ),
    1235             :                                                     true
    1236             :                                                   );
    1237             : 
    1238             :         /* focused_feature_name */
    1239             :         /* note that focused features are always lifelines and these never have names */
    1240             : 
    1241             :         /* ref_uuid */
    1242           0 :         const bool feat_valid = ( feat_occur == NULL ) ? false : data_feature_is_valid( feat_occur );
    1243           0 :         const bool clas_valid = data_classifier_is_valid( occurrence );
    1244           0 :         const char *const node_ref
    1245             :             = ( feat_valid )
    1246           0 :             ? data_feature_get_uuid_const( feat_occur )
    1247           0 :             : ( clas_valid )
    1248           0 :             ? data_classifier_get_uuid_const( occurrence )
    1249           0 :             : "";
    1250           0 :         out_err |= json_writer_write_member_string( &((*this_).json_writer),
    1251             :                                                     6,
    1252             :                                                     JSON_CONSTANTS_KEY_DIAGRAMELEMENT_NODE,
    1253             :                                                     node_ref,
    1254             :                                                     true
    1255             :                                                   );
    1256             : 
    1257             :         /* uuid */
    1258           0 :         out_err |= json_writer_write_member_string( &((*this_).json_writer),
    1259             :                                                     6,
    1260             :                                                     JSON_CONSTANTS_KEY_UUID,
    1261           0 :                                                     data_diagramelement_get_uuid_const( diagramelement_ptr ),
    1262             :                                                     false  /* LAST, no NEXT */
    1263             :                                                   );
    1264             : 
    1265             :         /* update export statistics */
    1266           0 :         data_stat_inc_count ( (*this_).export_stat, DATA_STAT_TABLE_DIAGRAMELEMENT, DATA_STAT_SERIES_EXPORTED );
    1267             :     }
    1268             : 
    1269           0 :     U8_TRACE_END_ERR(out_err);
    1270           0 :     return out_err;
    1271             : }
    1272             : 
    1273           0 : u8_error_t json_element_writer_end_diagramelement( json_element_writer_t *this_,
    1274             :                                                    const data_diagram_t *parent,
    1275             :                                                    const data_diagramelement_t *diagramelement_ptr )
    1276             : {
    1277           0 :     U8_TRACE_BEGIN();
    1278           0 :     assert( diagramelement_ptr != NULL );
    1279           0 :     assert( parent != NULL );
    1280           0 :     u8_error_t out_err = U8_ERROR_NONE;
    1281             : 
    1282           0 :     if ( (*this_).mode == JSON_WRITER_PASS_VIEWS )
    1283             :     {
    1284             :         /* end diagramelement */
    1285           0 :         out_err |= json_writer_write_plain( &((*this_).json_writer),
    1286             :                                             JSON_CONSTANTS_TAB
    1287             :                                             JSON_CONSTANTS_TAB
    1288             :                                             JSON_CONSTANTS_TAB
    1289             :                                             JSON_CONSTANTS_TAB
    1290             :                                             JSON_CONSTANTS_TAB
    1291             :                                             JSON_CONSTANTS_END_OBJECT
    1292             :                                           );
    1293             : 
    1294           0 :         if ( out_err != 0 )
    1295             :         {
    1296           0 :             U8_LOG_ERROR( "output buffer exceeded." );
    1297             :         }
    1298             :     }
    1299             : 
    1300           0 :     U8_TRACE_END_ERR(out_err);
    1301           0 :     return out_err;
    1302             : }
    1303             : 
    1304           6 : u8_error_t json_element_writer_end_main( json_element_writer_t *this_ )
    1305             : {
    1306           6 :     U8_TRACE_BEGIN();
    1307           6 :     u8_error_t out_err = U8_ERROR_NONE;
    1308             : 
    1309             :     /* print diagram end here because the official end requires hierarcical diagram containments */
    1310           6 :     if ( (*this_).mode == JSON_WRITER_PASS_VIEWS )
    1311             :     {
    1312           2 :         if ( ! (*this_).is_outer_first )
    1313             :         {
    1314           0 :             out_err |= json_element_writer_private_end_diagram( this_ );
    1315             :         }
    1316             :     }
    1317             : 
    1318           6 :     assert( (*this_).in_outer_array == true );
    1319           6 :     assert( (*this_).in_inner_array == false );
    1320           6 :     (*this_).in_outer_array = false;
    1321           6 :     (*this_).is_outer_first = false;
    1322             : 
    1323           6 :     out_err |= json_writer_write_plain( &((*this_).json_writer),
    1324             :                                         JSON_CONSTANTS_NL
    1325             :                                         JSON_CONSTANTS_TAB
    1326             :                                         JSON_CONSTANTS_END_ARRAY
    1327             :                                         JSON_CONSTANTS_NL
    1328             :                                       );
    1329             : 
    1330           6 :     if ( out_err != 0 )
    1331             :     {
    1332           0 :         U8_LOG_ERROR( "output buffer exceeded." );
    1333             :     }
    1334             : 
    1335           6 :     U8_TRACE_END_ERR(out_err);
    1336           6 :     return out_err;
    1337             : }
    1338             : 
    1339           2 : u8_error_t json_element_writer_write_footer( json_element_writer_t *this_ )
    1340             : {
    1341           2 :     U8_TRACE_BEGIN();
    1342           2 :     assert( (*this_).in_outer_array == false );
    1343           2 :     assert( (*this_).in_inner_array == false );
    1344           2 :     u8_error_t out_err = U8_ERROR_NONE;
    1345             : 
    1346           2 :     out_err |= json_writer_write_plain( &((*this_).json_writer),
    1347             :                                         JSON_CONSTANTS_END_OBJECT_NL
    1348             :                                       );
    1349             : 
    1350           2 :     if ( out_err != 0 )
    1351             :     {
    1352           0 :         U8_LOG_ERROR( "output buffer exceeded." );
    1353             :     }
    1354             : 
    1355           2 :     U8_TRACE_END_ERR(out_err);
    1356           2 :     return out_err;
    1357             : }
    1358             : 
    1359             : 
    1360             : /*
    1361             : Copyright 2016-2025 Andreas Warnke
    1362             : 
    1363             : Licensed under the Apache License, Version 2.0 (the "License");
    1364             : you may not use this file except in compliance with the License.
    1365             : You may obtain a copy of the License at
    1366             : 
    1367             :     http://www.apache.org/licenses/LICENSE-2.0
    1368             : 
    1369             : Unless required by applicable law or agreed to in writing, software
    1370             : distributed under the License is distributed on an "AS IS" BASIS,
    1371             : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    1372             : See the License for the specific language governing permissions and
    1373             : limitations under the License.
    1374             : */

Generated by: LCOV version 1.16