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 : out_count = U8_FAULT_INJECT_COND( U8_TEST_COND_FWRITE, 0, out_count ); 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 : flush_err = U8_FAULT_INJECT_COND( U8_TEST_COND_FFLUSH, EOF, flush_err ); 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-2024 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 : */