From 7d6795804d1c29097de471c54d5a6cb34b240f79 Mon Sep 17 00:00:00 2001 From: Rodrigo Garcia Date: Tue, 17 May 2022 21:56:59 -0300 Subject: [PATCH] Extends String to print 64-bit integers --- cores/esp32/WString.cpp | 43 +++++++++++++++++++++++++++++++++ cores/esp32/WString.h | 20 ++++++++++++++++ cores/esp32/stdlib_noniso.c | 48 +++++++++++++++++++++++++++++++++++++ cores/esp32/stdlib_noniso.h | 4 ++++ 4 files changed, 115 insertions(+) diff --git a/cores/esp32/WString.cpp b/cores/esp32/WString.cpp index f69302a253f..f31024ea8ba 100644 --- a/cores/esp32/WString.cpp +++ b/cores/esp32/WString.cpp @@ -137,6 +137,24 @@ String::String(double value, unsigned int decimalPlaces) { } } +String::String(long long value, unsigned char base) { + init(); + char buf[2 + 8 * sizeof(long long)]; + if (base==10) { + sprintf(buf, "%lld", value); // NOT SURE - NewLib Nano ... does it support %lld? + } else { + lltoa(value, buf, base); + } + *this = buf; +} + +String::String(unsigned long long value, unsigned char base) { + init(); + char buf[1 + 8 * sizeof(unsigned long long)]; + ulltoa(value, buf, base); + *this = buf; +} + String::~String() { invalidate(); } @@ -408,6 +426,17 @@ unsigned char String::concat(double num) { return concat(string, strlen(string)); } +unsigned char String::concat(long long num) { + char buf[2 + 3 * sizeof(long long)]; + return concat(buf, sprintf(buf, "%lld", num)); // NOT SURE - NewLib Nano ... does it support %lld? +} + +unsigned char String::concat(unsigned long long num) { + char buf[1 + 3 * sizeof(unsigned long long)]; + ulltoa(num, buf, 10); + return concat(buf, strlen(buf)); +} + unsigned char String::concat(const __FlashStringHelper * str) { if (!str) return 0; int length = strlen_P((PGM_P)str); @@ -493,6 +522,20 @@ StringSumHelper & operator +(const StringSumHelper &lhs, double num) { return a; } +StringSumHelper & operator +(const StringSumHelper &lhs, long long num) { + StringSumHelper &a = const_cast(lhs); + if(!a.concat(num)) + a.invalidate(); + return a; +} + +StringSumHelper & operator +(const StringSumHelper &lhs, unsigned long long num) { + StringSumHelper &a = const_cast(lhs); + if(!a.concat(num)) + a.invalidate(); + return a; +} + StringSumHelper & operator + (const StringSumHelper &lhs, const __FlashStringHelper *rhs) { StringSumHelper &a = const_cast(lhs); diff --git a/cores/esp32/WString.h b/cores/esp32/WString.h index 3190a247dda..99e85e0df52 100644 --- a/cores/esp32/WString.h +++ b/cores/esp32/WString.h @@ -73,6 +73,8 @@ class String { explicit String(unsigned long, unsigned char base = 10); explicit String(float, unsigned int decimalPlaces = 2); explicit String(double, unsigned int decimalPlaces = 2); + explicit String(long long, unsigned char base = 10); + explicit String(unsigned long long, unsigned char base = 10); ~String(void); // memory management @@ -122,6 +124,8 @@ class String { unsigned char concat(unsigned long num); unsigned char concat(float num); unsigned char concat(double num); + unsigned char concat(long long num); + unsigned char concat(unsigned long long num); unsigned char concat(const __FlashStringHelper * str); // if there's not enough memory for the concatenated value, the string @@ -166,6 +170,14 @@ class String { concat(num); return (*this); } + String & operator +=(long long num) { + concat(num); + return (*this); + } + String & operator +=(unsigned long long num) { + concat(num); + return (*this); + } String & operator += (const __FlashStringHelper *str){ concat(str); return (*this); @@ -182,6 +194,8 @@ class String { friend StringSumHelper & operator +(const StringSumHelper &lhs, float num); friend StringSumHelper & operator +(const StringSumHelper &lhs, double num); friend StringSumHelper & operator +(const StringSumHelper &lhs, const __FlashStringHelper *rhs); + friend StringSumHelper & operator +(const StringSumHelper &lhs, long long num); + friend StringSumHelper & operator +(const StringSumHelper &lhs, unsigned long long num); // comparison (only works w/ Strings and "strings") operator StringIfHelperType() const { @@ -373,6 +387,12 @@ class StringSumHelper: public String { StringSumHelper(double num) : String(num) { } + StringSumHelper(long long num) : + String(num) { + } + StringSumHelper(unsigned long long num) : + String(num) { + } }; extern const String emptyString; diff --git a/cores/esp32/stdlib_noniso.c b/cores/esp32/stdlib_noniso.c index e66edace7e3..d30febd97f8 100644 --- a/cores/esp32/stdlib_noniso.c +++ b/cores/esp32/stdlib_noniso.c @@ -67,6 +67,31 @@ char* ltoa(long value, char* result, int base) { return result; } +char* lltoa (long long val, char* result, int base) { + if(base < 2 || base > 16) { + *result = 0; + return result; + } + + char* out = result; + long long quotient = val > 0 ? val : -val; + + do { + const long long tmp = quotient / base; + *out = "0123456789abcdef"[quotient - (tmp * base)]; + ++out; + quotient = tmp; + } while(quotient); + + // Apply negative sign + if(val < 0) + *out++ = '-'; + + reverse(result, out); + *out = 0; + return result; +} + char* ultoa(unsigned long value, char* result, int base) { if(base < 2 || base > 16) { *result = 0; @@ -88,6 +113,27 @@ char* ultoa(unsigned long value, char* result, int base) { return result; } +char* ulltoa (unsigned long long val, char* result, int base) { + if(base < 2 || base > 16) { + *result = 0; + return result; + } + + char* out = result; + unsigned long long quotient = val; + + do { + const unsigned long long tmp = quotient / base; + *out = "0123456789abcdef"[quotient - (tmp * base)]; + ++out; + quotient = tmp; + } while(quotient); + + reverse(result, out); + *out = 0; + return result; +} + char * dtostrf(double number, signed int width, unsigned int prec, char *s) { bool negative = false; @@ -160,3 +206,5 @@ char * dtostrf(double number, signed int width, unsigned int prec, char *s) { *out = 0; return s; } + + diff --git a/cores/esp32/stdlib_noniso.h b/cores/esp32/stdlib_noniso.h index e5bb44e563a..8356c1199aa 100644 --- a/cores/esp32/stdlib_noniso.h +++ b/cores/esp32/stdlib_noniso.h @@ -35,10 +35,14 @@ char* itoa (int val, char *s, int radix); char* ltoa (long val, char *s, int radix); +char* lltoa (long long val, char* s, int radix); + char* utoa (unsigned int val, char *s, int radix); char* ultoa (unsigned long val, char *s, int radix); +char* ulltoa (unsigned long long val, char* s, int radix); + char* dtostrf (double val, signed int width, unsigned int prec, char *s); #ifdef __cplusplus