LCOV - code coverage report
Current view: top level - src/bitstream - bitstream_symbol.c (source / functions) Coverage Total Hit
Test: lcov.info Lines: 100.0 % 73 73
Test Date: 2026-03-09 04:08:32 Functions: 100.0 % 4 4
Branches: 91.0 % 78 71

             Branch data     Line data    Source code
       1                 :             : /**
       2                 :             :  * @file bitstream_symbol.c
       3                 :             :  * @brief Fixed-width symbol and UTF-8 codepoint read/write.
       4                 :             :  */
       5                 :             : 
       6                 :             : #include "bitstream_internal.h"
       7                 :             : 
       8                 :             : /* ── Symbol ──────────────────────────────────────────────────────────── */
       9                 :             : 
      10                 :          42 : tp_result tp_bs_read_symbol(tp_bitstream_reader *r, unsigned int bps, uint32_t *out)
      11                 :             : {
      12   [ +  +  +  +  :          42 :     if (!r || !out || bps == 0 || bps > 32)
             +  +  +  + ]
      13                 :           4 :         return TP_ERR_INVALID_PARAM;
      14                 :             : 
      15                 :             :     uint64_t val;
      16                 :          38 :     tp_result rc = tp_bs_read_bits(r, bps, &val);
      17         [ +  - ]:          38 :     if (rc == TP_OK)
      18                 :          38 :         *out = (uint32_t)val;
      19                 :          38 :     return rc;
      20                 :             : }
      21                 :             : 
      22                 :          41 : tp_result tp_bs_write_symbol(tp_bitstream_writer *w, uint32_t val, unsigned int bps)
      23                 :             : {
      24   [ +  +  +  +  :          41 :     if (!w || bps == 0 || bps > 32)
                   +  + ]
      25                 :           3 :         return TP_ERR_INVALID_PARAM;
      26                 :          38 :     return tp_bs_write_bits(w, val, bps);
      27                 :             : }
      28                 :             : 
      29                 :             : /* ── UTF-8 ───────────────────────────────────────────────────────────── */
      30                 :             : 
      31                 :          29 : tp_result tp_bs_read_utf8(tp_bitstream_reader *r, uint32_t *out)
      32                 :             : {
      33   [ +  +  +  + ]:          29 :     if (!r || !out)
      34                 :           2 :         return TP_ERR_INVALID_PARAM;
      35                 :             : 
      36                 :             :     uint8_t first;
      37                 :          27 :     tp_result rc = tp_bs_read_u8(r, &first);
      38         [ +  + ]:          27 :     if (rc != TP_OK)
      39                 :           1 :         return rc;
      40                 :             : 
      41                 :             :     uint32_t cp;
      42                 :             :     uint8_t cont;
      43                 :             : 
      44         [ +  + ]:          26 :     if ((first & 0x80) == 0) {
      45                 :           3 :         *out = first;
      46                 :           3 :         return TP_OK;
      47         [ +  + ]:          23 :     } else if ((first & 0xE0) == 0xC0) {
      48                 :           6 :         cp = first & 0x1F;
      49                 :           6 :         cont = 1;
      50         [ +  + ]:          17 :     } else if ((first & 0xF0) == 0xE0) {
      51                 :           8 :         cp = first & 0x0F;
      52                 :           8 :         cont = 2;
      53         [ +  + ]:           9 :     } else if ((first & 0xF8) == 0xF0) {
      54                 :           6 :         cp = first & 0x07;
      55                 :           6 :         cont = 3;
      56                 :             :     } else {
      57                 :           3 :         return TP_ERR_INVALID_UTF8;
      58                 :             :     }
      59                 :             : 
      60         [ +  + ]:          54 :     for (uint8_t i = 0; i < cont; i++) {
      61                 :             :         uint8_t b;
      62                 :          40 :         rc = tp_bs_read_u8(r, &b);
      63         [ +  + ]:          40 :         if (rc != TP_OK)
      64                 :           6 :             return rc;
      65         [ +  + ]:          37 :         if ((b & 0xC0) != 0x80)
      66                 :           3 :             return TP_ERR_INVALID_UTF8;
      67                 :          34 :         cp = (cp << 6) | (b & 0x3F);
      68                 :             :     }
      69                 :             : 
      70                 :             :     /* Reject overlong encodings */
      71   [ +  +  +  + ]:          14 :     if (cont == 1 && cp < 0x80)
      72                 :           1 :         return TP_ERR_INVALID_UTF8;
      73   [ +  +  +  + ]:          13 :     if (cont == 2 && cp < 0x800)
      74                 :           1 :         return TP_ERR_INVALID_UTF8;
      75   [ +  +  +  + ]:          12 :     if (cont == 3 && cp < 0x10000)
      76                 :           1 :         return TP_ERR_INVALID_UTF8;
      77                 :             : 
      78                 :             :     /* Reject surrogates U+D800..U+DFFF */
      79   [ +  +  +  + ]:          11 :     if (cp >= 0xD800 && cp <= 0xDFFF)
      80                 :           2 :         return TP_ERR_INVALID_UTF8;
      81                 :             : 
      82                 :           9 :     *out = cp;
      83                 :           9 :     return TP_OK;
      84                 :             : }
      85                 :             : 
      86                 :          22 : tp_result tp_bs_write_utf8(tp_bitstream_writer *w, uint32_t cp)
      87                 :             : {
      88         [ +  + ]:          22 :     if (!w)
      89                 :           1 :         return TP_ERR_INVALID_PARAM;
      90                 :             : 
      91                 :             :     /* Reject surrogates U+D800..U+DFFF */
      92   [ +  +  +  + ]:          21 :     if (cp >= 0xD800 && cp <= 0xDFFF)
      93                 :           6 :         return TP_ERR_INVALID_UTF8;
      94                 :             : 
      95                 :             :     /* Allocation failure paths are excluded from coverage (LCOV_EXCL). */
      96         [ +  + ]:          15 :     if (cp <= 0x7F) {
      97                 :           3 :         return tp_bs_write_u8(w, (uint8_t)cp);
      98         [ +  + ]:          12 :     } else if (cp <= 0x7FF) {
      99                 :           3 :         tp_result rc = tp_bs_write_u8(w, (uint8_t)(0xC0 | (cp >> 6)));
     100         [ -  + ]:           3 :         if (rc != TP_OK)
     101                 :             :             return rc; /* LCOV_EXCL_LINE */
     102                 :           3 :         return tp_bs_write_u8(w, (uint8_t)(0x80 | (cp & 0x3F)));
     103         [ +  + ]:           9 :     } else if (cp <= 0xFFFF) {
     104                 :           3 :         tp_result rc = tp_bs_write_u8(w, (uint8_t)(0xE0 | (cp >> 12)));
     105         [ -  + ]:           3 :         if (rc != TP_OK)
     106                 :             :             return rc; /* LCOV_EXCL_LINE */
     107                 :           3 :         rc = tp_bs_write_u8(w, (uint8_t)(0x80 | ((cp >> 6) & 0x3F)));
     108         [ -  + ]:           3 :         if (rc != TP_OK)
     109                 :             :             return rc; /* LCOV_EXCL_LINE */
     110                 :           3 :         return tp_bs_write_u8(w, (uint8_t)(0x80 | (cp & 0x3F)));
     111         [ +  + ]:           6 :     } else if (cp <= 0x10FFFF) {
     112                 :           3 :         tp_result rc = tp_bs_write_u8(w, (uint8_t)(0xF0 | (cp >> 18)));
     113         [ -  + ]:           3 :         if (rc != TP_OK)
     114                 :             :             return rc; /* LCOV_EXCL_LINE */
     115                 :           3 :         rc = tp_bs_write_u8(w, (uint8_t)(0x80 | ((cp >> 12) & 0x3F)));
     116         [ -  + ]:           3 :         if (rc != TP_OK)
     117                 :             :             return rc; /* LCOV_EXCL_LINE */
     118                 :           3 :         rc = tp_bs_write_u8(w, (uint8_t)(0x80 | ((cp >> 6) & 0x3F)));
     119         [ -  + ]:           3 :         if (rc != TP_OK)
     120                 :             :             return rc; /* LCOV_EXCL_LINE */
     121                 :           3 :         return tp_bs_write_u8(w, (uint8_t)(0x80 | (cp & 0x3F)));
     122                 :             :     }
     123                 :             : 
     124                 :           3 :     return TP_ERR_INVALID_UTF8;
     125                 :             : }
        

Generated by: LCOV version 2.0-1