WString Fix int64_t (#7765)
WString Fix int64_t Fixed int64_t String support. Resolves issue #7760. Background: sprintf on esp32 doesn't support "%lld" parameter. It's possible to recompile the underlying libraries to add that option, but I have an easier solution. This has already been solved in ESP8266 version of WString by replacing sprintf() with itoa/ltoa/lltoa. This PR does the following: Fixes integer print issues by replacing sprintf() with itoa/ltoa/lltoa Moves concat(long long num), concat(unsigned long long num) location (match ESP8266) Cleans up code formatting (matches ESP8266) Co-authored-by: Me No Dev <me-no-dev@users.noreply.github.com>
This commit is contained in:
parent
024ba74068
commit
345e3c637a
2 changed files with 58 additions and 70 deletions
|
|
@ -21,7 +21,7 @@
|
||||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <Arduino.h>
|
#include "Arduino.h"
|
||||||
#include "WString.h"
|
#include "WString.h"
|
||||||
#include "stdlib_noniso.h"
|
#include "stdlib_noniso.h"
|
||||||
#include "esp32-hal-log.h"
|
#include "esp32-hal-log.h"
|
||||||
|
|
@ -80,11 +80,7 @@ String::String(unsigned char value, unsigned char base) {
|
||||||
String::String(int value, unsigned char base) {
|
String::String(int value, unsigned char base) {
|
||||||
init();
|
init();
|
||||||
char buf[2 + 8 * sizeof(int)];
|
char buf[2 + 8 * sizeof(int)];
|
||||||
if (base == 10) {
|
itoa(value, buf, base);
|
||||||
sprintf(buf, "%d", value);
|
|
||||||
} else {
|
|
||||||
itoa(value, buf, base);
|
|
||||||
}
|
|
||||||
*this = buf;
|
*this = buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -98,11 +94,7 @@ String::String(unsigned int value, unsigned char base) {
|
||||||
String::String(long value, unsigned char base) {
|
String::String(long value, unsigned char base) {
|
||||||
init();
|
init();
|
||||||
char buf[2 + 8 * sizeof(long)];
|
char buf[2 + 8 * sizeof(long)];
|
||||||
if (base==10) {
|
ltoa(value, buf, base);
|
||||||
sprintf(buf, "%ld", value);
|
|
||||||
} else {
|
|
||||||
ltoa(value, buf, base);
|
|
||||||
}
|
|
||||||
*this = buf;
|
*this = buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -140,11 +132,7 @@ String::String(double value, unsigned int decimalPlaces) {
|
||||||
String::String(long long value, unsigned char base) {
|
String::String(long long value, unsigned char base) {
|
||||||
init();
|
init();
|
||||||
char buf[2 + 8 * sizeof(long long)];
|
char buf[2 + 8 * sizeof(long long)];
|
||||||
if (base==10) {
|
lltoa(value, buf, base);
|
||||||
sprintf(buf, "%lld", value); // NOT SURE - NewLib Nano ... does it support %lld?
|
|
||||||
} else {
|
|
||||||
lltoa(value, buf, base);
|
|
||||||
}
|
|
||||||
*this = buf;
|
*this = buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -159,9 +147,9 @@ String::~String() {
|
||||||
invalidate();
|
invalidate();
|
||||||
}
|
}
|
||||||
|
|
||||||
// /*********************************************/
|
/*********************************************/
|
||||||
// /* Memory Management */
|
/* Memory Management */
|
||||||
// /*********************************************/
|
/*********************************************/
|
||||||
|
|
||||||
inline void String::init(void) {
|
inline void String::init(void) {
|
||||||
setSSO(false);
|
setSSO(false);
|
||||||
|
|
@ -221,8 +209,7 @@ bool String::changeBuffer(unsigned int maxStrLen) {
|
||||||
// Copy the SSO buffer into allocated space
|
// Copy the SSO buffer into allocated space
|
||||||
memmove(newbuffer, sso.buff, sizeof(sso.buff));
|
memmove(newbuffer, sso.buff, sizeof(sso.buff));
|
||||||
}
|
}
|
||||||
if (newSize > oldSize)
|
if (newSize > oldSize) {
|
||||||
{
|
|
||||||
memset(newbuffer + oldSize, 0, newSize - oldSize);
|
memset(newbuffer + oldSize, 0, newSize - oldSize);
|
||||||
}
|
}
|
||||||
setSSO(false);
|
setSSO(false);
|
||||||
|
|
@ -234,9 +221,9 @@ bool String::changeBuffer(unsigned int maxStrLen) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// /*********************************************/
|
/*********************************************/
|
||||||
// /* Copy and Move */
|
/* Copy and Move */
|
||||||
// /*********************************************/
|
/*********************************************/
|
||||||
|
|
||||||
String & String::copy(const char *cstr, unsigned int length) {
|
String & String::copy(const char *cstr, unsigned int length) {
|
||||||
if(!reserve(length)) {
|
if(!reserve(length)) {
|
||||||
|
|
@ -292,12 +279,10 @@ void String::move(String &rhs) {
|
||||||
String & String::operator =(const String &rhs) {
|
String & String::operator =(const String &rhs) {
|
||||||
if(this == &rhs)
|
if(this == &rhs)
|
||||||
return *this;
|
return *this;
|
||||||
|
|
||||||
if(rhs.buffer())
|
if(rhs.buffer())
|
||||||
copy(rhs.buffer(), rhs.len());
|
copy(rhs.buffer(), rhs.len());
|
||||||
else
|
else
|
||||||
invalidate();
|
invalidate();
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -320,7 +305,6 @@ String & String::operator =(const char *cstr) {
|
||||||
copy(cstr, strlen(cstr));
|
copy(cstr, strlen(cstr));
|
||||||
else
|
else
|
||||||
invalidate();
|
invalidate();
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -333,9 +317,9 @@ String & String::operator =(const __FlashStringHelper *pstr) {
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
// /*********************************************/
|
/*********************************************/
|
||||||
// /* concat */
|
/* concat */
|
||||||
// /*********************************************/
|
/*********************************************/
|
||||||
|
|
||||||
bool String::concat(const String &s) {
|
bool String::concat(const String &s) {
|
||||||
// Special case if we're concatting ourself (s += s;) since we may end up
|
// Special case if we're concatting ourself (s += s;) since we may end up
|
||||||
|
|
@ -388,12 +372,14 @@ bool String::concat(char c) {
|
||||||
|
|
||||||
bool String::concat(unsigned char num) {
|
bool String::concat(unsigned char num) {
|
||||||
char buf[1 + 3 * sizeof(unsigned char)];
|
char buf[1 + 3 * sizeof(unsigned char)];
|
||||||
return concat(buf, sprintf(buf, "%d", num));
|
utoa(num, buf, 10);
|
||||||
|
return concat(buf, strlen(buf));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool String::concat(int num) {
|
bool String::concat(int num) {
|
||||||
char buf[2 + 3 * sizeof(int)];
|
char buf[2 + 3 * sizeof(int)];
|
||||||
return concat(buf, sprintf(buf, "%d", num));
|
itoa(num, buf, 10);
|
||||||
|
return concat(buf, strlen(buf));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool String::concat(unsigned int num) {
|
bool String::concat(unsigned int num) {
|
||||||
|
|
@ -404,7 +390,8 @@ bool String::concat(unsigned int num) {
|
||||||
|
|
||||||
bool String::concat(long num) {
|
bool String::concat(long num) {
|
||||||
char buf[2 + 3 * sizeof(long)];
|
char buf[2 + 3 * sizeof(long)];
|
||||||
return concat(buf, sprintf(buf, "%ld", num));
|
ltoa(num, buf, 10);
|
||||||
|
return concat(buf, strlen(buf));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool String::concat(unsigned long num) {
|
bool String::concat(unsigned long num) {
|
||||||
|
|
@ -413,6 +400,18 @@ bool String::concat(unsigned long num) {
|
||||||
return concat(buf, strlen(buf));
|
return concat(buf, strlen(buf));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool String::concat(long long num) {
|
||||||
|
char buf[2 + 3 * sizeof(long long)];
|
||||||
|
lltoa(num, buf, 10);
|
||||||
|
return concat(buf, strlen(buf));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool String::concat(unsigned long long num) {
|
||||||
|
char buf[1 + 3 * sizeof(unsigned long long)];
|
||||||
|
ulltoa(num, buf, 10);
|
||||||
|
return concat(buf, strlen(buf));
|
||||||
|
}
|
||||||
|
|
||||||
bool String::concat(float num) {
|
bool String::concat(float num) {
|
||||||
char buf[20];
|
char buf[20];
|
||||||
char* string = dtostrf(num, 4, 2, buf);
|
char* string = dtostrf(num, 4, 2, buf);
|
||||||
|
|
@ -425,17 +424,6 @@ bool String::concat(double num) {
|
||||||
return concat(string, strlen(string));
|
return concat(string, strlen(string));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool 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?
|
|
||||||
}
|
|
||||||
|
|
||||||
bool String::concat(unsigned long long num) {
|
|
||||||
char buf[1 + 3 * sizeof(unsigned long long)];
|
|
||||||
ulltoa(num, buf, 10);
|
|
||||||
return concat(buf, strlen(buf));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool String::concat(const __FlashStringHelper * str) {
|
bool String::concat(const __FlashStringHelper * str) {
|
||||||
if (!str)
|
if (!str)
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -546,9 +534,9 @@ StringSumHelper & operator + (const StringSumHelper &lhs, const __FlashStringHel
|
||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
|
|
||||||
// /*********************************************/
|
/*********************************************/
|
||||||
// /* Comparison */
|
/* Comparison */
|
||||||
// /*********************************************/
|
/*********************************************/
|
||||||
|
|
||||||
int String::compareTo(const String &s) const {
|
int String::compareTo(const String &s) const {
|
||||||
if(!buffer() || !s.buffer()) {
|
if(!buffer() || !s.buffer()) {
|
||||||
|
|
@ -650,9 +638,9 @@ bool String::endsWith(const String &s2) const {
|
||||||
return strcmp(&buffer()[len() - s2.len()], s2.buffer()) == 0;
|
return strcmp(&buffer()[len() - s2.len()], s2.buffer()) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// /*********************************************/
|
/*********************************************/
|
||||||
// /* Character Access */
|
/* Character Access */
|
||||||
// /*********************************************/
|
/*********************************************/
|
||||||
|
|
||||||
char String::charAt(unsigned int loc) const {
|
char String::charAt(unsigned int loc) const {
|
||||||
return operator[](loc);
|
return operator[](loc);
|
||||||
|
|
@ -692,9 +680,9 @@ void String::getBytes(unsigned char *buf, unsigned int bufsize, unsigned int ind
|
||||||
buf[n] = 0;
|
buf[n] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// /*********************************************/
|
/*********************************************/
|
||||||
// /* Search */
|
/* Search */
|
||||||
// /*********************************************/
|
/*********************************************/
|
||||||
|
|
||||||
int String::indexOf(char c) const {
|
int String::indexOf(char c) const {
|
||||||
return indexOf(c, 0);
|
return indexOf(c, 0);
|
||||||
|
|
@ -703,7 +691,7 @@ int String::indexOf(char c) const {
|
||||||
int String::indexOf(char ch, unsigned int fromIndex) const {
|
int String::indexOf(char ch, unsigned int fromIndex) const {
|
||||||
if(fromIndex >= len())
|
if(fromIndex >= len())
|
||||||
return -1;
|
return -1;
|
||||||
const char* temp = strchr(buffer() + fromIndex, ch);
|
const char *temp = strchr(buffer() + fromIndex, ch);
|
||||||
if(temp == NULL)
|
if(temp == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
return temp - buffer();
|
return temp - buffer();
|
||||||
|
|
@ -773,9 +761,9 @@ String String::substring(unsigned int left, unsigned int right) const {
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
// /*********************************************/
|
/*********************************************/
|
||||||
// /* Modification */
|
/* Modification */
|
||||||
// /*********************************************/
|
/*********************************************/
|
||||||
|
|
||||||
void String::replace(char find, char replace) {
|
void String::replace(char find, char replace) {
|
||||||
if(!buffer())
|
if(!buffer())
|
||||||
|
|
@ -786,7 +774,7 @@ void String::replace(char find, char replace) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void String::replace(const String& find, const String& replace) {
|
void String::replace(const String &find, const String &replace) {
|
||||||
if(len() == 0 || find.len() == 0)
|
if(len() == 0 || find.len() == 0)
|
||||||
return;
|
return;
|
||||||
int diff = replace.len() - find.len();
|
int diff = replace.len() - find.len();
|
||||||
|
|
@ -892,9 +880,9 @@ void String::trim(void) {
|
||||||
wbuffer()[newlen] = 0;
|
wbuffer()[newlen] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// /*********************************************/
|
/*********************************************/
|
||||||
// /* Parsing / Conversion */
|
/* Parsing / Conversion */
|
||||||
// /*********************************************/
|
/*********************************************/
|
||||||
|
|
||||||
long String::toInt(void) const {
|
long String::toInt(void) const {
|
||||||
if (buffer())
|
if (buffer())
|
||||||
|
|
@ -908,8 +896,7 @@ float String::toFloat(void) const {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
double String::toDouble(void) const
|
double String::toDouble(void) const {
|
||||||
{
|
|
||||||
if (buffer())
|
if (buffer())
|
||||||
return atof(buffer());
|
return atof(buffer());
|
||||||
return 0.0;
|
return 0.0;
|
||||||
|
|
|
||||||
|
|
@ -23,15 +23,13 @@
|
||||||
#define String_class_h
|
#define String_class_h
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
||||||
|
#include <pgmspace.h>
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <stdint.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <pgmspace.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
// An inherited class for holding the result of a concatenation. These
|
|
||||||
// result objects are assumed to be writable by subsequent concatenations.
|
|
||||||
class StringSumHelper;
|
|
||||||
|
|
||||||
// an abstract class used as a means to proide a unique pointer type
|
// an abstract class used as a means to proide a unique pointer type
|
||||||
// but really has no body
|
// but really has no body
|
||||||
|
|
@ -39,6 +37,10 @@ class __FlashStringHelper;
|
||||||
#define FPSTR(pstr_pointer) (reinterpret_cast<const __FlashStringHelper *>(pstr_pointer))
|
#define FPSTR(pstr_pointer) (reinterpret_cast<const __FlashStringHelper *>(pstr_pointer))
|
||||||
#define F(string_literal) (FPSTR(PSTR(string_literal)))
|
#define F(string_literal) (FPSTR(PSTR(string_literal)))
|
||||||
|
|
||||||
|
// An inherited class for holding the result of a concatenation. These
|
||||||
|
// result objects are assumed to be writable by subsequent concatenations.
|
||||||
|
class StringSumHelper;
|
||||||
|
|
||||||
// The string class
|
// The string class
|
||||||
class String {
|
class String {
|
||||||
// use a function pointer to allow for "if (s)" without the
|
// use a function pointer to allow for "if (s)" without the
|
||||||
|
|
@ -107,7 +109,7 @@ class String {
|
||||||
String & operator =(StringSumHelper &&rval);
|
String & operator =(StringSumHelper &&rval);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// concatenate (works w/ built-in types)
|
// concatenate (works w/ built-in types, same as assignment)
|
||||||
|
|
||||||
// returns true on success, false on failure (in which case, the string
|
// returns true on success, false on failure (in which case, the string
|
||||||
// is left unchanged). if the argument is null or invalid, the
|
// is left unchanged). if the argument is null or invalid, the
|
||||||
|
|
@ -265,7 +267,6 @@ class String {
|
||||||
String substring(unsigned int beginIndex) const {
|
String substring(unsigned int beginIndex) const {
|
||||||
return substring(beginIndex, len());
|
return substring(beginIndex, len());
|
||||||
}
|
}
|
||||||
;
|
|
||||||
String substring(unsigned int beginIndex, unsigned int endIndex) const;
|
String substring(unsigned int beginIndex, unsigned int endIndex) const;
|
||||||
|
|
||||||
// modification
|
// modification
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue