LCOV - code coverage report
Current view: top level - u8stream/source/u8stream - universal_buffer_output_stream.c (source / functions) Coverage Total Hit
Test: crystal-facet-uml_v1.70.2_covts Lines: 100.0 % 59 59
Test Date: 2026-05-03 11:56:31 Functions: 100.0 % 5 5

            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-2026 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 2.0-1