Line data Source code
1 : /* File: universal_memory_output_stream.inl; Copyright and License: see below */
2 :
3 : #include "utf8stringbuf/utf8stringview.h"
4 : #include <assert.h>
5 :
6 262 : static inline void* universal_memory_output_stream_get_start( const universal_memory_output_stream_t *this_ )
7 : {
8 262 : assert( (*this_).mem_buf_start != NULL );
9 262 : return (*this_).mem_buf_start;
10 : }
11 :
12 : static inline size_t universal_memory_output_stream_get_size( const universal_memory_output_stream_t *this_ )
13 : {
14 : return (*this_).mem_buf_size;
15 : }
16 :
17 256 : static inline size_t universal_memory_output_stream_get_fill( const universal_memory_output_stream_t *this_ )
18 : {
19 256 : assert( (*this_).mem_buf_filled <= (*this_).mem_buf_size );
20 256 : return (*this_).mem_buf_filled;
21 : }
22 :
23 15304 : static inline u8_error_t universal_memory_output_stream_private_write_0term ( universal_memory_output_stream_t *this_, bool utf8_mode )
24 : {
25 15304 : U8_TRACE_BEGIN();
26 15304 : assert( (*this_).mem_buf_start != NULL );
27 15304 : u8_error_t err = U8_ERROR_NONE;
28 :
29 15304 : if ( (*this_).mem_buf_size == 0 )
30 : {
31 1 : U8_LOG_ERROR( "buffer size is 0; buffer is not terminated by zero." );
32 1 : err = U8_ERROR_CONFIG_OUT_OF_RANGE;
33 : }
34 15303 : else if ( (*this_).mem_buf_filled < (*this_).mem_buf_size )
35 : {
36 : /* add a terminating zero at position (*this_).mem_buf_filled, */
37 : /* but do not increase the mem_buf_filled because more bytes may be written ... */
38 15243 : char *const term_char = &( (*( (char(*)[])(*this_).mem_buf_start ))[(*this_).mem_buf_filled] );
39 15243 : *term_char = '\0';
40 : }
41 : else
42 : {
43 60 : if ( utf8_mode )
44 : {
45 : /* use a utf8stringview_t to determine the end-position of the last full unicode codepoint: */
46 : utf8stringview_t view_on_buf;
47 59 : const utf8error_t cut = utf8stringview_init( &view_on_buf, (*this_).mem_buf_start, (*this_).mem_buf_size-1 );
48 59 : char *const last_char
49 59 : = &( (*( (char(*)[])utf8stringview_get_start(&view_on_buf) ))[utf8stringview_get_length(&view_on_buf)] );
50 59 : *last_char = '\0';
51 59 : utf8stringview_destroy( &view_on_buf );
52 59 : if ( cut == UTF8ERROR_SUCCESS )
53 : {
54 58 : U8_TRACE_INFO( "last byte overwritten by terminating zero" );
55 : /* prevent errors on consecutive calls to flush (e.g. at a reset to utf8stream_writer): */
56 58 : (*this_).mem_buf_filled = (*this_).mem_buf_size - 1;
57 : }
58 : else
59 : {
60 1 : U8_TRACE_INFO( "multiple last bytes dropped by terminating zero" );
61 : /* prevent errors on consecutive calls to flush (-1 is not accurate here but suits the purpose): */
62 1 : (*this_).mem_buf_filled = (*this_).mem_buf_size - 1;
63 : }
64 : }
65 : else
66 : {
67 1 : char *const last_char = &( (*( (char(*)[])(*this_).mem_buf_start ))[(*this_).mem_buf_size - 1] );
68 1 : *last_char = '\0';
69 1 : U8_TRACE_INFO( "last byte overwritten by terminating zero" );
70 : /* prevent errors on consecutive calls to flush: */
71 1 : (*this_).mem_buf_filled = (*this_).mem_buf_size - 1;
72 : }
73 60 : err = U8_ERROR_AT_FILE_WRITE;
74 : }
75 :
76 :
77 15304 : U8_TRACE_END_ERR(err);
78 15304 : return err;
79 : }
80 :
81 :
82 : /*
83 : Copyright 2024-2025 Andreas Warnke
84 :
85 : Licensed under the Apache License, Version 2.0 (the "License");
86 : you may not use this file except in compliance with the License.
87 : You may obtain a copy of the License at
88 :
89 : http://www.apache.org/licenses/LICENSE-2.0
90 :
91 : Unless required by applicable law or agreed to in writing, software
92 : distributed under the License is distributed on an "AS IS" BASIS,
93 : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
94 : See the License for the specific language governing permissions and
95 : limitations under the License.
96 : */
|