1
0
mirror of https://github.com/esp8266/Arduino.git synced 2025-04-19 23:22:16 +03:00

String: compatibility with 64 bits scalars (#7863)

time_t is now 64 bits. String(time_t) was ambiguous
tests added
This commit is contained in:
david gauchard 2021-02-13 17:47:47 +01:00 committed by GitHub
parent a886515ce9
commit 483519f852
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 139 additions and 4 deletions

View File

@ -98,6 +98,32 @@ String::String(unsigned long value, unsigned char base) {
*this = buf; *this = buf;
} }
String::String(long long value) {
init();
char buf[2 + 8 * sizeof(long long)];
sprintf(buf, "%lld", value);
*this = buf;
}
String::String(unsigned long long value) {
init();
char buf[1 + 8 * sizeof(unsigned long long)];
sprintf(buf, "%llu", value);
*this = buf;
}
String::String(long long value, unsigned char base) {
init();
char buf[2 + 8 * sizeof(long long)];
*this = lltoa(value, buf, sizeof(buf), base);
}
String::String(unsigned long long value, unsigned char base) {
init();
char buf[1 + 8 * sizeof(unsigned long long)];
*this = ulltoa(value, buf, sizeof(buf), base);
}
String::String(float value, unsigned char decimalPlaces) { String::String(float value, unsigned char decimalPlaces) {
init(); init();
char buf[33]; char buf[33];
@ -313,6 +339,16 @@ unsigned char String::concat(unsigned long num) {
return concat(buf, strlen(buf)); return concat(buf, strlen(buf));
} }
unsigned char String::concat(long long num) {
char buf[2 + 3 * sizeof(long long)];
return concat(buf, sprintf(buf, "%lld", num));
}
unsigned char String::concat(unsigned long long num) {
char buf[1 + 3 * sizeof(unsigned long long)];
return concat(buf, sprintf(buf, "%llu", num));
}
unsigned char String::concat(float num) { unsigned char String::concat(float num) {
char buf[20]; char buf[20];
char *string = dtostrf(num, 4, 2, buf); char *string = dtostrf(num, 4, 2, buf);

View File

@ -72,6 +72,10 @@ class String {
explicit String(unsigned int, unsigned char base = 10); explicit String(unsigned int, unsigned char base = 10);
explicit String(long, unsigned char base = 10); explicit String(long, unsigned char base = 10);
explicit String(unsigned long, unsigned char base = 10); explicit String(unsigned long, unsigned char base = 10);
explicit String(long long /* base 10 */);
explicit String(long long, unsigned char base);
explicit String(unsigned long long /* base 10 */);
explicit String(unsigned long long, unsigned char base);
explicit String(float, unsigned char decimalPlaces = 2); explicit String(float, unsigned char decimalPlaces = 2);
explicit String(double, unsigned char decimalPlaces = 2); explicit String(double, unsigned char decimalPlaces = 2);
~String() { ~String() {
@ -117,6 +121,8 @@ class String {
unsigned char concat(unsigned int num); unsigned char concat(unsigned int num);
unsigned char concat(long num); unsigned char concat(long num);
unsigned char concat(unsigned long num); unsigned char concat(unsigned long num);
unsigned char concat(long long num);
unsigned char concat(unsigned long long num);
unsigned char concat(float num); unsigned char concat(float num);
unsigned char concat(double num); unsigned char concat(double num);
unsigned char concat(const __FlashStringHelper *str); unsigned char concat(const __FlashStringHelper *str);
@ -156,6 +162,14 @@ class String {
concat(num); concat(num);
return *this; return *this;
} }
String &operator +=(long long num) {
concat(num);
return *this;
}
String &operator +=(unsigned long long num) {
concat(num);
return *this;
}
String &operator +=(float num) { String &operator +=(float num) {
concat(num); concat(num);
return *this; return *this;
@ -177,6 +191,8 @@ class String {
friend StringSumHelper &operator +(const StringSumHelper &lhs, unsigned int num); friend StringSumHelper &operator +(const StringSumHelper &lhs, unsigned int num);
friend StringSumHelper &operator +(const StringSumHelper &lhs, long num); friend StringSumHelper &operator +(const StringSumHelper &lhs, long num);
friend StringSumHelper &operator +(const StringSumHelper &lhs, unsigned long num); friend StringSumHelper &operator +(const StringSumHelper &lhs, unsigned long num);
friend StringSumHelper &operator +(const StringSumHelper &lhs, long long num);
friend StringSumHelper &operator +(const StringSumHelper &lhs, unsigned long long num);
friend StringSumHelper &operator +(const StringSumHelper &lhs, float num); friend StringSumHelper &operator +(const StringSumHelper &lhs, float num);
friend StringSumHelper &operator +(const StringSumHelper &lhs, double num); friend StringSumHelper &operator +(const StringSumHelper &lhs, double num);
friend StringSumHelper &operator +(const StringSumHelper &lhs, const __FlashStringHelper *rhs); friend StringSumHelper &operator +(const StringSumHelper &lhs, const __FlashStringHelper *rhs);
@ -375,6 +391,12 @@ class StringSumHelper: public String {
StringSumHelper(unsigned long num) : StringSumHelper(unsigned long num) :
String(num) { String(num) {
} }
StringSumHelper(long long num) :
String(num) {
}
StringSumHelper(unsigned long long num) :
String(num) {
}
StringSumHelper(float num) : StringSumHelper(float num) :
String(num) { String(num) {
} }

View File

@ -30,7 +30,7 @@ void hexdump(const void *mem, uint32_t len, uint8_t cols)
while (len > 0) while (len > 0)
{ {
uint32_t linesize = cols > len ? len : cols; uint32_t linesize = cols > len ? len : cols;
os_printf("\n[%p] 0x%04x: ", src, src - (const char*)mem); os_printf("\n[%p] 0x%04x: ", src, (int)(src - (const char*)mem));
for (uint32_t i = 0; i < linesize; i++) for (uint32_t i = 0; i < linesize; i++)
{ {
os_printf("%02x ", *(src + i)); os_printf("%02x ", *(src + i));

View File

@ -0,0 +1,62 @@
/*
stdlib_noniso.h - nonstandard (but usefull) conversion functions
Copyright (c) 2021 David Gauchard. All rights reserved.
This file is part of the esp8266 core for Arduino environment.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "stdlib_noniso.h"
// ulltoa() is slower than std::to_char() (1.6 times)
// but is smaller by ~800B/flash and ~250B/rodata
// ulltoa fills str backwards and can return a pointer different from str
char* ulltoa(unsigned long long val, char* str, int slen, unsigned int radix)
{
str += --slen;
*str = 0;
do
{
auto mod = val % radix;
val /= radix;
*--str = mod + ((mod > 9) ? ('a' - 10) : '0');
} while (--slen && val);
return val? nullptr: str;
}
// lltoa fills str backwards and can return a pointer different from str
char* lltoa (long long val, char* str, int slen, unsigned int radix)
{
bool neg;
if (val < 0)
{
val = -val;
neg = true;
}
else
{
neg = false;
}
char* ret = ulltoa(val, str, slen, radix);
if (neg)
{
if (ret == str || ret == nullptr)
return nullptr;
*--ret = '-';
}
return ret;
}

View File

@ -1,9 +1,9 @@
/* /*
stdlib_noniso.h - nonstandard (but usefull) conversion functions stdlib_noniso.h - nonstandard (but usefull) conversion functions
Copyright (c) 2014 Ivan Grokhotkov. All rights reserved. Copyright (c) 2014 Ivan Grokhotkov. All rights reserved.
This file is part of the esp8266 core for Arduino environment. This file is part of the esp8266 core for Arduino environment.
This library is free software; you can redistribute it and/or This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either License as published by the Free Software Foundation; either
@ -36,10 +36,14 @@ char* itoa (int val, char *s, int radix);
char* ltoa (long val, char *s, int radix); char* ltoa (long val, char *s, int radix);
char* lltoa (long long val, char* str, int slen, unsigned int radix);
char* utoa (unsigned int val, char *s, int radix); char* utoa (unsigned int val, char *s, int radix);
char* ultoa (unsigned long val, char *s, int radix); char* ultoa (unsigned long val, char *s, int radix);
char* ulltoa (unsigned long long val, char* str, int slen, unsigned int radix);
char* dtostrf (double val, signed char width, unsigned char prec, char *s); char* dtostrf (double val, signed char width, unsigned char prec, char *s);
void reverse(char* begin, char* end); void reverse(char* begin, char* end);

View File

@ -80,6 +80,7 @@ CORE_CPP_FILES := \
Stream.cpp \ Stream.cpp \
WString.cpp \ WString.cpp \
Print.cpp \ Print.cpp \
stdlib_noniso.cpp \
FS.cpp \ FS.cpp \
spiffs_api.cpp \ spiffs_api.cpp \
MD5Builder.cpp \ MD5Builder.cpp \

View File

@ -132,6 +132,16 @@ TEST_CASE("String concantenation", "[core][String]")
REQUIRE(str == "abcdeabcde9872147483647-2147483648691969-123321-1.01"); REQUIRE(str == "abcdeabcde9872147483647-2147483648691969-123321-1.01");
str += (double)1.01; str += (double)1.01;
REQUIRE(str == "abcdeabcde9872147483647-2147483648691969-123321-1.011.01"); REQUIRE(str == "abcdeabcde9872147483647-2147483648691969-123321-1.011.01");
str += LLONG_MIN;
REQUIRE(str == "abcdeabcde9872147483647-2147483648691969-123321-1.011.01-9223372036854775808");
str += String(LLONG_MIN, 10);
REQUIRE(str == "abcdeabcde9872147483647-2147483648691969-123321-1.011.01-9223372036854775808-9223372036854775808");
str += LLONG_MAX;
REQUIRE(str == "abcdeabcde9872147483647-2147483648691969-123321-1.011.01-9223372036854775808-92233720368547758089223372036854775807");
str += ULLONG_MAX;
REQUIRE(str == "abcdeabcde9872147483647-2147483648691969-123321-1.011.01-9223372036854775808-9223372036854775808922337203685477580718446744073709551615");
str += String(ULLONG_MAX, 16);
REQUIRE(str == "abcdeabcde9872147483647-2147483648691969-123321-1.011.01-9223372036854775808-9223372036854775808922337203685477580718446744073709551615ffffffffffffffff");
str = "clean"; str = "clean";
REQUIRE(str.concat(str) == true); REQUIRE(str.concat(str) == true);
REQUIRE(str == "cleanclean"); REQUIRE(str == "cleanclean");