Line data Source code
1 : /* File: io_txt_writer.c; Copyright and License: see below */ 2 : 3 : #include "format/io_txt_writer.h" 4 : #include "utf8stringbuf/utf8stringlines.h" 5 : #include "u8/u8_trace.h" 6 : #include "u8/u8_log.h" 7 : #include <stdio.h> 8 : #include <stdbool.h> 9 : #include <assert.h> 10 : 11 : enum io_txt_writer_indent_enum { 12 : TXT_WRITER_INDENT_COLUMN = 80, /*!< the text column in which the id shal end */ 13 : TXT_WRITER_MAX_COLUMN = 80, /*!< the number of max columns the text shall be layouted - if possible */ 14 : }; 15 : 16 : static const char TXT_ID_INDENT_SPACES[TXT_WRITER_INDENT_COLUMN+1] 17 : = " "; 18 : static const char TXT_NEWLINE[] = "\n"; 19 : 20 7 : void io_txt_writer_init ( io_txt_writer_t *this_, 21 : universal_output_stream_t *output ) 22 : { 23 7 : U8_TRACE_BEGIN(); 24 7 : assert( NULL != output ); 25 : 26 7 : (*this_).output = output; 27 : 28 7 : U8_TRACE_END(); 29 7 : } 30 : 31 7 : void io_txt_writer_destroy( io_txt_writer_t *this_ ) 32 : { 33 7 : U8_TRACE_BEGIN(); 34 : 35 7 : (*this_).output = NULL; 36 : 37 7 : U8_TRACE_END(); 38 7 : } 39 : 40 7 : u8_error_t io_txt_writer_write_indent_multiline_string ( io_txt_writer_t *this_, 41 : const char *indent, 42 : const char *multiline_string ) 43 : { 44 7 : U8_TRACE_BEGIN(); 45 7 : assert( NULL != indent ); 46 7 : assert( NULL != (*this_).output ); 47 7 : u8_error_t result = U8_ERROR_NONE; 48 : utf8stringview_t indent_view; 49 7 : utf8stringview_init_str( &indent_view, indent ); 50 : 51 7 : if ( NULL != multiline_string ) 52 : { 53 : utf8stringview_t line_list; 54 6 : utf8stringview_init_str( &line_list, multiline_string ); 55 : utf8stringlines_t line_iter; 56 6 : utf8stringlines_init( &line_iter, 57 : &line_list, 58 6 : TXT_WRITER_MAX_COLUMN - utf8stringview_get_length( &indent_view ) /*line_length*/ 59 : ); 60 : 61 17 : while ( utf8stringlines_has_next( &line_iter ) ) 62 : { 63 11 : utf8stringview_t line = utf8stringlines_next( &line_iter ); 64 11 : const bool is_empty_last_line 65 11 : = ( ! utf8stringlines_has_next( &line_iter ) )&&( 0 == utf8stringview_get_length( &line ) ); 66 11 : if ( ! is_empty_last_line ) 67 : { 68 : /* print indent pattern */ 69 8 : result |= universal_output_stream_write( (*this_).output, 70 8 : utf8stringview_get_start( &indent_view ), 71 : utf8stringview_get_length( &indent_view ) 72 : ); 73 : 74 : /* print next line */ 75 8 : result |= universal_output_stream_write( (*this_).output, 76 8 : utf8stringview_get_start( &line ), 77 : utf8stringview_get_length( &line ) 78 : ); 79 : 80 8 : if ( ! utf8stringview_ends_with_str( &line, TXT_NEWLINE ) ) 81 : { 82 : /* print newline */ 83 4 : result |= universal_output_stream_write( (*this_).output, TXT_NEWLINE, strlen(TXT_NEWLINE) ); 84 : } 85 : } 86 : } 87 6 : utf8stringlines_destroy( &line_iter ); 88 6 : utf8stringview_destroy( &line_list ); 89 : } 90 : 91 7 : utf8stringview_destroy( &indent_view ); 92 : 93 7 : U8_TRACE_END_ERR( result ); 94 7 : return result; 95 : } 96 : 97 0 : u8_error_t io_txt_writer_write_aligned_id ( io_txt_writer_t *this_, int right_align_to, data_id_t id ) 98 : { 99 0 : U8_TRACE_BEGIN(); 100 0 : assert( DATA_TABLE_VOID != data_id_get_table(&id) ); 101 0 : assert( DATA_ROW_VOID != data_id_get_row_id(&id) ); 102 0 : assert( NULL != (*this_).output ); 103 : assert( sizeof(TXT_ID_INDENT_SPACES) == 1+TXT_WRITER_INDENT_COLUMN ); 104 0 : u8_error_t result = U8_ERROR_NONE; 105 : 106 : /* indent */ 107 0 : if ( right_align_to > TXT_WRITER_INDENT_COLUMN ) 108 : { 109 0 : U8_LOG_ERROR_INT( "more spaces requested than available. missing:", right_align_to - TXT_WRITER_INDENT_COLUMN ); 110 0 : right_align_to = TXT_WRITER_INDENT_COLUMN; 111 : } 112 : 113 : /* print id */ 114 : { 115 : char id_buf[DATA_ID_MAX_UTF8STRING_SIZE+2]; 116 0 : utf8stringbuf_t id_str = UTF8STRINGBUF( id_buf ); 117 0 : utf8stringbuf_clear( &id_str ); 118 0 : utf8stringbuf_append_str( &id_str, "[" ); 119 0 : data_id_to_utf8stringbuf( &id, id_str ); 120 0 : utf8stringbuf_append_str( &id_str, "]" ); 121 0 : const unsigned int len = utf8stringbuf_get_length( &id_str ); 122 : 123 : /* do indentation: */ 124 0 : int remaining_indent = right_align_to - len; 125 0 : if ( remaining_indent > 0 ) 126 : { 127 0 : result |= universal_output_stream_write( (*this_).output, &TXT_ID_INDENT_SPACES, remaining_indent ); 128 : } 129 : 130 0 : result |= universal_output_stream_write( (*this_).output, utf8stringbuf_get_string( &id_str ), len ); 131 : } 132 : 133 0 : U8_TRACE_END_ERR( result ); 134 0 : return result; 135 : } 136 : 137 0 : u8_error_t io_txt_writer_write_plain_id ( io_txt_writer_t *this_, data_id_t id ) 138 : { 139 0 : U8_TRACE_BEGIN(); 140 0 : assert( DATA_TABLE_VOID != data_id_get_table(&id) ); 141 0 : assert( DATA_ROW_VOID != data_id_get_row_id(&id) ); 142 0 : assert( NULL != (*this_).output ); 143 0 : u8_error_t result = U8_ERROR_NONE; 144 : 145 : /* print id */ 146 : { 147 : char id_buf[DATA_ID_MAX_UTF8STRING_SIZE]; 148 0 : utf8stringbuf_t id_str = UTF8STRINGBUF( id_buf ); 149 0 : utf8stringbuf_clear( &id_str ); 150 0 : data_id_to_utf8stringbuf( &id, id_str ); 151 : 152 0 : const unsigned int len = utf8stringbuf_get_length( &id_str ); 153 0 : result |= universal_output_stream_write ( (*this_).output, utf8stringbuf_get_string( &id_str ), len ); 154 : } 155 : 156 0 : U8_TRACE_END_ERR( result ); 157 0 : return result; 158 : } 159 : 160 : 161 : /* 162 : Copyright 2017-2025 Andreas Warnke 163 : 164 : Licensed under the Apache License, Version 2.0 (the "License"); 165 : you may not use this file except in compliance with the License. 166 : You may obtain a copy of the License at 167 : 168 : http://www.apache.org/licenses/LICENSE-2.0 169 : 170 : Unless required by applicable law or agreed to in writing, software 171 : distributed under the License is distributed on an "AS IS" BASIS, 172 : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 173 : See the License for the specific language governing permissions and 174 : limitations under the License. 175 : */