LCOV - code coverage report
Current view: top level - libs/mem/src - mem_string.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 100.0 % 19 19
Test Date: 2026-07-12 01:01:34 Functions: 100.0 % 1 1
Branches: 100.0 % 16 16

             Branch data     Line data    Source code
       1                 :             : #include "mem.h"
       2                 :             : #include "mem_internal.h"
       3                 :             : 
       4                 :             : /**
       5                 :             :  * @brief Zero-filled fallback storage for soft read-only string access
       6                 :             :  *
       7                 :             :  * `mem_string(...)` must be able to return an empty string even for string
       8                 :             :  * descriptors whose elements are wider than one byte. A plain
       9                 :             :  * `static char empty_string[] = ""` is only guaranteed to describe a byte
      10                 :             :  * string, so it is not a good universal fallback for `wchar_t`, `char16_t`,
      11                 :             :  * `char32_t`, or other descriptor element widths
      12                 :             :  *
      13                 :             :  * The `empty` field provides a block of zero-filled storage whose size matches
      14                 :             :  * `sizeof(max_align_t)`. The `align` field is not used as data. It exists so
      15                 :             :  * the whole object inherits the strongest standard alignment that the platform
      16                 :             :  * normally provides for fundamental scalar types. That way callers can safely
      17                 :             :  * interpret the returned address as a pointer to a zero-valued string element
      18                 :             :  * of the descriptor's width instead of only as a `char *`
      19                 :             :  *
      20                 :             :  * Using a file-scope union also solves the lifetime problem. A stack buffer
      21                 :             :  * would become invalid as soon as `mem_string(...)` returned, while this object
      22                 :             :  * lives for the whole program and needs no heap allocation or cleanup logic.
      23                 :             :  * The exact byte size stays platform-dependent because `sizeof(max_align_t)` is
      24                 :             :  * ABI-dependent, but that is still preferable here to introducing a separate
      25                 :             :  * hard-coded magic limit
      26                 :             :  */
      27                 :             : static const union
      28                 :             : {
      29                 :             :         max_align_t align;
      30                 :             :         unsigned char empty[sizeof(max_align_t)];
      31                 :             : } empty_string = {0};
      32                 :             : 
      33                 :             : /**
      34                 :             :  * @brief Return a soft read-only string view without modifying descriptor state
      35                 :             :  *
      36                 :             :  * This helper is meant for callers that already trust string mode and only need
      37                 :             :  * a readable pointer. It does not rescan the buffer for a terminator, does not
      38                 :             :  * recalculate the visible length, and never rewrites descriptor state. The
      39                 :             :  * function performs only the most basic descriptor checks and otherwise fully
      40                 :             :  * trusts the cached `string_length`
      41                 :             :  *
      42                 :             :  * When the descriptor is logically empty, the function returns a zero-filled
      43                 :             :  * fallback string instead of NULL. Gross descriptor contract violations such
      44                 :             :  * as a NULL descriptor, a zero element size, calling the helper on a data
      45                 :             :  * descriptor, a non-zero logical length with a NULL data pointer, or a cached
      46                 :             :  * string length that is not strictly smaller than `length` are reported and
      47                 :             :  * also fall back to the same empty string storage
      48                 :             :  *
      49                 :             :  * @param memory_object Descriptor interpreted as a read-only string descriptor
      50                 :             :  * @return Read-only pointer to descriptor-backed string data or to shared empty
      51                 :             :  *         fallback storage when no valid string view can be exposed
      52                 :             :  */
      53                 :      109249 : const void *mem_string(const memory *memory_object)
      54                 :             : {
      55         [ +  + ]:      109249 :         if(memory_object == NULL)
      56                 :             :         {
      57                 :           1 :                 report("Memory management; Soft string view requires a non-NULL descriptor");
      58                 :           1 :                 return(empty_string.empty);
      59                 :             :         }
      60                 :             : 
      61         [ +  + ]:      109248 :         if(memory_object->single_element_size == 0)
      62                 :             :         {
      63                 :           1 :                 report("Memory management; Soft string view requires a non-zero element size");
      64                 :           1 :                 return(empty_string.empty);
      65                 :             :         }
      66                 :             : 
      67         [ +  + ]:      109247 :         if(memory_object->is_string == false)
      68                 :             :         {
      69                 :           1 :                 report("Memory management; Soft string view requires a string descriptor");
      70                 :           1 :                 return(empty_string.empty);
      71                 :             :         }
      72                 :             : 
      73   [ +  +  +  + ]:      109246 :         if(memory_object->length > 0 && memory_object->data == NULL)
      74                 :             :         {
      75                 :           2 :                 report("Memory management; Descriptor has non-zero length with NULL data pointer");
      76                 :           2 :                 return(empty_string.empty);
      77                 :             :         }
      78                 :             : 
      79   [ +  +  +  + ]:      109244 :         if(memory_object->data == NULL || memory_object->length == 0)
      80                 :             :         {
      81                 :        1082 :                 return(empty_string.empty);
      82                 :             :         }
      83                 :             : 
      84         [ +  + ]:      108162 :         if(memory_object->string_length >= memory_object->length)
      85                 :             :         {
      86                 :           1 :                 report("Memory management; Soft string view requires string_length to stay below length");
      87                 :           1 :                 return(empty_string.empty);
      88                 :             :         }
      89                 :             : 
      90                 :      108161 :         return(memory_object->data);
      91                 :             : }
        

Generated by: LCOV version 2.0-1