// // Created by xemon on 06.09.22. // #include #include #include "AsciiStringAssmeblingUtils.h" static const char ASCII_STRING_HEX_CHAR[] = "0123456789ABCDEF"; static const uint64_t ASCII_STRING_DEC_POW[] = { 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000, 10000000000, 100000000000 }; static const uint8_t ASCII_STRING_DEC_POW_LEN = (sizeof(ASCII_STRING_DEC_POW) / sizeof(uint64_t)); uint8_t vAsciiStringDecimalIntToChar(uint8_t number_0_9) { number_0_9 = number_0_9 % 10; //cutoff digits more 1 (numbers between 0 and 9) return ('0' + number_0_9); //return char of number('0' is base number in ascii) } void vAsciiStringAdd(char *string, size_t *stringLen, char *addString, size_t addStringLen) { memcpy(string + (*stringLen), addString, addStringLen); *stringLen += addStringLen; } void vAsciiStringAddChar(char *string, size_t *stringLen, uint8_t singleChar) { string[*stringLen] = singleChar; ++(*stringLen); } void vAsciiStringInit(char *string, size_t *stringLen, size_t fullLen) { memset(string, 0, fullLen); *stringLen = 0; } void vAsciiStringClean(char *string, size_t *stringLen) { if (*stringLen == 0)return; memset(string, 0, *stringLen); *stringLen = 0; } void vAsciiStringAddDecimalInt(char *string, size_t *stringLen, uint8_t number, uint8_t digits) { for (uint8_t reverse_digit = 1; reverse_digit <= digits; ++reverse_digit) { string[*stringLen + digits - reverse_digit] = vAsciiStringDecimalIntToChar(number); number /= 10; } *stringLen += digits; } void vAsciiStringAddDecimalInt64(char *string, size_t *stringLen, uint64_t number, uint8_t digits) { for (uint8_t reverse_digit = 1; reverse_digit <= digits; ++reverse_digit) { string[*stringLen + digits - reverse_digit] = vAsciiStringDecimalIntToChar(number % 10); number /= 10; } *stringLen += digits; } void vAsciiStringSpitChars(char *one, char *two) { char tmp; tmp = *one; *one = *two; *two = tmp; } void vAsciiStringAddDecimalIntWithLimit(char *string, size_t *stringLen, int64_t number, uint8_t digitsLimit) { if (number < 0) { *(string + (*stringLen)) = '-'; ++(*stringLen); number = -number; } uint32_t cutoffNumber = 1; for (uint8_t scale = 0; scale < digitsLimit; ++scale) { cutoffNumber *= 10; } number = number % cutoffNumber; if (number == 0) { string[*stringLen] = '0'; (*stringLen) += 1; } uint8_t digits = 0; for (; (digits < digitsLimit) && (number != 0); ++digits) { string[(*stringLen) + digits] = vAsciiStringDecimalIntToChar(number % 10); number /= 10; } uint8_t reverses = digits / 2; for (uint8_t reverse_digit = 0; reverse_digit < reverses; ++reverse_digit) { vAsciiStringSpitChars(string + *stringLen + reverse_digit, string + *stringLen + digits - 1 - reverse_digit); } *stringLen += digits; } void vAsciiStringAddByteAsHex(char *str, size_t *stringLen, uint8_t number) { str[*stringLen + 0] = ASCII_STRING_HEX_CHAR[(number >> 4) & 0xF]; str[*stringLen + 1] = ASCII_STRING_HEX_CHAR[(number & 0xF)]; *stringLen += 2; } void vAsciiStringAddBytesAsHex(char *str, size_t *stringLen, uint8_t *bytesData, size_t bytesCount) { uint8_t *end = bytesData + bytesCount; while (end > bytesData) { vAsciiStringAddByteAsHex(str, stringLen, *bytesData); ++bytesData; } } static inline uint64_t get_dec_pow(uint8_t value) { if (value < ASCII_STRING_DEC_POW_LEN) { return ASCII_STRING_DEC_POW[value]; } uint64_t mux = ASCII_STRING_DEC_POW[ASCII_STRING_DEC_POW_LEN - 1]; for (uint8_t scale = ASCII_STRING_DEC_POW_LEN; scale < value; ++scale) { mux *= 10; } return mux; } void vAsciiStringAddDecimalFloatWithLimit( char *string, size_t *stringLen, double number, uint8_t intDigits, uint8_t fractionalDigits ) { uint64_t dec_mux = get_dec_pow(fractionalDigits); uint64_t intPart = (uint64_t) number; double fractional = round(number * dec_mux) / dec_mux - intPart; uint64_t fractionalPartInInteger = (uint64_t) (fractional * dec_mux); vAsciiStringAddDecimalIntWithLimit(string, stringLen, intPart, intDigits); vAsciiStringAddChar(string, stringLen, '.'); vAsciiStringAddDecimalInt64(string, stringLen, fractionalPartInInteger, fractionalDigits); }