LCOV - code coverage report
Current view: top level - io/include/json - json_token_reader.inl (source / functions) Coverage Total Hit
Test: crystal-facet-uml_v1.63.2_covts Lines: 95.4 % 109 104
Test Date: 2025-05-01 10:10:14 Functions: 100.0 % 7 7

            Line data    Source code
       1              : /* File: json_token_reader.inl; Copyright and License: see below */
       2              : 
       3              : #include "json/json_constants.h"
       4              : #include "u8/u8_trace.h"
       5              : #include <assert.h>
       6              : 
       7         4342 : static inline void json_token_reader_private_skip_whitespace ( json_token_reader_t *this_ )
       8              : {
       9         4342 :     bool ws_end_reached = false;
      10         4342 :     char current = ' ';
      11        18895 :     while ( ( ! ws_end_reached ) && ( current != '\0' ) )
      12              :     {
      13        14553 :         current = universal_buffer_input_stream_peek_next( &((*this_).in_stream) );
      14        14553 :         if ( ( JSON_CONSTANTS_CHAR_NL != current )
      15        13399 :             && ( JSON_CONSTANTS_CHAR_CR != current )
      16        13394 :             && ( JSON_CONSTANTS_CHAR_TAB != current )
      17        13389 :             && ( JSON_CONSTANTS_CHAR_SPACE != current ))
      18              :         {
      19         4342 :             ws_end_reached = true;
      20              :         }
      21              :         else
      22              :         {
      23        10211 :             universal_buffer_input_stream_read_next( &((*this_).in_stream) );
      24        10211 :             if ( current == JSON_CONSTANTS_CHAR_NL )
      25              :             {
      26         1154 :                 (*this_).input_line ++;
      27              :             }
      28              :         }
      29              :     }
      30         4342 : }
      31              : 
      32           22 : static inline unsigned int json_token_reader_get_input_line ( json_token_reader_t *this_ )
      33              : {
      34           22 :     return (*this_).input_line;
      35              : }
      36              : 
      37           52 : static inline size_t json_token_reader_get_input_pos ( json_token_reader_t *this_ )
      38              : {
      39           52 :     return universal_buffer_input_stream_read_pos( &((*this_).in_stream) );
      40              : }
      41              : 
      42         1470 : static inline bool json_token_reader_private_is_value_end ( json_token_reader_t *this_ )
      43              : {
      44         1470 :     char next = universal_buffer_input_stream_peek_next( &((*this_).in_stream) );
      45              : 
      46         1470 :     const bool result = (( next == '\0' )
      47         1462 :         || ( next == JSON_CONSTANTS_CHAR_NL )
      48         1413 :         || ( next == JSON_CONSTANTS_CHAR_CR )
      49         1412 :         || ( next == JSON_CONSTANTS_CHAR_TAB )
      50         1411 :         || ( next == JSON_CONSTANTS_CHAR_SPACE )
      51         1362 :         || ( next == JSON_CONSTANTS_CHAR_BEGIN_OBJECT )
      52         1362 :         || ( next == JSON_CONSTANTS_CHAR_END_OBJECT )
      53         1361 :         || ( next == JSON_CONSTANTS_CHAR_BEGIN_ARRAY )
      54         1361 :         || ( next == JSON_CONSTANTS_CHAR_END_ARRAY )
      55         1360 :         || ( next == JSON_CONSTANTS_CHAR_NAME_SEPARATOR )
      56         2932 :         || ( next == JSON_CONSTANTS_CHAR_VALUE_SEPARATOR ));
      57              : 
      58         1470 :     return result;
      59              : }
      60              : 
      61         1149 : static inline u8_error_t json_token_reader_private_read_string ( json_token_reader_t *this_, universal_output_stream_t *out_stream )
      62              : {
      63         1149 :     assert( out_stream != NULL );
      64         1149 :     u8_error_t result = U8_ERROR_NONE;
      65         1149 :     bool str_end_reached = false;
      66         1149 :     char esc_incomplete = false;
      67              :     char out_buffer[64];
      68         1149 :     size_t ouf_buf_len = 0;
      69        14564 :     while ( ! str_end_reached )
      70              :     {
      71        13415 :         char current = universal_buffer_input_stream_peek_next( &((*this_).in_stream) );
      72        13415 :         if ( '\0' == current )
      73              :         {
      74            1 :             str_end_reached = true;
      75            1 :             result = U8_ERROR_LEXICAL_STRUCTURE;
      76              :         }
      77        13414 :         else if (( JSON_CONSTANTS_CHAR_END_STRING == current )&&( ! esc_incomplete ))
      78              :         {
      79         1148 :             str_end_reached = true;
      80              :         }
      81              :         else
      82              :         {
      83        12266 :             assert( ouf_buf_len < sizeof(out_buffer) );
      84        12266 :             out_buffer[ouf_buf_len] = universal_buffer_input_stream_read_next( &((*this_).in_stream) );
      85        12266 :             ouf_buf_len ++;
      86              :         }
      87        13415 :         if (( JSON_CONSTANTS_CHAR_ESC == current ) && ( ! esc_incomplete ))
      88              :         {
      89          107 :             esc_incomplete = true;
      90              :         }
      91              :         else
      92              :         {
      93        13308 :             esc_incomplete = false;
      94        13308 :             if ( ouf_buf_len >= (sizeof(out_buffer)-sizeof(char)) )
      95              :             {
      96              :                 /* only if not in the middle of an escape character, write to out_stream */
      97              :                 const int err
      98            0 :                     = universal_output_stream_write( out_stream, &out_buffer, ouf_buf_len );
      99            0 :                 ouf_buf_len = 0;
     100            0 :                 if ( err != 0 )
     101              :                 {
     102            0 :                     U8_TRACE_INFO( "could not write all data to output stream in json_token_reader_private_read_string." );
     103            0 :                     result = U8_ERROR_STRING_BUFFER_EXCEEDED;
     104              :                 }
     105              :             }
     106              :         }
     107              :     }
     108              :     {
     109              :         const int err2
     110         1149 :             = universal_output_stream_write( out_stream, &out_buffer, ouf_buf_len );
     111         1149 :         ouf_buf_len = 0;
     112         1149 :         if ( err2 != 0 )
     113              :         {
     114           43 :             U8_TRACE_INFO( "could not write all data to output stream in json_token_reader_private_read_string" );
     115           43 :             result = U8_ERROR_STRING_BUFFER_EXCEEDED;
     116              :         }
     117              :     }
     118              : 
     119         1149 :     return result;
     120              : }
     121              : 
     122          295 : static inline u8_error_t json_token_reader_private_parse_integer ( json_token_reader_t *this_, int64_t *out_int )
     123              : {
     124          295 :     assert( out_int != NULL );
     125              :     int64_t result;
     126          295 :     u8_error_t err = U8_ERROR_NONE;
     127              : 
     128          295 :     char first = universal_buffer_input_stream_peek_next( &((*this_).in_stream) );
     129          295 :     if ( '0' == first )
     130              :     {
     131              :         /* only zero may begin with digit zero */
     132           27 :         result = 0;
     133           27 :         universal_buffer_input_stream_read_next( &((*this_).in_stream) );
     134              :     }
     135              :     else
     136              :     {
     137          268 :         bool minus = false;
     138          268 :         bool has_digits = false;
     139          268 :         bool minus_zero_error = false;
     140          268 :         result = 0;
     141              : 
     142              :         /* check for minus */
     143          268 :         if ( '-' == first )
     144              :         {
     145           54 :             minus = true;
     146           54 :             universal_buffer_input_stream_read_next( &((*this_).in_stream) );
     147           54 :             if ( '0' == universal_buffer_input_stream_peek_next( &((*this_).in_stream) ) )
     148              :             {
     149              :                 /* number starts with -0 which is invalid */
     150            1 :                 minus_zero_error = true;
     151              :             }
     152              :         }
     153              : 
     154          268 :         bool int_end_reached = false;
     155         1514 :         while ( ! int_end_reached )
     156              :         {
     157         1246 :             char current = universal_buffer_input_stream_peek_next( &((*this_).in_stream) );
     158         1246 :             if (( '0' <= current )&&( current <= '9'))
     159              :             {
     160          978 :                 has_digits = true;
     161          978 :                 universal_buffer_input_stream_read_next( &((*this_).in_stream) );
     162          978 :                 result = (result*10)+((int) (current-'0'));
     163              :             }
     164              :             else
     165              :             {
     166          268 :                 int_end_reached = true;
     167              :             }
     168              :         }
     169              : 
     170          268 :         if ( minus )
     171              :         {
     172           54 :             result = -result;
     173              :         }
     174              : 
     175          268 :         if ( ( ! has_digits ) || minus_zero_error )
     176              :         {
     177            3 :             result = 0;
     178            3 :             err = U8_ERROR_LEXICAL_STRUCTURE;
     179              :         }
     180              :     }
     181              : 
     182          295 :     *out_int = result;
     183          295 :     return err;
     184              : }
     185              : 
     186           15 : static inline u8_error_t json_token_reader_private_skip_number ( json_token_reader_t *this_ )
     187              : {
     188           15 :     u8_error_t result = U8_ERROR_LEXICAL_STRUCTURE;
     189              : 
     190           15 :     bool num_end_reached = false;
     191           91 :     while ( ! num_end_reached )
     192              :     {
     193           76 :         char current = universal_buffer_input_stream_peek_next( &((*this_).in_stream) );
     194           76 :         if ( (( '0' <= current )&&( current <= '9'))
     195           34 :             || ( 'e' == current )
     196           31 :             || ( 'E' == current )
     197           28 :             || ( '.' == current )
     198           22 :             || ( '+' == current )
     199           18 :             || ( '-' == current ) )
     200              :         {
     201              :             /* could be part of a valid number */
     202           61 :             universal_buffer_input_stream_read_next( &((*this_).in_stream) );
     203           61 :             result = U8_ERROR_NONE;
     204              :         }
     205              :         else
     206              :         {
     207           15 :             num_end_reached = true;
     208              :         }
     209              :     }
     210              : 
     211           15 :     return result;
     212              : }
     213              : 
     214              : 
     215              : /*
     216              : Copyright 2016-2025 Andreas Warnke
     217              : 
     218              : Licensed under the Apache License, Version 2.0 (the "License");
     219              : you may not use this file except in compliance with the License.
     220              : You may obtain a copy of the License at
     221              : 
     222              :     http://www.apache.org/licenses/LICENSE-2.0
     223              : 
     224              : Unless required by applicable law or agreed to in writing, software
     225              : distributed under the License is distributed on an "AS IS" BASIS,
     226              : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     227              : See the License for the specific language governing permissions and
     228              : limitations under the License.
     229              : */
        

Generated by: LCOV version 2.0-1