Embedded SDK
Embedded SDK
Loading...
Searching...
No Matches
format.c
Go to the documentation of this file.
1/*****************************************************************************
2 * (c) 2020 Ledger SAS.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *****************************************************************************/
16
17#include <stddef.h> // size_t
18#include <stdint.h> // int*_t, uint*_t
19#include <string.h> // strncpy, memmove
20#include <stdbool.h> // bool
21
22#include "format.h"
23
24bool format_i64(char *dst, size_t dst_len, const int64_t value)
25{
26 char temp[] = "-9223372036854775808";
27
28 char *ptr = temp;
29 int64_t num = value;
30 int sign = 1;
31
32 if (value < 0) {
33 sign = -1;
34 }
35
36 while (num != 0) {
37 *ptr++ = '0' + (num % 10) * sign;
38 num /= 10;
39 }
40
41 if (value < 0) {
42 *ptr++ = '-';
43 }
44 else if (value == 0) {
45 *ptr++ = '0';
46 }
47
48 int distance = (ptr - temp) + 1;
49
50 if ((int) dst_len < distance) {
51 return false;
52 }
53
54 size_t index = 0;
55
56 while (--ptr >= temp) {
57 dst[index++] = *ptr;
58 }
59
60 dst[index] = '\0';
61
62 return true;
63}
64
65bool format_u64(char *out, size_t outLen, uint64_t in)
66{
67 size_t i = 0;
68
69 if (outLen == 0) {
70 return false;
71 }
72 outLen--;
73
74 while (in > 9) {
75 out[i] = in % 10 + '0';
76 in /= 10;
77 i++;
78 if (i + 1 > outLen) {
79 return false;
80 }
81 }
82 out[i] = in + '0';
83 out[i + 1] = '\0';
84
85 uint8_t j = 0;
86 char tmp;
87
88 // revert the string
89 while (j < i) {
90 // swap out[j] and out[i]
91 tmp = out[j];
92 out[j] = out[i];
93 out[i] = tmp;
94
95 i--;
96 j++;
97 }
98 return true;
99}
100
101bool format_fpu64(char *dst, size_t dst_len, const uint64_t value, uint8_t decimals)
102{
103 char buffer[21] = {0};
104
105 if (!format_u64(buffer, sizeof(buffer), value)) {
106 return false;
107 }
108
109 size_t digits = strlen(buffer);
110
111 if (digits <= decimals) {
112 if (dst_len <= 2 + decimals - digits) {
113 return false;
114 }
115 *dst++ = '0';
116 *dst++ = '.';
117 for (uint16_t i = 0; i < decimals - digits; i++, dst++) {
118 *dst = '0';
119 }
120 dst_len -= 2 + decimals - digits;
121 strncpy(dst, buffer, dst_len);
122 }
123 else {
124 if (dst_len <= digits + 1 + decimals) {
125 return false;
126 }
127
128 const size_t shift = digits - decimals;
129 memmove(dst, buffer, shift);
130 dst[shift] = '.';
131 strncpy(dst + shift + 1, buffer + shift, decimals);
132 }
133
134 return true;
135}
136
137bool format_fpu64_trimmed(char *dst, size_t dst_len, const uint64_t value, uint8_t decimals)
138{
139 if (!format_fpu64(dst, dst_len, value, decimals)) {
140 return false;
141 }
142
143 size_t len = strlen(dst);
144
145 while (len > 0 && (dst[len - 1] == '0' || dst[len - 1] == '.')) {
146 if (dst[len - 1] == '.') {
147 dst[len - 1] = '\0';
148 return true;
149 }
150 len--;
151 }
152 dst[len] = '\0';
153 return true;
154}
155
156int format_hex(const uint8_t *in, size_t in_len, char *out, size_t out_len)
157{
158 if (out_len < 2 * in_len + 1) {
159 return -1;
160 }
161
162 const char hex[] = "0123456789ABCDEF";
163 size_t i = 0;
164 int written = 0;
165
166 while (i < in_len && (i * 2 + (2 + 1)) <= out_len) {
167 uint8_t high_nibble = (in[i] & 0xF0) >> 4;
168 *out = hex[high_nibble];
169 out++;
170
171 uint8_t low_nibble = in[i] & 0x0F;
172 *out = hex[low_nibble];
173 out++;
174
175 i++;
176 written += 2;
177 }
178
179 *out = '\0';
180
181 return written + 1;
182}
bool format_u64(char *out, size_t outLen, uint64_t in)
Definition format.c:65
int format_hex(const uint8_t *in, size_t in_len, char *out, size_t out_len)
Definition format.c:156
bool format_fpu64_trimmed(char *dst, size_t dst_len, const uint64_t value, uint8_t decimals)
Definition format.c:137
bool format_i64(char *dst, size_t dst_len, const int64_t value)
Definition format.c:24
bool format_fpu64(char *dst, size_t dst_len, const uint64_t value, uint8_t decimals)
Definition format.c:101
unsigned short uint16_t
Definition usbd_conf.h:54
unsigned char uint8_t
Definition usbd_conf.h:53