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_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_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-2025 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 : */
|