LCOV - code coverage report
Current view: top level - u8stream/include/utf8stream - utf8stream_writer.inl (source / functions) Hit Total Coverage
Test: crystal-facet-uml_v1.57.0_covts Lines: 64 64 100.0 %
Date: 2024-04-07 11:14:42 Functions: 8 8 100.0 %

          Line data    Source code
       1             : /* File: utf8stream_writer.c; Copyright and License: see below */
       2             : 
       3             : #include "u8/u8_trace.h"
       4             : #include <string.h>
       5             : #include <inttypes.h>
       6             : #include <assert.h>
       7             : 
       8         429 : static inline void utf8stream_writer_init ( utf8stream_writer_t *this_, universal_output_stream_t* out_stream )
       9             : {
      10         429 :     assert( out_stream != NULL );
      11         429 :     (*this_).output_stream = out_stream;
      12         429 :     (*this_).buf_fill = 0;
      13         429 : }
      14             : 
      15         429 : static inline u8_error_t utf8stream_writer_destroy ( utf8stream_writer_t *this_ )
      16             : {
      17         429 :     assert( (*this_).output_stream != NULL );
      18             : 
      19         429 :     const u8_error_t err = utf8stream_writer_flush( this_ );
      20         429 :     (*this_).output_stream = NULL;
      21             : 
      22         429 :     return err;
      23             : }
      24             : 
      25       11645 : static inline u8_error_t utf8stream_writer_write_str ( utf8stream_writer_t *this_, const void *utf8_string )
      26             : {
      27       11645 :     assert( (*this_).output_stream != NULL );
      28       11645 :     assert( utf8_string != NULL );
      29             : 
      30       11645 :     utf8stringview_t view = UTF8STRINGVIEW_STR( utf8_string );
      31       11645 :     const u8_error_t err = utf8stream_writer_write_view( this_, &view );
      32             : 
      33       11645 :     return err;
      34             : }
      35             : 
      36        2742 : static inline u8_error_t utf8stream_writer_write_int ( utf8stream_writer_t *this_, const int64_t number )
      37             : {
      38        2742 :     assert( (*this_).output_stream != NULL );
      39             : 
      40             :     char number_str[21]; /* this is sufficient for signed 64 bit integers: -9223372036854775806 */
      41             :     /* Note: snprintf is not available on every OS */
      42        2742 :     sprintf( number_str, "%" PRIi64, number );
      43             : 
      44        2742 :     utf8stringview_t view = UTF8STRINGVIEW_STR( number_str );
      45        2742 :     const u8_error_t err = utf8stream_writer_write_view( this_, &view );
      46             : 
      47        2742 :     return err;
      48             : }
      49             : 
      50           1 : static inline u8_error_t utf8stream_writer_write_hex ( utf8stream_writer_t *this_, const int64_t number )
      51             : {
      52           1 :     assert( (*this_).output_stream != NULL );
      53             : 
      54             :     char number_str[17]; /* this is sufficient for 64 bit integers */
      55             :     /* Note: snprintf is not available on every OS */
      56           1 :     sprintf( number_str, "%" PRIx64, number );
      57             : 
      58           1 :     utf8stringview_t view = UTF8STRINGVIEW_STR( number_str );
      59           1 :     const u8_error_t err = utf8stream_writer_write_view( this_, &view );
      60             : 
      61           1 :     return err;
      62             : }
      63             : 
      64        3841 : static inline utf8error_t utf8stream_writer_write_char( utf8stream_writer_t *this_, const uint32_t codepoint )
      65             : {
      66        3841 :     assert( (*this_).output_stream != NULL );
      67             : 
      68        3841 :     const utf8codepoint_t cp = utf8codepoint( codepoint );
      69        3841 :     const utf8codepointseq_t mem_buf = utf8codepoint_get_utf8( cp );
      70        3841 :     const unsigned int mem_len = utf8codepoint_get_length( cp );
      71        3841 :     assert( mem_len <= sizeof(utf8codepointseq_t) );
      72             : 
      73        3841 :     utf8stringview_t view = UTF8STRINGVIEW( (const char*) &mem_buf, mem_len );
      74        3841 :     const u8_error_t err = utf8stream_writer_write_view( this_, &view );
      75             : 
      76        3841 :     return err;
      77             : }
      78             : 
      79       18282 : static inline u8_error_t utf8stream_writer_write_view ( utf8stream_writer_t *this_, const utf8stringview_t *utf8_view )
      80             : {
      81       18282 :     assert( (*this_).output_stream != NULL );
      82       18282 :     assert( (*this_).buf_fill <= sizeof( (*this_).buffer ) );
      83             :     assert( UTF8STREAM_WRITER_MAX_BUF == sizeof( (*this_).buffer ) );
      84       18282 :     assert( utf8_view != NULL );
      85       18282 :     const char *start = utf8stringview_get_start( utf8_view );
      86       18282 :     const size_t length = utf8stringview_get_length( utf8_view );
      87       18282 :     u8_error_t err = U8_ERROR_NONE;
      88             : 
      89             :     /* is there buffer free? */
      90       18282 :     if ( length <= UTF8STREAM_WRITER_MAX_BUF - (*this_).buf_fill )  /* all possible constants are on the right side for compiler optimizations */
      91             :     {
      92             :         /* store to buffer */
      93       17346 :         memcpy( &((*this_).buffer[(*this_).buf_fill]), start, length );
      94       17346 :         (*this_).buf_fill += length;
      95             :     }
      96             :     else
      97             :     {
      98             :         /* flush the buffer */
      99         936 :         if ( (*this_).buf_fill > 0 )
     100             :         {
     101         450 :             err |= universal_output_stream_write( (*this_).output_stream, &((*this_).buffer), (*this_).buf_fill );
     102         450 :             (*this_).buf_fill = 0;
     103             :         }
     104             : 
     105             :         /* is there enough buffer free now? */
     106         936 :         if ( length < UTF8STREAM_WRITER_MAX_BUF )
     107             :         {
     108             :             /* store to buffer */
     109         357 :             memcpy( &((*this_).buffer), start, length );
     110         357 :             (*this_).buf_fill = length;
     111             :         }
     112             :         else
     113             :         {
     114             :             /* write immediate */
     115         579 :             err |= universal_output_stream_write( (*this_).output_stream, start, length );
     116             :         }
     117             :     }
     118             : 
     119       18282 :     return err;
     120             : }
     121             : 
     122        4944 : static inline u8_error_t utf8stream_writer_flush ( utf8stream_writer_t *this_ )
     123             : {
     124        4944 :     assert( (*this_).output_stream != NULL );
     125        4944 :     assert( (*this_).buf_fill <= sizeof( (*this_).buffer ) );
     126        4944 :     u8_error_t err = U8_ERROR_NONE;
     127             : 
     128        4944 :     if ( (*this_).buf_fill > 0 )
     129             :     {
     130        4071 :         err |= universal_output_stream_write( (*this_).output_stream, &((*this_).buffer), (*this_).buf_fill );
     131        4071 :         (*this_).buf_fill = 0;
     132             :     }
     133             : 
     134        4944 :     err |= universal_output_stream_flush( (*this_).output_stream );
     135             : 
     136        4944 :     return err;
     137             : }
     138             : 
     139             : 
     140             : /*
     141             : Copyright 2021-2024 Andreas Warnke
     142             : 
     143             : Licensed under the Apache License, Version 2.0 (the "License");
     144             : you may not use this file except in compliance with the License.
     145             : You may obtain a copy of the License at
     146             : 
     147             :     http://www.apache.org/licenses/LICENSE-2.0
     148             : 
     149             : Unless required by applicable law or agreed to in writing, software
     150             : distributed under the License is distributed on an "AS IS" BASIS,
     151             : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     152             : See the License for the specific language governing permissions and
     153             : limitations under the License.
     154             : */

Generated by: LCOV version 1.16