GPS Device
Loading...
Searching...
No Matches
common.c
Go to the documentation of this file.
1
11
12#include <stdbool.h>
13
14#include "common.h"
15
20
22uint32_t get_str_len(char const *str) {
23 uint32_t len = 0;
24
25 while(*str++) {
26 len++;
27 }
28
29 return len;
30}
31
33void int_to_str(int num, char *str) {
34 char *start = str;
35 bool is_negative = false;
36
37 if (num < 0) {
38 is_negative = true;
39 num = -num;
40 }
41 if (num == 0) {
42 *str++ = '0';
43 }
44
45 while (num > 0) {
46 uint8_t digit = num % 10;
47 num = num / 10;
48
49 *str++ = (char)(digit + '0');
50 }
51
52 if (is_negative) {
53 *str++ = '-';
54 }
55
56 *str = '\0';
57
58 char *end = str - 1;
59 while (start < end) {
60 char tmp = *start;
61 *start = *end;
62 *end = tmp;
63 start++;
64 end--;
65 }
66}
67
69int str_to_int(const char* str) {
70 bool negative = false;
71 uint8_t num_array[12] = { 0 };
72 uint8_t digit_counter = 0;
73 int32_t num = 0;
74
75 if(*str == '-') {
76 negative = true;
77 str++;
78 }
79
80 while(*str) {
81 num_array[digit_counter] = *str - 48;
82
83 digit_counter++;
84 str++;
85 }
86
87 uint32_t multiplier = 1;
88 for(int8_t i = digit_counter - 1; i >= 0 ; i--) {
89 num += num_array[i] * multiplier;
90
91 multiplier *= 10;
92 }
93
94 if(negative) {
95 num *= -1;
96 }
97
98 return num;
99}
100
102void double_to_str(double num, char *str, int8_t frac_digits) {
103 int32_t int_part;
104 double frac_part;
105 uint8_t int_part_len;
106 uint8_t frac_part_len;
107 uint8_t total_len = 0;
108 double addend;
109 uint8_t missing_zeroes = 0;
110 bool negative_0_to_1 = false;
111
112 if(num > -1 && num < 0) {
113 negative_0_to_1 = true;
114 }
115
116 int_part = (int32_t)num;
117 frac_part = ((num - (double)int_part) * get_pow(10, frac_digits));
118
119 addend = 1.0 / (20 * get_pow(10, frac_digits));
120
121 if(frac_part < 0) {
122 frac_part -= addend;
123 frac_part *= -1;
124 }
125 else {
126 frac_part += addend;
127 }
128
129 for(uint8_t i = 1; i <= frac_digits; i++) {
130 int32_t comp_to_frac = (get_pow(10, frac_digits - i));
131
132 if(frac_part < comp_to_frac) {
133 missing_zeroes++;
134 }
135 else {
136 break;
137 }
138 }
139 total_len += missing_zeroes;
140
141 char int_buf[20] = { 0 };
142 if(negative_0_to_1) {
143 int_buf[0] = '-';
144 int_to_str(int_part, int_buf + 1);
145 }
146 else {
147 int_to_str(int_part, int_buf);
148 }
149 int_part_len = get_str_len(int_buf);
150 total_len += int_part_len;
151
152 char double_buf[12] = { 0 };
153 int_to_str((int32_t)frac_part, double_buf);
154 frac_part_len = get_str_len(double_buf);
155 total_len += frac_part_len;
156
157 int_buf[int_part_len] = '.';
158 total_len++;
159
160 for(uint8_t i = 0; i < missing_zeroes; i++) {
161 int_buf[int_part_len + 1 + i] = '0';
162 }
163
164 str_set(int_buf, double_buf, frac_part_len, total_len - frac_part_len);
165
166 int_buf[total_len] = '\0';
167 total_len++;
168
169 for(uint8_t i = 0; i < total_len; i++) {
170 str[i] = int_buf[i];
171 }
172}
173
175void hex_byte_to_str(uint8_t byte, char *str) {
176 uint8_t first_part = byte / 16;
177 uint8_t second_part = byte % 16;
178
179 if(first_part < 10) {
180 str[0] = (byte / 16) + 48;
181 }
182 else {
183 str[0] = (byte / 16) + 55;
184 }
185
186 if(second_part < 10) {
187 str[1] = (byte % 16) + 48;
188 }
189 else {
190 str[1] = (byte % 16) + 55;
191 }
192}
193
195void str_set(char *target_str, char const *host_str, uint32_t host_str_len, uint32_t pos) {
196 uint32_t pos_counter = 0;
197 bool pos_reached = false;
198 uint32_t bytes_replaced = 0;
199
200 while(bytes_replaced != host_str_len) {
201 if(pos_counter == pos) {
202 pos_reached = true;
203 }
204
205 if(pos_reached) {
206 *target_str = host_str[bytes_replaced];
207 bytes_replaced++;
208
209 if(bytes_replaced == host_str_len) {
210 break;
211 }
212 }
213
214 target_str++;
215 pos_counter++;
216 }
217}
218
220int32_t get_pow(int32_t base, int32_t exponent) {
221 int32_t result = 1;
222
223 for(int32_t i = 0; i < exponent; i++) {
224 result *= base;
225 }
226
227 return result;
228}
229
231void arr_cmprs(char *arr, uint8_t len) {
232 uint8_t write = 0;
233
234 for(uint8_t read = 0; read < len; read++) {
235 if(arr[read] != '\0') {
236 arr[write] = arr[read];
237 write++;
238 }
239 }
240
241 while(write < len) {
242 arr[write] = '\0';
243 write++;
244 }
245}
246
248bool str_cmp(const char *str1, const char *str2) {
249 while(*str1 != '\0' && *str2 != '\0') {
250 if(*str1 != *str2) {
251 return false;
252 }
253 str1++;
254 str2++;
255 }
256
257 if(*str1 == '\0' && *str2 == '\0') {
258 return true;
259 }
260
261 return false;
262}
263
265uint8_t ascii_hex_to_byte(char high, char low) {
266 uint8_t value = 0;
267 uint8_t nibble;
268
269 if (high >= '0' && high <= '9')
270 nibble = (uint8_t)(high - '0');
271 else
272 nibble = (uint8_t)(high - 'A' + 10);
273
274 value = (uint8_t)(nibble << 4);
275
276 if (low >= '0' && low <= '9')
277 nibble = (uint8_t)(low - '0');
278 else
279 nibble = (uint8_t)(low - 'A' + 10);
280
281 value |= nibble;
282
283 return value;
284}
285
287int str_tokenize(char *str, const char *separator, uint16_t max_tokens, char **tokens, uint16_t *num_tokens) {
288 while(true) {
289 while(*str == ' ') {
290 str++;
291 }
292
293 if(*str == '\0') {
294 return -1;
295 }
296
297 if(*num_tokens <= max_tokens) {
298 tokens[*num_tokens] = str;
299 *num_tokens = *num_tokens + 1;
300 }
301 else {
302 return -1;
303 }
304
305 while(*str && *str != *separator) {
306 str++;
307 }
308
309 if(*str == '\0') {
310 break;
311 }
312
313 *str++ = '\0';
314 }
315
316 return 0;
317}
318
320bool str_to_bool(char const *str) {
321 if(str_cmp(str, "true") == true) {
322 return true;
323 }
324 else if(str_cmp(str, "false") == true) {
325 return false;
326 }
327
328 // Error
329 return false;
330}
331
333int str_cpy(char *str_to, const char *str_from, uint32_t len)
334{
335 if (len == 0 || str_to == (void*)0 || str_from == (void*)0) {
336 return -1;
337 }
338
339 while (*str_from && len > 1) {
340 *str_to++ = *str_from++;
341 len--;
342 }
343
344 *str_to = '\0'; // always null-terminate
345
346 return 0;
347}
348
350int txt_cpy(char *txt_to, const char *txt_from, uint32_t len) {
351 if (len == 0 || txt_to == (void*)0 || txt_from == (void*)0) {
352 return -1;
353 }
354
355 while (*txt_from && len != 0) {
356 *txt_to++ = *txt_from++;
357 len--;
358 }
359
360 return 0;
361}
362
364bool is_pow(uint32_t num) {
365 return num && !(num & (num - 1));
366}
367
369uint32_t extract_bits(const uint8_t *data, uint16_t start_bit, uint8_t num_bits) {
370 uint32_t result = 0;
371 uint16_t byte_index = start_bit / 8;
372 uint8_t bit_offset = start_bit % 8;
373
374 for (int i = 0; i < num_bits; i++) {
375 // SD card registers are big-endian, bit 127 is MSB of first byte
376 if (data[byte_index] & (1 << (7 - bit_offset))) {
377 result |= (1 << (num_bits - 1 - i));
378 }
379
380 bit_offset++;
381 if (bit_offset >= 8) {
382 bit_offset = 0;
383 byte_index++;
384 }
385 }
386
387 return result;
388}
389
Common utility module public API.
bool str_cmp(const char *str1, const char *str2)
Compares two null-terminated strings for equality.
Definition common.c:248
int str_to_int(const char *str)
Converts a decimal string to an integer.
Definition common.c:69
int str_cpy(char *str_to, const char *str_from, uint32_t len)
Copies a null-terminated string into a destination buffer.
Definition common.c:333
uint32_t extract_bits(const uint8_t *data, uint16_t start_bit, uint8_t num_bits)
Extracts a range of bits from a big-endian byte array.
Definition common.c:369
void hex_byte_to_str(uint8_t byte, char *str)
Converts a single byte to a two-character uppercase hexadecimal string.
Definition common.c:175
void str_set(char *target_str, char const *host_str, uint32_t host_str_len, uint32_t pos)
Overwrites a region of a target string with the contents of a source string.
Definition common.c:195
uint8_t ascii_hex_to_byte(char high, char low)
Converts two ASCII hex characters into a single byte value.
Definition common.c:265
uint32_t get_str_len(char const *str)
Returns the length of a string, excluding the null terminator.
Definition common.c:22
void double_to_str(double num, char *str, int8_t frac_digits)
Converts a double to a decimal string with a fixed number of fractional digits.
Definition common.c:102
bool str_to_bool(char const *str)
Converts a string representation of a boolean to a bool value.
Definition common.c:320
bool is_pow(uint32_t num)
Checks whether a number is a power of two.
Definition common.c:364
int str_tokenize(char *str, const char *separator, uint16_t max_tokens, char **tokens, uint16_t *num_tokens)
Splits a string into tokens separated by a given delimiter.
Definition common.c:287
int txt_cpy(char *txt_to, const char *txt_from, uint32_t len)
Copies a fixed-length block of text into a destination buffer.
Definition common.c:350
void int_to_str(int num, char *str)
Converts an integer to its decimal string representation.
Definition common.c:33
int32_t get_pow(int32_t base, int32_t exponent)
Computes an integer power.
Definition common.c:220
void arr_cmprs(char *arr, uint8_t len)
Compresses an array by removing null bytes and shifting remaining elements left.
Definition common.c:231