LCOV - code coverage report
Current view: top level - u8stream/source/u8stream - universal_buffer_output_stream.c (source / functions) Hit Total Coverage
Test: crystal-facet-uml_v1.57.0_covts Lines: 59 59 100.0 %
Date: 2024-04-07 11:14:42 Functions: 5 5 100.0 %

          Line data    Source code
       1             : /* File: universal_buffer_output_stream.c; Copyright and License: see below */
       2             : 
       3             : #include "u8stream/universal_buffer_output_stream.h"
       4             : #include "u8stream/universal_output_stream_if.h"
       5             : #include "u8/u8_trace.h"
       6             : #include "u8/u8_log.h"
       7             : #include <string.h>
       8             : #include <assert.h>
       9             : 
      10             : /* the vmt implementing the interface */
      11             : static const universal_output_stream_if_t universal_buffer_output_stream_private_if
      12             :     = {
      13             :         .write = (u8_error_t (*)(universal_output_stream_impl_t*, const void*, size_t)) &universal_buffer_output_stream_write,
      14             :         .flush = (u8_error_t (*)(universal_output_stream_impl_t*)) &universal_buffer_output_stream_flush
      15             :     };
      16             : 
      17           2 : void universal_buffer_output_stream_init( universal_buffer_output_stream_t *this_,
      18             :                                           void* mem_buf_start,
      19             :                                           size_t mem_buf_size,
      20             :                                           universal_output_stream_t *sink )
      21             : {
      22           2 :     U8_TRACE_BEGIN();
      23           2 :     assert( mem_buf_start != NULL );
      24           2 :     assert( sink != NULL );
      25             : 
      26           2 :     (*this_).sink = sink;
      27             : 
      28           2 :     (*this_).mem_buf_start = mem_buf_start;
      29           2 :     (*this_).mem_buf_size = mem_buf_size;
      30           2 :     (*this_).mem_buf_filled = 0;
      31           2 :     universal_output_stream_private_init( &((*this_).output_stream), &universal_buffer_output_stream_private_if, this_ );
      32             : 
      33           2 :     U8_TRACE_END();
      34           2 : }
      35             : 
      36           2 : u8_error_t universal_buffer_output_stream_destroy( universal_buffer_output_stream_t *this_ )
      37             : {
      38           2 :     U8_TRACE_BEGIN();
      39           2 :     assert( (*this_).mem_buf_start != NULL );
      40           2 :     assert( (*this_).sink != NULL );
      41           2 :     u8_error_t err = U8_ERROR_NONE;
      42             : 
      43           2 :     err = universal_buffer_output_stream_flush( this_ );
      44             : 
      45           2 :     (*this_).mem_buf_start = NULL;
      46           2 :     (*this_).mem_buf_size = 0;
      47           2 :     (*this_).mem_buf_filled = 0;
      48           2 :     universal_output_stream_private_destroy( &((*this_).output_stream) );
      49             : 
      50           2 :     (*this_).sink = NULL;
      51             : 
      52           2 :     U8_TRACE_END_ERR(err);
      53           2 :     return err;
      54             : }
      55             : 
      56           7 : u8_error_t universal_buffer_output_stream_write ( universal_buffer_output_stream_t *this_, const void *start, size_t length )
      57             : {
      58             :     /*U8_TRACE_BEGIN();*/
      59           7 :     assert( start != NULL );
      60           7 :     assert( (*this_).mem_buf_start != NULL );
      61           7 :     assert( (*this_).sink != NULL );
      62           7 :     u8_error_t err = U8_ERROR_NONE;
      63             : 
      64           7 :     const size_t space_left = (*this_).mem_buf_size - (*this_).mem_buf_filled;
      65           7 :     char *const buf_first_free = &(  (*(  (char(*)[])(*this_).mem_buf_start  ))[(*this_).mem_buf_filled]  );
      66           7 :     if ( length <= space_left )
      67             :     {
      68             :         /* append all to buffer */
      69           3 :         memcpy( buf_first_free, start, length );
      70           3 :         (*this_).mem_buf_filled += length;
      71             :     }
      72             :     else
      73             :     {
      74             :         /* append to buffer till buffer is full */
      75           4 :         memcpy( buf_first_free, start, space_left );
      76           4 :         (*this_).mem_buf_filled += space_left;
      77           4 :         const size_t remaining_len = length - space_left;
      78           4 :         const void *remaining_start = &(  (*(  (char(*)[])start  ))[space_left]  );
      79             : 
      80           4 :         err |= universal_buffer_output_stream_flush( this_ );
      81             : 
      82           4 :         if ( remaining_len <= (*this_).mem_buf_size )
      83             :         {
      84           3 :             memcpy( (*this_).mem_buf_start , remaining_start, remaining_len );
      85           3 :             (*this_).mem_buf_filled = remaining_len;
      86             :         }
      87             :         else
      88             :         {
      89           1 :             err |= universal_output_stream_write( (*this_).sink, remaining_start, remaining_len );
      90             :         }
      91             :     }
      92             : 
      93             :     /*U8_TRACE_END_ERR(err);*/
      94           7 :     return err;
      95             : }
      96             : 
      97           7 : u8_error_t universal_buffer_output_stream_flush( universal_buffer_output_stream_t *this_ )
      98             : {
      99           7 :     U8_TRACE_BEGIN();
     100           7 :     assert( (*this_).mem_buf_start != NULL );
     101           7 :     assert( (*this_).sink != NULL );
     102           7 :     u8_error_t err = U8_ERROR_NONE;
     103             : 
     104           7 :     if ( (*this_).mem_buf_filled > 0 )
     105             :     {
     106           7 :         err |= universal_output_stream_write( (*this_).sink, (*this_).mem_buf_start, (*this_).mem_buf_filled );
     107             :     }
     108           7 :     (*this_).mem_buf_filled = 0;
     109             : 
     110           7 :     U8_TRACE_END_ERR(err);
     111           7 :     return err;
     112             : }
     113             : 
     114           2 : universal_output_stream_t* universal_buffer_output_stream_get_output_stream( universal_buffer_output_stream_t *this_ )
     115             : {
     116           2 :     U8_TRACE_BEGIN();
     117             : 
     118           2 :     universal_output_stream_t* result = &((*this_).output_stream);
     119             : 
     120           2 :     U8_TRACE_END();
     121           2 :     return result;
     122             : }
     123             : 
     124             : 
     125             : /*
     126             : Copyright 2021-2024 Andreas Warnke
     127             : 
     128             : Licensed under the Apache License, Version 2.0 (the "License");
     129             : you may not use this file except in compliance with the License.
     130             : You may obtain a copy of the License at
     131             : 
     132             :     http://www.apache.org/licenses/LICENSE-2.0
     133             : 
     134             : Unless required by applicable law or agreed to in writing, software
     135             : distributed under the License is distributed on an "AS IS" BASIS,
     136             : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     137             : See the License for the specific language governing permissions and
     138             : limitations under the License.
     139             : */

Generated by: LCOV version 1.16