LCOV - code coverage report
Current view: top level - ballet/utf8 - fd_utf8.c (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 54 54 100.0 %
Date: 2024-11-13 11:58:15 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        7593 :                 ulong        sz ) {
      30             : 
      31        7593 :   uchar const *       cur = (uchar const *)str;
      32        7593 :   if( FD_UNLIKELY( cur==NULL ) ) {
      33           9 :     return 1;
      34           9 :   }
      35             : 
      36        7584 :   uchar const * const end = cur+sz;
      37             : 
      38      452139 :   while( cur<end ) {
      39      446172 :     uint c0 = *cur;
      40      446172 :     if( c0>=0x80U ) {
      41       25497 :       ulong width = fd_utf8_char_width[ c0 ];
      42       25497 :       if( FD_UNLIKELY( width > (ulong)(end-cur) ) )
      43         219 :         return 0;
      44       25278 :       cur++;
      45       25278 :       switch( width ) {
      46        9201 :       case 2: {
      47        9201 :         schar c1 = (schar)( *cur++ );
      48        9201 :         if( FD_UNLIKELY( (c1>=-64) ) )
      49         195 :           return 0;
      50        9006 :         break;
      51        9201 :       }
      52        9021 :       case 3: {
      53        9021 :         uint c1 =          *cur++;
      54        9021 :          int c2 = (schar)( *cur++ );
      55        9021 :         if( FD_UNLIKELY(
      56        9021 :             !(   ( (c0==0xe0)&           (c1>=0xa0)&(c1<=0xbf) )
      57        9021 :                | ( (c0>=0xe1)&(c0<=0xec)&(c1>=0x80)&(c1<=0xbf) )
      58        9021 :                | ( (c0==0xed)&           (c1>=0x80)&(c1<=0x9f) )
      59        9021 :                | ( (c0>=0xee)&(c0<=0xef)&(c1>=0x80)&(c1<=0xbf) ) )
      60        9021 :             | (c2>=-64) ) )
      61         156 :           return 0;
      62        8865 :         break;
      63        9021 :       }
      64        8865 :       case 4: {
      65        6099 :         uint c1 =          *cur++;
      66        6099 :          int c2 = (schar)( *cur++ );
      67        6099 :          int c3 = (schar)( *cur++ );
      68        6099 :         if( FD_UNLIKELY(
      69        6099 :             !(   ( (c0==0xf0)&           (c1>=0x90)&(c1<=0xbf) )
      70        6099 :                | ( (c0>=0xf1)&(c0<=0xf3)&(c1>=0x80)&(c1<=0xbf) )
      71        6099 :                | ( (c0==0xf4)&           (c1>=0x80)&(c1<=0x8f) ) )
      72        6099 :             | (c2>=-64)
      73        6099 :             | (c3>=-64) ) )
      74          90 :           return 0;
      75        6009 :         break;
      76        6099 :       }
      77        6009 :       default:
      78         957 :         return 0;
      79       25278 :       }
      80      420675 :     } else {
      81      420675 :       cur++;
      82      420675 :     }
      83      446172 :   }
      84             : 
      85        5967 :   return 1;
      86        7584 : }

Generated by: LCOV version 1.14