1 /*
2  * Copyright 2018 Oticon A/S
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <stdlib.h>
8 #include <stdint.h>
9 #include <string.h>
10 #include <stdio.h>
11 #include "bs_string.h"
12 #include "bs_tracing.h"
13 
14 /**
15  * Return how many chars (digits) a number will occupy as a string
16  */
bs_number_strlen(long long int a)17 int bs_number_strlen(long long int a) {
18   int c = 0;
19   if (a < 0) {
20     c++;
21     a=-a;
22   }
23   do {
24     c++;
25     a/=10;
26   } while (a != 0);
27   return c;
28 }
29 
30 /**
31  * Convert a bs_time_t into a string.
32  * The format will always be: hh:mm:ss.ssssss\0
33  *  hour will not wrap at 24 hours, but it will be truncated to 2 digits (so 161hours = 61)
34  *
35  * Note: the caller has to allocate the destination buffer == 16 chars
36  */
bs_time_to_str(char * dest,bs_time_t time)37 char * bs_time_to_str(char* dest, bs_time_t time) {
38   if ( time != TIME_NEVER ){
39     uint hour;
40     uint minute;
41     uint second;
42     uint us;
43 
44     hour   = ( time/3600/1000000 ) % 100;
45     minute = ( time/60/1000000 ) % 60;
46     second = ( time/1000000 ) % 60;
47     us     = time % 1000000;
48 
49     sprintf(dest,"%02u:%02u:%02u.%06u",hour, minute, second,us);
50   } else {
51     sprintf(dest," NEVER/UNKNOWN ");
52   }
53   return dest;
54 }
55 
56 /**
57  * Function to dump a set of bytes as a Hexadecimal string
58  * The caller allocates <buffer> with at least nbytes*3 + 1 bytes
59  */
bs_hex_dump(char * buffer,const uint8_t * bytes,size_t nbytes)60 void bs_hex_dump(char* buffer, const uint8_t *bytes, size_t nbytes) {
61   size_t ni,no = 0;
62   buffer[0] = 0; //in case nbytes is 0, we terminate the string
63   if ( nbytes >= 1 ) {
64     for ( ni = 0; ni < nbytes -1; ni++){
65       sprintf(&buffer[no], "%02X ", bytes[ni]);
66       no +=3;
67     }
68     sprintf(&buffer[no], "%02X", bytes[nbytes-1]);
69   }
70 }
71 
72 /**
73  * Convert a single hexadecimal (ASCII) char to an integer
74  */
valuefromhexchar(char a)75 static inline uint8_t valuefromhexchar(char a) {
76   if ( ( a >= '0' ) && ( a <= '9') ) {
77     return a - '0';
78   } else if ( ( a >= 'A' ) && ( a <= 'F' ) ) {
79     return a - 'A' + 0xA;
80   } else if ( ( a >= 'a' ) && ( a <= 'f' ) ) {
81     return a - 'a' + 0xA;
82   } else {
83     bs_trace_error_line("Character '%c' is not valid hexadecimal\n",a);
84     return -1;
85   }
86 }
87 
88 /**
89  * Read back into buffer a HexDump of another buffer
90  * (maximum size bytes)
91  */
bs_read_hex_dump(char * s,uint8_t * buffer,uint size)92 void bs_read_hex_dump(char *s,uint8_t *buffer, uint size) {
93   uint ni = 0;
94   uint no = 0;
95   while ( s[ni] != 0 && no < size ){
96     if (s[ni] != 0 && s[ni+1]!= 0){
97       buffer[no] = valuefromhexchar(s[ni])*16;
98       buffer[no] += valuefromhexchar(s[ni+1]);
99       ni+=2;
100     } else {
101       break;
102     }
103     if ( s[ni]!= 0 )
104       ni++;
105     no++;
106   }
107 }
108