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