LCOV - code coverage report
Current view: top level - ballet/utf8 - fd_utf8.c (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 39 54 72.2 %
Date: 2025-03-20 12:08:36 Functions: 1 1 100.0 %

          Line data    Source code
       1             : #include "fd_utf8.h"
       2             : 
       3             : /* Basic UTF-8 validator imported from Rust's core/src/str/validations.rs */
       4             : 
       5             : /* FIXME: Add high-performance AVX version */
       6             : 
       7             : static uchar const fd_utf8_char_width[ 256 ] = {
       8             :   // 1  2  3  4  5  6  7  8  9  A  B  C  D  E  F
       9             :   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0
      10             :   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 1
      11             :   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 2
      12             :   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 3
      13             :   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 4
      14             :   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 5
      15             :   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 6
      16             :   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 7
      17             :   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8
      18             :   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9
      19             :   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // A
      20             :   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // B
      21             :   0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // C
      22             :   2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // D
      23             :   3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // E
      24             :   4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // F
      25             : };
      26             : 
      27             : FD_FN_PURE int
      28             : fd_utf8_verify( char const * str,
      29         789 :                 ulong        sz ) {
      30             : 
      31         789 :   uchar const *       cur = (uchar const *)str;
      32         789 :   if( FD_UNLIKELY( cur==NULL ) ) {
      33           0 :     return 1;
      34           0 :   }
      35             : 
      36         789 :   uchar const * const end = cur+sz;
      37             : 
      38       31539 :   while( cur<end ) {
      39       31143 :     uint c0 = *cur;
      40       31143 :     if( c0>=0x80U ) {
      41         402 :       ulong width = fd_utf8_char_width[ c0 ];
      42         402 :       if( FD_UNLIKELY( width > (ulong)(end-cur) ) )
      43         162 :         return 0;
      44         240 :       cur++;
      45         240 :       switch( width ) {
      46           3 :       case 2: {
      47           3 :         schar c1 = (schar)( *cur++ );
      48           3 :         if( FD_UNLIKELY( (c1>=-64) ) )
      49           0 :           return 0;
      50           3 :         break;
      51           3 :       }
      52           3 :       case 3: {
      53           0 :         uint c1 =          *cur++;
      54           0 :          int c2 = (schar)( *cur++ );
      55           0 :         if( FD_UNLIKELY(
      56           0 :             !(   ( (c0==0xe0)&           (c1>=0xa0)&(c1<=0xbf) )
      57           0 :                | ( (c0>=0xe1)&(c0<=0xec)&(c1>=0x80)&(c1<=0xbf) )
      58           0 :                | ( (c0==0xed)&           (c1>=0x80)&(c1<=0x9f) )
      59           0 :                | ( (c0>=0xee)&(c0<=0xef)&(c1>=0x80)&(c1<=0xbf) ) )
      60           0 :             | (c2>=-64) ) )
      61           0 :           return 0;
      62           0 :         break;
      63           0 :       }
      64           6 :       case 4: {
      65           6 :         uint c1 =          *cur++;
      66           6 :          int c2 = (schar)( *cur++ );
      67           6 :          int c3 = (schar)( *cur++ );
      68           6 :         if( FD_UNLIKELY(
      69           6 :             !(   ( (c0==0xf0)&           (c1>=0x90)&(c1<=0xbf) )
      70           6 :                | ( (c0>=0xf1)&(c0<=0xf3)&(c1>=0x80)&(c1<=0xbf) )
      71           6 :                | ( (c0==0xf4)&           (c1>=0x80)&(c1<=0x8f) ) )
      72           6 :             | (c2>=-64)
      73           6 :             | (c3>=-64) ) )
      74           0 :           return 0;
      75           6 :         break;
      76           6 :       }
      77         231 :       default:
      78         231 :         return 0;
      79         240 :       }
      80       30741 :     } else {
      81       30741 :       cur++;
      82       30741 :     }
      83       31143 :   }
      84             : 
      85         396 :   return 1;
      86         789 : }

Generated by: LCOV version 1.14