LCOV - code coverage report
Current view: top level - u8stream/include/utf8stream - utf8stream_writer.inl (source / functions) Hit Total Coverage
Test: crystal-facet-uml_v1.61.0_covts Lines: 66 66 100.0 %
Date: 2024-10-26 21:44:38 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         191 : static inline void utf8stream_writer_init ( utf8stream_writer_t *this_, universal_output_stream_t* out_stream )
       9             : {
      10         191 :     assert( out_stream != NULL );
      11         191 :     (*this_).output_stream = out_stream;
      12         191 :     (*this_).buf_fill = 0;
      13         191 : }
      14             : 
      15         191 : static inline u8_error_t utf8stream_writer_destroy ( utf8stream_writer_t *this_ )
      16             : {
      17         191 :     assert( (*this_).output_stream != NULL );
      18             : 
      19         191 :     const u8_error_t err = utf8stream_writer_flush( this_ );
      20         191 :     (*this_).output_stream = NULL;
      21             : 
      22         191 :     return err;
      23             : }
      24             : 
      25       54672 : static inline u8_error_t utf8stream_writer_write_str ( utf8stream_writer_t *this_, const void *utf8_string )
      26             : {
      27       54672 :     assert( (*this_).output_stream != NULL );
      28       54672 :     assert( utf8_string != NULL );
      29             : 
      30       54672 :     utf8stringview_t view = UTF8STRINGVIEW_STR( utf8_string );
      31       54672 :     const u8_error_t err = utf8stream_writer_write_view( this_, &view );
      32             : 
      33       54672 :     return err;
      34             : }
      35             : 
      36        9846 : static inline u8_error_t utf8stream_writer_write_int ( utf8stream_writer_t *this_, const int64_t number )
      37             : {
      38        9846 :     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        9846 :     sprintf( number_str, "%" PRIi64, number );
      43             : 
      44        9846 :     utf8stringview_t view = UTF8STRINGVIEW_STR( number_str );
      45        9846 :     const u8_error_t err = utf8stream_writer_write_view( this_, &view );
      46             : 
      47        9846 :     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       68413 : static inline u8_error_t utf8stream_writer_write_view ( utf8stream_writer_t *this_, const utf8stringview_t *utf8_view )
      80             : {
      81       68413 :     assert( (*this_).output_stream != NULL );
      82       68413 :     assert( (*this_).buf_fill <= sizeof( (*this_).buffer ) );
      83             :     assert( UTF8STREAM_WRITER_MAX_BUF == sizeof( (*this_).buffer ) );
      84       68413 :     assert( utf8_view != NULL );
      85       68413 :     const char *start = utf8stringview_get_start( utf8_view );
      86       68413 :     const size_t length = utf8stringview_get_length( utf8_view );
      87       68413 :     u8_error_t err = U8_ERROR_NONE;
      88             : 
      89             :     /* is there buffer free? */
      90       68413 :     if ( length <= ((size_t)UTF8STREAM_WRITER_MAX_BUF) - (*this_).buf_fill )  /* all possible constants are on the right side for compiler optimizations */
      91             :     {
      92             :         /* store to buffer */
      93             : #if __GNUC__ >= 8
      94             : #pragma GCC diagnostic push
      95             : #pragma GCC diagnostic ignored "-Warray-bounds"
      96             : #endif
      97       65588 :         memcpy( &((*this_).buffer[(*this_).buf_fill]), start, length );
      98             : #if __GNUC__ >= 8
      99             : #pragma GCC diagnostic pop
     100             : #endif
     101       65588 :         (*this_).buf_fill += length;
     102             :     }
     103             :     else
     104             :     {
     105             :         /* flush the buffer */
     106        2825 :         if ( (*this_).buf_fill > 0 )
     107             :         {
     108         450 :             err |= universal_output_stream_write( (*this_).output_stream, &((*this_).buffer), (*this_).buf_fill );
     109         450 :             (*this_).buf_fill = 0;
     110             :         }
     111             : 
     112             :         /* is there enough buffer free now? */
     113        2825 :         if ( length < UTF8STREAM_WRITER_MAX_BUF )
     114             :         {
     115             :             /* store to buffer */
     116         357 :             memcpy( &((*this_).buffer), start, length );
     117         357 :             (*this_).buf_fill = length;
     118             :         }
     119             :         else
     120             :         {
     121             :             /* write immediate */
     122        2468 :             err |= universal_output_stream_write( (*this_).output_stream, start, length );
     123             :         }
     124             :     }
     125             : 
     126       68413 :     return err;
     127             : }
     128             : 
     129       21172 : static inline u8_error_t utf8stream_writer_flush ( utf8stream_writer_t *this_ )
     130             : {
     131       21172 :     U8_TRACE_BEGIN();
     132       21172 :     assert( (*this_).output_stream != NULL );
     133       21172 :     assert( (*this_).buf_fill <= sizeof( (*this_).buffer ) );
     134       21172 :     u8_error_t err = U8_ERROR_NONE;
     135             : 
     136       21172 :     if ( (*this_).buf_fill > 0 )
     137             :     {
     138       18523 :         err |= universal_output_stream_write( (*this_).output_stream, &((*this_).buffer), (*this_).buf_fill );
     139       18523 :         (*this_).buf_fill = 0;
     140             :     }
     141             : 
     142       21172 :     err |= universal_output_stream_flush( (*this_).output_stream );
     143             : 
     144       21172 :     U8_TRACE_END_ERR( err );
     145       21172 :     return err;
     146             : }
     147             : 
     148             : 
     149             : /*
     150             : Copyright 2021-2024 Andreas Warnke
     151             : 
     152             : Licensed under the Apache License, Version 2.0 (the "License");
     153             : you may not use this file except in compliance with the License.
     154             : You may obtain a copy of the License at
     155             : 
     156             :     http://www.apache.org/licenses/LICENSE-2.0
     157             : 
     158             : Unless required by applicable law or agreed to in writing, software
     159             : distributed under the License is distributed on an "AS IS" BASIS,
     160             : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     161             : See the License for the specific language governing permissions and
     162             : limitations under the License.
     163             : */

Generated by: LCOV version 1.16