Skip to content

Commit c8ecd5f

Browse files
committed
Sync IPAddress and Wstring with SAM implementation
Test suite failed on these functions
1 parent d179695 commit c8ecd5f

File tree

4 files changed

+119
-33
lines changed

4 files changed

+119
-33
lines changed

cores/arduino/IPAddress.cpp

+42
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,48 @@ IPAddress::IPAddress(const uint8_t *address)
4343
memcpy(_address.bytes, address, sizeof(_address.bytes));
4444
}
4545

46+
bool IPAddress::fromString(const char *address)
47+
{
48+
// TODO: add support for "a", "a.b", "a.b.c" formats
49+
50+
uint16_t acc = 0; // Accumulator
51+
uint8_t dots = 0;
52+
53+
while (*address)
54+
{
55+
char c = *address++;
56+
if (c >= '0' && c <= '9')
57+
{
58+
acc = acc * 10 + (c - '0');
59+
if (acc > 255) {
60+
// Value out of [0..255] range
61+
return false;
62+
}
63+
}
64+
else if (c == '.')
65+
{
66+
if (dots == 3) {
67+
// Too much dots (there must be 3 dots)
68+
return false;
69+
}
70+
_address.bytes[dots++] = acc;
71+
acc = 0;
72+
}
73+
else
74+
{
75+
// Invalid char
76+
return false;
77+
}
78+
}
79+
80+
if (dots != 3) {
81+
// Too few dots (there must be 3 dots)
82+
return false;
83+
}
84+
_address.bytes[3] = acc;
85+
return true;
86+
}
87+
4688
IPAddress& IPAddress::operator=(const uint8_t *address)
4789
{
4890
memcpy(_address.bytes, address, sizeof(_address.bytes));

cores/arduino/IPAddress.h

+5-2
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@
2121
#define IPAddress_h
2222

2323
#include <stdint.h>
24-
#include <Printable.h>
24+
#include "Printable.h"
25+
#include "WString.h"
2526

2627
// A class to make it easier to handle and pass around IP addresses
2728

@@ -45,6 +46,9 @@ class IPAddress : public Printable {
4546
IPAddress(uint32_t address);
4647
IPAddress(const uint8_t *address);
4748

49+
bool fromString(const char *address);
50+
bool fromString(const String &address) { return fromString(address.c_str()); }
51+
4852
// Overloaded cast operator to allow IPAddress objects to be used where a pointer
4953
// to a four-byte uint8_t array is expected
5054
operator uint32_t() const { return _address.dword; };
@@ -71,5 +75,4 @@ class IPAddress : public Printable {
7175

7276
const IPAddress INADDR_NONE(0,0,0,0);
7377

74-
7578
#endif

cores/arduino/WString.cpp

+61-26
Original file line numberDiff line numberDiff line change
@@ -31,15 +31,7 @@
3131
#include <stdio.h>
3232

3333

34-
// following the C++ standard operators with attributes in right
35-
// side must be defined globally
36-
String operator + ( const char *cstr, const String &str_arg)
37-
{
38-
String &str_arg_o = const_cast<String&>(str_arg);
39-
String aux = String(cstr);
40-
aux.concat(str_arg_o);
41-
return aux;
42-
}
34+
4335
/*********************************************/
4436
/* Constructors */
4537
/*********************************************/
@@ -56,7 +48,13 @@ String::String(const String &value)
5648
*this = value;
5749
}
5850

59-
#ifdef __GXX_EXPERIMENTAL_CXX0X__
51+
String::String(const __FlashStringHelper *pstr)
52+
{
53+
init();
54+
*this = pstr;
55+
}
56+
57+
#if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__)
6058
String::String(String &&rval)
6159
{
6260
init();
@@ -162,7 +160,6 @@ inline void String::init(void)
162160
buffer = NULL;
163161
capacity = 0;
164162
len = 0;
165-
flags = 0;
166163
}
167164

168165
void String::invalidate(void)
@@ -197,18 +194,29 @@ unsigned char String::changeBuffer(unsigned int maxStrLen)
197194
/* Copy and Move */
198195
/*********************************************/
199196

200-
String & String::copy(const char *cstr, unsigned int _length)
197+
String & String::copy(const char *cstr, unsigned int length)
201198
{
202-
if (!reserve(_length)) {
199+
if (!reserve(length)) {
203200
invalidate();
204201
return *this;
205202
}
206-
len = _length;
203+
len = length;
207204
strcpy(buffer, cstr);
208205
return *this;
209206
}
210207

211-
#ifdef __GXX_EXPERIMENTAL_CXX0X__
208+
String & String::copy(const __FlashStringHelper *pstr, unsigned int length)
209+
{
210+
if (!reserve(length)) {
211+
invalidate();
212+
return *this;
213+
}
214+
len = length;
215+
strcpy_P(buffer, (PGM_P)pstr);
216+
return *this;
217+
}
218+
219+
#if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__)
212220
void String::move(String &rhs)
213221
{
214222
if (buffer) {
@@ -240,7 +248,7 @@ String & String::operator = (const String &rhs)
240248
return *this;
241249
}
242250

243-
#ifdef __GXX_EXPERIMENTAL_CXX0X__
251+
#if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__)
244252
String & String::operator = (String &&rval)
245253
{
246254
if (this != &rval) move(rval);
@@ -262,6 +270,14 @@ String & String::operator = (const char *cstr)
262270
return *this;
263271
}
264272

273+
String & String::operator = (const __FlashStringHelper *pstr)
274+
{
275+
if (pstr) copy(pstr, strlen_P((PGM_P)pstr));
276+
else invalidate();
277+
278+
return *this;
279+
}
280+
265281
/*********************************************/
266282
/* concat */
267283
/*********************************************/
@@ -359,6 +375,18 @@ unsigned char String::concat(double num)
359375
return concat(string, strlen(string));
360376
}
361377

378+
unsigned char String::concat(const __FlashStringHelper * str)
379+
{
380+
if (!str) return 0;
381+
int length = strlen_P((const char *) str);
382+
if (length == 0) return 1;
383+
unsigned int newlen = len + length;
384+
if (!reserve(newlen)) return 0;
385+
strcpy_P(buffer + len, (const char *) str);
386+
len = newlen;
387+
return 1;
388+
}
389+
362390
/*********************************************/
363391
/* Concatenate */
364392
/*********************************************/
@@ -447,6 +475,13 @@ StringSumHelper & operator + (const StringSumHelper &lhs, double num)
447475
return a;
448476
}
449477

478+
StringSumHelper & operator + (const StringSumHelper &lhs, const __FlashStringHelper *rhs)
479+
{
480+
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
481+
if (!a.concat(rhs)) a.invalidate();
482+
return a;
483+
}
484+
450485
/*********************************************/
451486
/* Comparison */
452487
/*********************************************/
@@ -639,7 +674,7 @@ String String::substring(unsigned int left, unsigned int right) const
639674
left = temp;
640675
}
641676
String out;
642-
if (left > len) return out;
677+
if (left >= len) return out;
643678
if (right > len) right = len;
644679
char temp = buffer[right]; // save the replaced character
645680
buffer[right] = '\0';
@@ -652,33 +687,33 @@ String String::substring(unsigned int left, unsigned int right) const
652687
/* Modification */
653688
/*********************************************/
654689

655-
void String::replace(char find, char _replace)
690+
void String::replace(char find, char replace)
656691
{
657692
if (!buffer) return;
658693
for (char *p = buffer; *p; p++) {
659-
if (*p == find) *p = _replace;
694+
if (*p == find) *p = replace;
660695
}
661696
}
662697

663-
void String::replace(const String& find, const String& _replace)
698+
void String::replace(const String& find, const String& replace)
664699
{
665700
if (len == 0 || find.len == 0) return;
666-
int diff = _replace.len - find.len;
701+
int diff = replace.len - find.len;
667702
char *readFrom = buffer;
668703
char *foundAt;
669704
if (diff == 0) {
670705
while ((foundAt = strstr(readFrom, find.buffer)) != NULL) {
671-
memcpy(foundAt, _replace.buffer, _replace.len);
672-
readFrom = foundAt + _replace.len;
706+
memcpy(foundAt, replace.buffer, replace.len);
707+
readFrom = foundAt + replace.len;
673708
}
674709
} else if (diff < 0) {
675710
char *writeTo = buffer;
676711
while ((foundAt = strstr(readFrom, find.buffer)) != NULL) {
677712
unsigned int n = foundAt - readFrom;
678713
memcpy(writeTo, readFrom, n);
679714
writeTo += n;
680-
memcpy(writeTo, _replace.buffer, _replace.len);
681-
writeTo += _replace.len;
715+
memcpy(writeTo, replace.buffer, replace.len);
716+
writeTo += replace.len;
682717
readFrom = foundAt + find.len;
683718
len += diff;
684719
}
@@ -697,7 +732,7 @@ void String::replace(const String& find, const String& _replace)
697732
memmove(readFrom + diff, readFrom, len - (readFrom - buffer));
698733
len += diff;
699734
buffer[len] = 0;
700-
memcpy(buffer + index, _replace.buffer, _replace.len);
735+
memcpy(buffer + index, replace.buffer, replace.len);
701736
index--;
702737
}
703738
}

cores/arduino/WString.h

+11-5
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,8 @@ class String
6363
// be false).
6464
String(const char *cstr = "");
6565
String(const String &str);
66-
#ifdef __GXX_EXPERIMENTAL_CXX0X__
66+
String(const __FlashStringHelper *str);
67+
#if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__)
6768
String(String &&rval);
6869
String(StringSumHelper &&rval);
6970
#endif
@@ -91,7 +92,8 @@ class String
9192
// marked as invalid ("if (s)" will be false).
9293
String & operator = (const String &rhs);
9394
String & operator = (const char *cstr);
94-
#ifdef __GXX_EXPERIMENTAL_CXX0X__
95+
String & operator = (const __FlashStringHelper *str);
96+
#if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__)
9597
String & operator = (String &&rval);
9698
String & operator = (StringSumHelper &&rval);
9799
#endif
@@ -113,6 +115,7 @@ class String
113115
unsigned char concat(unsigned long long num);
114116
unsigned char concat(float num);
115117
unsigned char concat(double num);
118+
unsigned char concat(const __FlashStringHelper * str);
116119

117120
// if there's not enough memory for the concatenated value, the string
118121
// will be left unchanged (but this isn't signalled in any way)
@@ -128,6 +131,7 @@ class String
128131
String & operator += (unsigned long long num) {concat(num); return (*this);}
129132
String & operator += (float num) {concat(num); return (*this);}
130133
String & operator += (double num) {concat(num); return (*this);}
134+
String & operator += (const __FlashStringHelper *str){concat(str); return (*this);}
131135

132136
friend StringSumHelper & operator + (const StringSumHelper &lhs, const String &rhs);
133137
friend StringSumHelper & operator + (const StringSumHelper &lhs, const char *cstr);
@@ -141,6 +145,7 @@ class String
141145
friend StringSumHelper & operator + (const StringSumHelper &lhs, unsigned long long num);
142146
friend StringSumHelper & operator + (const StringSumHelper &lhs, float num);
143147
friend StringSumHelper & operator + (const StringSumHelper &lhs, double num);
148+
friend StringSumHelper & operator + (const StringSumHelper &lhs, const __FlashStringHelper *rhs);
144149

145150
// comparison (only works w/ Strings and "strings")
146151
operator StringIfHelperType() const { return buffer ? &String::StringIfHelper : 0; }
@@ -196,19 +201,20 @@ class String
196201
float toFloat(void) const;
197202
char * getCSpec(int base, bool issigned, bool islong);
198203

204+
protected:
199205
char *buffer; // the actual char array
200206
unsigned int capacity; // the array length minus one (for the '\0')
201207
unsigned int len; // the String length (not counting the '\0')
202-
unsigned char flags; // unused, for future features
203-
208+
protected:
204209
void init(void);
205210
void invalidate(void);
206211
unsigned char changeBuffer(unsigned int maxStrLen);
207212
unsigned char concat(const char *cstr, unsigned int length);
208213

209214
// copy and move
210215
String & copy(const char *cstr, unsigned int length);
211-
#ifdef __GXX_EXPERIMENTAL_CXX0X__
216+
String & copy(const __FlashStringHelper *pstr, unsigned int length);
217+
#if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__)
212218
void move(String &rhs);
213219
#endif
214220
};

0 commit comments

Comments
 (0)