LCOV - code coverage report
Current view: top level - io/include/json - json_token_reader.inl (source / functions) Hit Total Coverage
Test: crystal-facet-uml_v1.61.0_covts Lines: 104 109 95.4 %
Date: 2024-10-26 21:44:38 Functions: 7 7 100.0 %

          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        4153 : static inline void json_token_reader_private_skip_whitespace ( json_token_reader_t *this_ )
       8             : {
       9        4153 :     bool ws_end_reached = false;
      10        4153 :     char current = ' ';
      11       18256 :     while ( ( ! ws_end_reached ) && ( current != '\0' ) )
      12             :     {
      13       14103 :         current = universal_buffer_input_stream_peek_next( &((*this_).in_stream) );
      14       14103 :         if ( ( JSON_CONSTANTS_CHAR_NL != current )
      15       13018 :             && ( JSON_CONSTANTS_CHAR_CR != current )
      16       13013 :             && ( JSON_CONSTANTS_CHAR_TAB != current )
      17       13008 :             && ( JSON_CONSTANTS_CHAR_SPACE != current ))
      18             :         {
      19        4153 :             ws_end_reached = true;
      20             :         }
      21             :         else
      22             :         {
      23        9950 :             universal_buffer_input_stream_read_next( &((*this_).in_stream) );
      24        9950 :             if ( current == JSON_CONSTANTS_CHAR_NL )
      25             :             {
      26        1085 :                 (*this_).input_line ++;
      27             :             }
      28             :         }
      29             :     }
      30        4153 : }
      31             : 
      32          19 : static inline unsigned int json_token_reader_get_input_line ( json_token_reader_t *this_ )
      33             : {
      34          19 :     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        1416 : static inline bool json_token_reader_private_is_value_end ( json_token_reader_t *this_ )
      43             : {
      44        1416 :     char next = universal_buffer_input_stream_peek_next( &((*this_).in_stream) );
      45             : 
      46        1416 :     const bool result = (( next == '\0' )
      47        1408 :         || ( next == JSON_CONSTANTS_CHAR_NL )
      48        1362 :         || ( next == JSON_CONSTANTS_CHAR_CR )
      49        1361 :         || ( next == JSON_CONSTANTS_CHAR_TAB )
      50        1360 :         || ( next == JSON_CONSTANTS_CHAR_SPACE )
      51        1311 :         || ( next == JSON_CONSTANTS_CHAR_BEGIN_OBJECT )
      52        1311 :         || ( next == JSON_CONSTANTS_CHAR_END_OBJECT )
      53        1310 :         || ( next == JSON_CONSTANTS_CHAR_BEGIN_ARRAY )
      54        1310 :         || ( next == JSON_CONSTANTS_CHAR_END_ARRAY )
      55        1309 :         || ( next == JSON_CONSTANTS_CHAR_NAME_SEPARATOR )
      56        2824 :         || ( next == JSON_CONSTANTS_CHAR_VALUE_SEPARATOR ));
      57             : 
      58        1416 :     return result;
      59             : }
      60             : 
      61        1101 : static inline u8_error_t json_token_reader_private_read_string ( json_token_reader_t *this_, universal_output_stream_t *out_stream )
      62             : {
      63        1101 :     assert( out_stream != NULL );
      64        1101 :     u8_error_t result = U8_ERROR_NONE;
      65        1101 :     bool str_end_reached = false;
      66        1101 :     char esc_incomplete = false;
      67             :     char out_buffer[64];
      68        1101 :     size_t ouf_buf_len = 0;
      69       13946 :     while ( ! str_end_reached )
      70             :     {
      71       12845 :         char current = universal_buffer_input_stream_peek_next( &((*this_).in_stream) );
      72       12845 :         if ( '\0' == current )
      73             :         {
      74           1 :             str_end_reached = true;
      75           1 :             result = U8_ERROR_LEXICAL_STRUCTURE;
      76             :         }
      77       12844 :         else if (( JSON_CONSTANTS_CHAR_END_STRING == current )&&( ! esc_incomplete ))
      78             :         {
      79        1100 :             str_end_reached = true;
      80             :         }
      81             :         else
      82             :         {
      83       11744 :             assert( ouf_buf_len < sizeof(out_buffer) );
      84       11744 :             out_buffer[ouf_buf_len] = universal_buffer_input_stream_read_next( &((*this_).in_stream) );
      85       11744 :             ouf_buf_len ++;
      86             :         }
      87       12845 :         if (( JSON_CONSTANTS_CHAR_ESC == current ) && ( ! esc_incomplete ))
      88             :         {
      89         107 :             esc_incomplete = true;
      90             :         }
      91             :         else
      92             :         {
      93       12738 :             esc_incomplete = false;
      94       12738 :             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        1101 :             = universal_output_stream_write( out_stream, &out_buffer, ouf_buf_len );
     111        1101 :         ouf_buf_len = 0;
     112        1101 :         if ( err2 != 0 )
     113             :         {
     114          28 :             U8_TRACE_INFO( "could not write all data to output stream in json_token_reader_private_read_string" );
     115          28 :             result = U8_ERROR_STRING_BUFFER_EXCEEDED;
     116             :         }
     117             :     }
     118             : 
     119        1101 :     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           9 : static inline u8_error_t json_token_reader_private_skip_number ( json_token_reader_t *this_ )
     187             : {
     188           9 :     u8_error_t result = U8_ERROR_LEXICAL_STRUCTURE;
     189             : 
     190           9 :     bool num_end_reached = false;
     191          73 :     while ( ! num_end_reached )
     192             :     {
     193          64 :         char current = universal_buffer_input_stream_peek_next( &((*this_).in_stream) );
     194          64 :         if ( (( '0' <= current )&&( current <= '9'))
     195          28 :             || ( 'e' == current )
     196          25 :             || ( 'E' == current )
     197          22 :             || ( '.' == current )
     198          16 :             || ( '+' == current )
     199          12 :             || ( '-' == current ) )
     200             :         {
     201             :             /* could be part of a valid number */
     202          55 :             universal_buffer_input_stream_read_next( &((*this_).in_stream) );
     203          55 :             result = U8_ERROR_NONE;
     204             :         }
     205             :         else
     206             :         {
     207           9 :             num_end_reached = true;
     208             :         }
     209             :     }
     210             : 
     211           9 :     return result;
     212             : }
     213             : 
     214             : 
     215             : /*
     216             : Copyright 2016-2024 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 1.16