Line data Source code
1 : /* File: universal_stream_output_stream.c; Copyright and License: see below */
2 :
3 : #include "u8stream/universal_stream_output_stream.h"
4 : #include "u8stream/universal_output_stream_if.h"
5 : #include "u8_test_cond.h"
6 : #include "u8/u8_fault_inject.h"
7 : #include "u8/u8_trace.h"
8 : #include "u8/u8_log.h"
9 : #include <stdbool.h>
10 : #include <assert.h>
11 :
12 : /* the vmt implementing the interface */
13 : static const universal_output_stream_if_t universal_stream_output_stream_private_if
14 : = {
15 : .write = (u8_error_t (*)(universal_output_stream_impl_t*, const void*, size_t)) &universal_stream_output_stream_write,
16 : .flush = (u8_error_t (*)(universal_output_stream_impl_t*)) &universal_stream_output_stream_flush
17 : };
18 :
19 12 : void universal_stream_output_stream_init( universal_stream_output_stream_t *this_, FILE* out_stream )
20 : {
21 12 : U8_TRACE_BEGIN();
22 12 : assert( out_stream != NULL );
23 :
24 12 : (*this_).output = out_stream;
25 12 : universal_output_stream_private_init( &((*this_).output_stream), &universal_stream_output_stream_private_if, this_ );
26 :
27 12 : U8_TRACE_END();
28 12 : }
29 :
30 12 : void universal_stream_output_stream_destroy( universal_stream_output_stream_t *this_ )
31 : {
32 12 : U8_TRACE_BEGIN();
33 :
34 12 : (*this_).output = NULL;
35 12 : universal_output_stream_private_destroy( &((*this_).output_stream) );
36 :
37 12 : U8_TRACE_END();
38 12 : }
39 :
40 567 : u8_error_t universal_stream_output_stream_write ( universal_stream_output_stream_t *this_, const void *start, size_t length )
41 : {
42 : /*U8_TRACE_BEGIN();*/
43 567 : assert( (*this_).output != NULL );
44 567 : u8_error_t err = U8_ERROR_NONE;
45 :
46 567 : size_t written = 0;
47 1134 : while (( written < length )&&( err == U8_ERROR_NONE ))
48 : {
49 567 : const size_t remaining = length - written;
50 : size_t out_count;
51 567 : out_count = fwrite( ((const char*)start)+written, 1, remaining, (*this_).output );
52 567 : assert( out_count != 0 ); /* this should not happen, but do not take this for granted */
53 567 : U8_FAULT_INJECT_COND_SET( U8_TEST_COND_FWRITE, out_count, 0 );
54 567 : if ( out_count == 0 )
55 : {
56 1 : U8_LOG_ERROR_INT( "not all bytes could be written. missing:", remaining );
57 1 : err = U8_ERROR_AT_FILE_WRITE;
58 : }
59 : else
60 : {
61 566 : written += out_count;
62 : }
63 : }
64 :
65 : /*U8_TRACE_END_ERR(err);*/
66 567 : return err;
67 : }
68 :
69 42 : u8_error_t universal_stream_output_stream_flush( universal_stream_output_stream_t *this_ )
70 : {
71 42 : U8_TRACE_BEGIN();
72 42 : assert( (*this_).output != NULL );
73 42 : u8_error_t err = U8_ERROR_NONE;
74 :
75 42 : int flush_err = fflush( (*this_).output );
76 42 : assert( flush_err == 0 ); /* this should not happen, but do not take this for granted */
77 42 : U8_FAULT_INJECT_COND_SET( U8_TEST_COND_FFLUSH, flush_err, EOF );
78 42 : if ( 0 != flush_err )
79 : {
80 1 : U8_LOG_ERROR_INT("error at flushing file:",flush_err);
81 1 : err = U8_ERROR_AT_FILE_WRITE;
82 : }
83 :
84 42 : U8_TRACE_END_ERR(err);
85 42 : return err;
86 : }
87 :
88 11 : universal_output_stream_t* universal_stream_output_stream_get_output_stream( universal_stream_output_stream_t *this_ )
89 : {
90 11 : U8_TRACE_BEGIN();
91 :
92 11 : universal_output_stream_t* result = &((*this_).output_stream);
93 :
94 11 : U8_TRACE_END();
95 11 : return result;
96 : }
97 :
98 :
99 : /*
100 : Copyright 2021-2025 Andreas Warnke
101 :
102 : Licensed under the Apache License, Version 2.0 (the "License");
103 : you may not use this file except in compliance with the License.
104 : You may obtain a copy of the License at
105 :
106 : http://www.apache.org/licenses/LICENSE-2.0
107 :
108 : Unless required by applicable law or agreed to in writing, software
109 : distributed under the License is distributed on an "AS IS" BASIS,
110 : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
111 : See the License for the specific language governing permissions and
112 : limitations under the License.
113 : */
|