Last active
March 4, 2020 22:52
-
-
Save sleepdefic1t/ce02192a6b33487cb2b6b5b37df703b9 to your computer and use it in GitHub Desktop.
Print Numbers and Token Amounts as Strings in C
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef TOKEN_PRINTING_H | |
#define TOKEN_PRINTING_H | |
#include <stddef.h> | |
#include <stdint.h> | |
#include <string.h> | |
//////////////////////////////////////////////////////////////////////////////// | |
static size_t adjustDecimals(const char *src, size_t srcSize, | |
char *target, size_t targetSize, | |
uint8_t decimals) { | |
size_t startOffset; | |
size_t lastZeroOffset = 0; | |
size_t offset = 0; | |
if ((srcSize == 1) && (*src == '0')) { | |
if (targetSize < 2) { | |
return 0; | |
} | |
target[offset++] = '0'; | |
target[offset++] = '\0'; | |
return offset; | |
} | |
if (srcSize <= decimals) { | |
size_t delta = decimals - srcSize; | |
if (targetSize < srcSize + 1 + 2 + delta) { | |
return offset; | |
} | |
target[offset++] = '0'; | |
if (decimals > 0) { | |
target[offset++] = '.'; | |
} | |
for (size_t i = 0; i < delta; i++) { | |
target[offset++] = '0'; | |
} | |
startOffset = offset; | |
for (size_t i = 0; i < srcSize; i++) { | |
target[offset++] = src[i]; | |
} | |
target[offset] = '\0'; | |
} | |
else { | |
size_t sourceOffset = 0; | |
size_t delta = srcSize - decimals; | |
if (targetSize < srcSize + 1 + 1) { | |
return offset; | |
} | |
while (offset < delta) { | |
target[offset++] = src[sourceOffset++]; | |
} | |
if (decimals != 0) { | |
target[offset++] = '.'; | |
} | |
startOffset = offset; | |
while (sourceOffset < srcSize) { | |
target[offset++] = src[sourceOffset++]; | |
} | |
target[offset] = '\0'; | |
} | |
for (size_t i = startOffset; i < offset; i++) { | |
if (target[i] == '0') { | |
if (lastZeroOffset == 0) { | |
lastZeroOffset = i; | |
} | |
} | |
else { | |
lastZeroOffset = 0; | |
} | |
} | |
if (lastZeroOffset != 0) { | |
target[lastZeroOffset] = '\0'; | |
if (target[lastZeroOffset - 1] == '.') { | |
target[lastZeroOffset - 1] = '\0'; | |
} | |
} | |
return offset + lastZeroOffset; | |
} | |
//////////////////////////////////////////////////////////////////////////////// | |
size_t UintToString(uint64_t value, char *dst, size_t maxLen) { | |
if (dst == NULL || maxLen < 2) { | |
return 0; | |
} | |
if (value == 0) { | |
dst[0] = '0'; | |
dst[1] = '\0'; | |
return 2; | |
} | |
uint64_t base = 1; | |
size_t n = 0; | |
size_t i = 0; | |
const size_t maxN = 20; | |
// count how many characters are needed | |
while (base <= value && n <= maxN) { | |
base *= 0x0A; | |
n++; | |
} | |
if (n > maxLen - 1) { | |
dst[0] = '\0'; | |
return 0; | |
} | |
base /= 0x0A; | |
while (i < n) { | |
dst[i++] = '0' + ((value / base) % 0x0A); | |
base /= 0x0A; | |
} | |
dst[i] = '\0'; | |
return n + 1; | |
} | |
//////////////////////////////////////////////////////////////////////////////// | |
size_t TokenAmountToString(uint64_t amount, | |
char *dst, size_t maxLen, | |
const char *tokenName, size_t tokenNameSize, | |
uint8_t decimals) { | |
if (dst == NULL) { | |
return 0; | |
} | |
if (tokenNameSize > 0) { | |
memcpy(dst, tokenName, tokenNameSize); | |
} | |
if (decimals == 0) { | |
return tokenNameSize + UintToString(amount, dst + tokenNameSize, maxLen); | |
} | |
else { | |
char buffer[25]; | |
const size_t len = UintToString(amount, buffer, maxLen); | |
return tokenNameSize + | |
adjustDecimals(buffer, len, dst + tokenNameSize, maxLen, decimals + 1);; | |
} | |
} | |
#endif // TOKEN_PRINTING_H |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment