From 63d75ec2804873496f9a73a8777dd298de416df3 Mon Sep 17 00:00:00 2001 From: neithanmo Date: Mon, 25 Nov 2024 19:43:51 +0100 Subject: [PATCH] Add function to convert u128 numbers to string --- app/src/constants.h | 17 +++++++++++++++ app/src/ui_utils.c | 53 +++++++++++++++++++++++++++++++++++++++++++++ app/src/ui_utils.h | 16 ++++++++++++++ 3 files changed, 86 insertions(+) diff --git a/app/src/constants.h b/app/src/constants.h index 0f59ee8..1a3ec6d 100644 --- a/app/src/constants.h +++ b/app/src/constants.h @@ -1,3 +1,20 @@ +/******************************************************************************* + * (c) 2018 - 2023 Zondax AG + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + ********************************************************************************/ +#define U128_STR_MAX_LEN 40 + // Common BECH32m constants #define CHECKSUM_LENGTH 8 #define BECH32_BITS_PER_CHAR 5 diff --git a/app/src/ui_utils.c b/app/src/ui_utils.c index 3fba8b7..2c131bb 100644 --- a/app/src/ui_utils.c +++ b/app/src/ui_utils.c @@ -63,3 +63,56 @@ parser_error_t printAssetId(uint8_t *asset, uint16_t asset_len, char *out, uint1 asset, asset_len, ASSET_ID_LEN, out, out_len); } + +parser_error_t uint128_to_str(char *data, int dataLen, uint64_t high, uint64_t low) { + if (data == NULL) return parser_no_data; + if (dataLen < U128_STR_MAX_LEN) return parser_value_out_of_range; + + MEMZERO(data, dataLen); + char *p = data; + + if (high == 0 && low == 0) { + *(p++) = '0'; + return parser_ok; + } + + uint64_t temp_high = high; + uint64_t temp_low = low; + + while (temp_high != 0 || temp_low != 0) { + if (p - data >= (dataLen - 1)) return parser_value_out_of_range; + + uint64_t quotient_high = 0; + uint64_t quotient_low = 0; + uint64_t remainder = 0; + uint64_t current; + + current = temp_high; + quotient_high = current / 10; + remainder = current % 10; + + current = (remainder << 32) | (temp_low >> 32); + uint64_t q = current / 10; + remainder = current % 10; + quotient_low = (q << 32); + + current = (remainder << 32) | (temp_low & 0xFFFFFFFF); + q = current / 10; + remainder = current % 10; + quotient_low |= q; + + *(p++) = (char)('0' + remainder); + temp_high = quotient_high; + temp_low = quotient_low; + } + + while (p > data) { + p--; + char z = *data; + *data = *p; + *p = z; + data++; + } + + return parser_ok; +} diff --git a/app/src/ui_utils.h b/app/src/ui_utils.h index 98c8b94..a91e382 100644 --- a/app/src/ui_utils.h +++ b/app/src/ui_utils.h @@ -41,3 +41,19 @@ parser_error_t printBech32Encoded(const char *prefix, uint16_t prefix_len, uint8 parser_error_t printAddress(uint8_t *address, uint16_t address_len, char *out, uint16_t out_len); parser_error_t printAssetId(uint8_t *asset, uint16_t asset_len, char *out, uint16_t out_len); + +/** + * Converts a 128-bit unsigned integer to its decimal string representation. + * Output buffer will be null terminated and cleared using MEMZERO. + * + * @param[out] data Output buffer for the resulting string + * @param[in] dataLen Size of the output buffer + * @param[in] high Upper 64 bits of the 128-bit number + * @param[in] low Lower 64 bits of the 128-bit number + * + * @return parser_error_t: + * - parser_ok on success + * - parser_no_data if data is NULL + * - parser_value_out_of_range if buffer too small (< U128_STR_MAX_LEN) + */ +parser_error_t uint128_to_str(char *data, int dataLen, uint64_t high, uint64_t low);