LCOV - code coverage report
Current view: top level - libs/rational/src - rational_bkbmbgbtbpbeb.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 100.0 % 69 69
Test Date: 2026-07-12 01:01:34 Functions: 100.0 % 3 3
Branches: 100.0 % 36 36

             Branch data     Line data    Source code
       1                 :             : #include "rational.h"
       2                 :             : #include <stdio.h>
       3                 :             : 
       4                 :             : /**
       5                 :             :  * @brief Convert bytes
       6                 :             :  *
       7                 :             :  */
       8                 :             : static inline Byte tobyte(const size_t) __attribute__((always_inline));
       9                 :             : static inline Byte tobyte(const size_t bytes)
      10                 :             : {
      11                 :             :         /// Number of bytes in a kibibyte
      12                 :             :         /// 1024
      13                 :        1186 :         const size_t bytes_in_kibibyte = 1024ULL;
      14                 :             : 
      15                 :             :         /// Number of bytes in a mebibyte
      16                 :             :         /// 1024*1024
      17                 :        1186 :         const size_t bytes_in_mebibyte = bytes_in_kibibyte * 1024ULL;
      18                 :             : 
      19                 :             :         /// Number of bytes in a gibibyte
      20                 :             :         /// 1024*1024*1024
      21                 :        1186 :         const size_t bytes_in_gibibyte = bytes_in_mebibyte * 1024ULL;
      22                 :             : 
      23                 :             :         /// Number of bytes in a tebibyte
      24                 :             :         /// 1024*1024*1024*1024
      25                 :        1186 :         const size_t bytes_in_tebibyte = bytes_in_gibibyte * 1024ULL;
      26                 :             : 
      27                 :             :         /// Number of bytes in a pebibyte
      28                 :             :         /// 1024*1024*1024*1024*1024
      29                 :        1186 :         const size_t bytes_in_pebibyte = bytes_in_tebibyte * 1024ULL;
      30                 :             : 
      31                 :             :         /// Number of bytes in an exbibyte
      32                 :             :         /// 1024*1024*1024*1024*1024*1024
      33                 :        1186 :         const size_t bytes_in_exbibyte = bytes_in_pebibyte * 1024ULL;
      34                 :             : 
      35                 :             :         /*
      36                 :             :          *
      37                 :             :          * Fill out the corresponding values of the structure
      38                 :             :          *
      39                 :             :          */
      40                 :             : 
      41                 :             :         // Initializing of the structure that will be returned
      42                 :             :         // from the function
      43                 :        1186 :         Byte byte = {0};
      44                 :             : 
      45                 :        1186 :         byte.exbibytes = bytes/bytes_in_exbibyte;
      46                 :             : 
      47                 :        1186 :         const size_t exbibytes = byte.exbibytes*bytes_in_exbibyte;
      48                 :        1186 :         byte.pebibytes = (bytes - exbibytes)/bytes_in_pebibyte;
      49                 :             : 
      50                 :        1186 :         const size_t pebibytes = byte.pebibytes*bytes_in_pebibyte;
      51                 :        1186 :         byte.tebibytes = (bytes - exbibytes - pebibytes)/bytes_in_tebibyte;
      52                 :             : 
      53                 :        1186 :         const size_t tebibytes = byte.tebibytes*bytes_in_tebibyte;
      54                 :        1186 :         byte.gibibytes = (bytes - exbibytes - pebibytes - tebibytes)/bytes_in_gibibyte;
      55                 :             : 
      56                 :        1186 :         const size_t gibibytes = byte.gibibytes*bytes_in_gibibyte;
      57                 :        1186 :         byte.mebibytes = (bytes - exbibytes - pebibytes - tebibytes - gibibytes)/bytes_in_mebibyte;
      58                 :             : 
      59                 :        1186 :         const size_t mebibytes = byte.mebibytes*bytes_in_mebibyte;
      60                 :        1186 :         byte.kibibytes = (bytes - exbibytes - pebibytes - tebibytes - gibibytes - mebibytes)/bytes_in_kibibyte;
      61                 :             : 
      62                 :        1186 :         const size_t kibibytes = byte.kibibytes*bytes_in_kibibyte;
      63                 :        1186 :         byte.bytes = (bytes - exbibytes - pebibytes - tebibytes - gibibytes - mebibytes - kibibytes);
      64                 :             : 
      65                 :        1186 :         return(byte);
      66                 :             : }
      67                 :             : 
      68                 :             : /**
      69                 :             :  * @brief Append one non-zero unit to the resulting size string.
      70                 :             :  *
      71                 :             :  * @param result Output string being built.
      72                 :             :  * @param result_size Size of the output buffer.
      73                 :             :  * @param used_len Current used length of the output buffer.
      74                 :             :  * @param bytes Unit value to append when it is non-zero.
      75                 :             :  * @param suffix Unit suffix (B, KiB, MiB, GiB, TiB, PiB, EiB).
      76                 :             :  */
      77                 :        5812 : static void catbyte_r(
      78                 :             :         char *const       result,
      79                 :             :         const size_t      result_size,
      80                 :             :         size_t *const     used_len,
      81                 :             :         const size_t      bytes,
      82                 :             :         const char *const suffix)
      83                 :             : {
      84   [ +  +  +  + ]:        5812 :         if(bytes == 0ULL || *used_len >= result_size)
      85                 :             :         {
      86                 :        3896 :                 return;
      87                 :             :         }
      88                 :             : 
      89                 :        1916 :         const int written = snprintf(result + *used_len,result_size - *used_len,"%zu%s ",bytes,suffix);
      90                 :             : 
      91         [ +  + ]:        1916 :         if(written < 0)
      92                 :             :         {
      93                 :           1 :                 return;
      94                 :             :         }
      95                 :             : 
      96                 :        1915 :         const size_t write_size = (size_t)written;
      97                 :             : 
      98         [ +  + ]:        1915 :         if(write_size >= result_size - *used_len)
      99                 :             :         {
     100                 :             :                 /*
     101                 :             :                  * snprintf() has already written the largest prefix that fits.
     102                 :             :                  * Mark the buffer as full so later units do not try to append text
     103                 :             :                  */
     104                 :           5 :                 *used_len = result_size;
     105                 :           5 :                 result[result_size - 1ULL] = '\0';
     106                 :             : 
     107                 :             :                 /*
     108                 :             :                  * If the visible prefix ends right after a unit separator, hide that
     109                 :             :                  * separator so callers get a clean partial value
     110                 :             :                  */
     111   [ +  +  +  + ]:           5 :                 if(result_size > 1ULL && result[result_size - 2ULL] == ' ')
     112                 :             :                 {
     113                 :           1 :                         result[result_size - 2ULL] = '\0';
     114                 :             :                 }
     115                 :             :         } else {
     116                 :        1910 :                 *used_len += write_size;
     117                 :             :         }
     118                 :             : }
     119                 :             : 
     120                 :             : /**
     121                 :             :  * @brief Convert bytes to a human-readable size string in caller-provided buffer.
     122                 :             :  *
     123                 :             :  * @details Convert number of bytes to human-readable string:
     124                 :             :  * B   - Byte
     125                 :             :  * KiB - Kibibyte
     126                 :             :  * MiB - Mebibyte
     127                 :             :  * GiB - Gibibyte
     128                 :             :  * TiB - Tebibyte
     129                 :             :  * PiB - Pebibyte
     130                 :             :  * EiB - Exbibyte
     131                 :             :  *
     132                 :             :  * @param bytes Number of bytes to format.
     133                 :             :  * @param format Output style:
     134                 :             :  *               - FULL_VIEW: show all non-zero units.
     135                 :             :  *               - MAJOR_VIEW: show only the highest non-zero unit.
     136                 :             :  * @param buffer Destination buffer.
     137                 :             :  * @param buffer_size Destination buffer size in bytes.
     138                 :             :  * @return @p buffer on success, NULL when @p buffer is NULL or @p buffer_size is zero.
     139                 :             :  */
     140                 :        1238 : char *bkbmbgbtbpbeb_r(
     141                 :             :         const size_t     bytes,
     142                 :             :         const ByteFormat format,
     143                 :             :         char             *buffer,
     144                 :             :         const size_t     buffer_size)
     145                 :             : {
     146   [ +  +  +  + ]:        1238 :         if(buffer == NULL || buffer_size == 0ULL)
     147                 :             :         {
     148                 :           2 :                 return(NULL);
     149                 :             :         }
     150                 :             : 
     151                 :        1236 :         buffer[0] = '\0';
     152                 :        1236 :         size_t used_len = 0ULL;
     153                 :             : 
     154                 :             :         // If the number passed is 0 Bytes
     155         [ +  + ]:        1236 :         if(bytes == 0ULL)
     156                 :             :         {
     157                 :          50 :                 (void)snprintf(buffer,buffer_size,"0B");
     158                 :          50 :                 return(buffer);
     159                 :             :         }
     160                 :             : 
     161                 :             :         Byte byte = tobyte(bytes);
     162                 :             : 
     163         [ +  + ]:        1186 :         if(format == MAJOR_VIEW)
     164                 :             :         {
     165         [ +  + ]:         415 :                 if(byte.exbibytes > 0ULL)
     166                 :             :                 {
     167                 :           1 :                         catbyte_r(buffer,buffer_size,&used_len,byte.exbibytes,"EiB");
     168         [ +  + ]:         414 :                 } else if(byte.pebibytes > 0ULL){
     169                 :           1 :                         catbyte_r(buffer,buffer_size,&used_len,byte.pebibytes,"PiB");
     170         [ +  + ]:         413 :                 } else if(byte.tebibytes > 0ULL){
     171                 :           1 :                         catbyte_r(buffer,buffer_size,&used_len,byte.tebibytes,"TiB");
     172         [ +  + ]:         412 :                 } else if(byte.gibibytes > 0ULL){
     173                 :           2 :                         catbyte_r(buffer,buffer_size,&used_len,byte.gibibytes,"GiB");
     174         [ +  + ]:         410 :                 } else if(byte.mebibytes > 0ULL){
     175                 :         112 :                         catbyte_r(buffer,buffer_size,&used_len,byte.mebibytes,"MiB");
     176         [ +  + ]:         298 :                 } else if(byte.kibibytes > 0ULL){
     177                 :         110 :                         catbyte_r(buffer,buffer_size,&used_len,byte.kibibytes,"KiB");
     178                 :             :                 } else {
     179                 :         188 :                         catbyte_r(buffer,buffer_size,&used_len,byte.bytes,"B");
     180                 :             :                 }
     181                 :             : 
     182                 :             :         } else {
     183                 :         771 :                 catbyte_r(buffer,buffer_size,&used_len,byte.exbibytes,"EiB");
     184                 :         771 :                 catbyte_r(buffer,buffer_size,&used_len,byte.pebibytes,"PiB");
     185                 :         771 :                 catbyte_r(buffer,buffer_size,&used_len,byte.tebibytes,"TiB");
     186                 :         771 :                 catbyte_r(buffer,buffer_size,&used_len,byte.gibibytes,"GiB");
     187                 :         771 :                 catbyte_r(buffer,buffer_size,&used_len,byte.mebibytes,"MiB");
     188                 :         771 :                 catbyte_r(buffer,buffer_size,&used_len,byte.kibibytes,"KiB");
     189                 :         771 :                 catbyte_r(buffer,buffer_size,&used_len,byte.bytes,"B");
     190                 :             :         }
     191                 :             : 
     192   [ +  +  +  + ]:        1186 :         if(used_len > 0ULL && buffer[used_len - 1ULL] == ' ')
     193                 :             :         {
     194                 :        1180 :                 buffer[used_len - 1ULL] = '\0';
     195                 :             :         }
     196                 :             : 
     197                 :        1186 :         return(buffer);
     198                 :             : }
     199                 :             : 
     200                 :             : /**
     201                 :             :  * @brief Convert bytes to a human-readable size string.
     202                 :             :  *
     203                 :             :  * @param bytes Number of bytes to format.
     204                 :             :  * @param format Output style:
     205                 :             :  *               - FULL_VIEW: show all non-zero units.
     206                 :             :  *               - MAJOR_VIEW: show only the highest non-zero unit.
     207                 :             :  * @return Pointer to a static buffer with formatted text.
     208                 :             :  */
     209                 :         958 : char *bkbmbgbtbpbeb(
     210                 :             :         const size_t     bytes,
     211                 :             :         const ByteFormat format)
     212                 :             : {
     213                 :             :         // Zero out a static memory area with a string array
     214                 :             :         static char result[MAX_CHARACTERS] = {0};
     215                 :             : 
     216                 :         958 :         (void)bkbmbgbtbpbeb_r(bytes,format,result,sizeof(result));
     217                 :             : 
     218                 :         958 :         return(result);
     219                 :             : }
     220                 :             : #if 0
     221                 :             : /// Test
     222                 :             : /// 4617322122555958282 = ((1024*1024*1024*1024*1024*1024)*4)+((1024*1024*1024*1024*1024)*5)+((1024*1024*1024*1024)*6)+((1024*1024*1024)*7)+((1024*1024)*8)+((1024)*9)+10
     223                 :             : /// Should be 4EiB 5PiB 6TiB 7GiB 8MiB 9KiB 10B
     224                 :             : int main(void)
     225                 :             : {
     226                 :             :         const size_t bytes = 4617322122555958282ULL;
     227                 :             :         printf("%s\n",bkbmbgbtbpbeb(bytes,FULL_VIEW));
     228                 :             :         return 0;
     229                 :             : }
     230                 :             : #endif
        

Generated by: LCOV version 2.0-1