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