merge minor API changes of IPAddress, Print, Stream and WString from official Arduion core source. LookaheadMode is still under evaluation.

This commit is contained in:
xymopen 2016-10-22 03:57:13 +08:00
parent 7985f25fbc
commit 1d321b6b70
16 changed files with 320 additions and 4 deletions

View File

@ -44,6 +44,48 @@ IPAddress::IPAddress(const uint8_t *address)
memcpy(_address.bytes, address, sizeof(_address.bytes)); memcpy(_address.bytes, address, sizeof(_address.bytes));
} }
bool IPAddress::fromString(const char *address)
{
// TODO: add support for "a", "a.b", "a.b.c" formats
uint16_t acc = 0; // Accumulator
uint8_t dots = 0;
while (*address)
{
char c = *address++;
if (c >= '0' && c <= '9')
{
acc = acc * 10 + (c - '0');
if (acc > 255) {
// Value out of [0..255] range
return false;
}
}
else if (c == '.')
{
if (dots == 3) {
// Too much dots (there must be 3 dots)
return false;
}
_address.bytes[dots++] = acc;
acc = 0;
}
else
{
// Invalid char
return false;
}
}
if (dots != 3) {
// Too few dots (there must be 3 dots)
return false;
}
_address.bytes[3] = acc;
return true;
}
IPAddress& IPAddress::operator=(const uint8_t *address) IPAddress& IPAddress::operator=(const uint8_t *address)
{ {
memcpy(_address.bytes, address, sizeof(_address.bytes)); memcpy(_address.bytes, address, sizeof(_address.bytes));

View File

@ -46,6 +46,9 @@ public:
IPAddress(uint32_t address); IPAddress(uint32_t address);
IPAddress(const uint8_t *address); IPAddress(const uint8_t *address);
bool fromString(const char *address);
bool fromString(const String &address) { return fromString(address.c_str()); }
// Overloaded cast operator to allow IPAddress objects to be used where a pointer // Overloaded cast operator to allow IPAddress objects to be used where a pointer
// to a four-byte uint8_t array is expected // to a four-byte uint8_t array is expected
operator uint32_t() const { return _address.dword; }; operator uint32_t() const { return _address.dword; };

View File

@ -124,6 +124,18 @@ size_t Print::print(double n, int digits) {
return printFloat(n, digits); return printFloat(n, digits);
} }
size_t Print::print(const __FlashStringHelper *ifsh)
{
size_t n = print(ifsh);
n += println();
return n;
}
size_t Print::print(const Printable& x)
{
return x.printTo(*this);
}
size_t Print::println(void) size_t Print::println(void)
{ {
size_t n = print('\r'); size_t n = print('\r');
@ -198,6 +210,20 @@ size_t Print::println(double n, int digits) {
return s; return s;
} }
size_t Print::println(const __FlashStringHelper *ifsh)
{
size_t n = print(ifsh);
n += println();
return n;
}
size_t Print::println(const Printable& x)
{
size_t n = print(x);
n += println();
return n;
}
#ifdef SUPPORTS_PRINTF #ifdef SUPPORTS_PRINTF
#include <stdio.h> #include <stdio.h>
#include <stdarg.h> #include <stdarg.h>

View File

@ -25,6 +25,7 @@
#include <libmaple/libmaple_types.h> #include <libmaple/libmaple_types.h>
#include "WString.h" #include "WString.h"
#include "Printable.h"
enum { enum {
BYTE = 0, BYTE = 0,
@ -51,6 +52,8 @@ public:
size_t print(long long, int=DEC); size_t print(long long, int=DEC);
size_t print(unsigned long long, int=DEC); size_t print(unsigned long long, int=DEC);
size_t print(double, int=2); size_t print(double, int=2);
size_t print(const __FlashStringHelper *);
size_t print(const Printable&);
size_t println(void); size_t println(void);
size_t println(const String &s); size_t println(const String &s);
size_t println(char); size_t println(char);
@ -63,6 +66,8 @@ public:
size_t println(long long, int=DEC); size_t println(long long, int=DEC);
size_t println(unsigned long long, int=DEC); size_t println(unsigned long long, int=DEC);
size_t println(double, int=2); size_t println(double, int=2);
size_t println(const __FlashStringHelper *);
size_t println(const Printable&);
#ifdef SUPPORTS_PRINTF #ifdef SUPPORTS_PRINTF
// Roger Clark. Work in progress to add printf support // Roger Clark. Work in progress to add printf support
int printf(const char * format, ...); int printf(const char * format, ...);

View File

@ -268,3 +268,68 @@ String Stream::readStringUntil(char terminator)
return ret; return ret;
} }
int Stream::findMulti( struct Stream::MultiTarget *targets, int tCount) {
// any zero length target string automatically matches and would make
// a mess of the rest of the algorithm.
for (struct MultiTarget *t = targets; t < targets+tCount; ++t) {
if (t->len <= 0)
return t - targets;
}
while (1) {
int c = timedRead();
if (c < 0)
return -1;
for (struct MultiTarget *t = targets; t < targets+tCount; ++t) {
// the simple case is if we match, deal with that first.
if (c == t->str[t->index]) {
if (++t->index == t->len)
return t - targets;
else
continue;
}
// if not we need to walk back and see if we could have matched further
// down the stream (ie '1112' doesn't match the first position in '11112'
// but it will match the second position so we can't just reset the current
// index to 0 when we find a mismatch.
if (t->index == 0)
continue;
int origIndex = t->index;
do {
--t->index;
// first check if current char works against the new current index
if (c != t->str[t->index])
continue;
// if it's the only char then we're good, nothing more to check
if (t->index == 0) {
t->index++;
break;
}
// otherwise we need to check the rest of the found string
int diff = origIndex - t->index;
size_t i;
for (i = 0; i < t->index; ++i) {
if (t->str[i] != t->str[i + diff])
break;
}
// if we successfully got through the previous loop then our current
// index is good.
if (i == t->index) {
t->index++;
break;
}
// otherwise we just try the next index
} while (t->index);
}
}
// unreachable
return -1;
}

View File

@ -55,6 +55,7 @@ class Stream : public Print
// parsing methods // parsing methods
void setTimeout(unsigned long timeout); // sets maximum milliseconds to wait for stream data, default is 1 second void setTimeout(unsigned long timeout); // sets maximum milliseconds to wait for stream data, default is 1 second
unsigned long getTimeout(void) { return _timeout; }
bool find(char *target); // reads data from the stream until the target string is found bool find(char *target); // reads data from the stream until the target string is found
bool find(uint8_t *target) { return find ((char *)target); } bool find(uint8_t *target) { return find ((char *)target); }
@ -64,6 +65,8 @@ class Stream : public Print
bool find(uint8_t *target, size_t length) { return find ((char *)target, length); } bool find(uint8_t *target, size_t length) { return find ((char *)target, length); }
// returns true if target string is found, false if timed out // returns true if target string is found, false if timed out
bool find(char target) { return find (&target, 1); }
bool findUntil(char *target, char *terminator); // as find but search ends if the terminator string is found bool findUntil(char *target, char *terminator); // as find but search ends if the terminator string is found
bool findUntil(uint8_t *target, char *terminator) { return findUntil((char *)target, terminator); } bool findUntil(uint8_t *target, char *terminator) { return findUntil((char *)target, terminator); }
@ -97,6 +100,16 @@ class Stream : public Print
// this allows format characters (typically commas) in values to be ignored // this allows format characters (typically commas) in values to be ignored
float parseFloat(char skipChar); // as above but the given skipChar is ignored float parseFloat(char skipChar); // as above but the given skipChar is ignored
struct MultiTarget {
const char *str; // string you're searching for
size_t len; // length of string you're searching for
size_t index; // index used by the search routine.
};
// This allows you to search for an arbitrary number of strings.
// Returns index of the target that is found first or -1 if timeout occurs.
int findMulti(struct MultiTarget *targets, int tCount);
}; };
#endif #endif

View File

@ -195,7 +195,7 @@ String & String::copy(const __FlashStringHelper *pstr, unsigned int length)
void String::move(String &rhs) void String::move(String &rhs)
{ {
if (buffer) { if (buffer) {
if (capacity >= rhs.len) { if (rhs && capacity >= rhs.len) {
strcpy(buffer, rhs.buffer); strcpy(buffer, rhs.buffer);
len = rhs.len; len = rhs.len;
rhs.len = 0; rhs.len = 0;

View File

@ -161,6 +161,10 @@ public:
void toCharArray(char *buf, unsigned int bufsize, unsigned int index=0) const void toCharArray(char *buf, unsigned int bufsize, unsigned int index=0) const
{getBytes((unsigned char *)buf, bufsize, index);} {getBytes((unsigned char *)buf, bufsize, index);}
const char * c_str() const { return buffer; } const char * c_str() const { return buffer; }
char* begin() { return buffer; }
char* end() { return buffer + length(); }
const char* begin() const { return c_str(); }
const char* end() const { return c_str() + length(); }
// search // search
int indexOf( char ch ) const; int indexOf( char ch ) const;

View File

@ -44,6 +44,48 @@ IPAddress::IPAddress(const uint8_t *address)
memcpy(_address.bytes, address, sizeof(_address.bytes)); memcpy(_address.bytes, address, sizeof(_address.bytes));
} }
bool IPAddress::fromString(const char *address)
{
// TODO: add support for "a", "a.b", "a.b.c" formats
uint16_t acc = 0; // Accumulator
uint8_t dots = 0;
while (*address)
{
char c = *address++;
if (c >= '0' && c <= '9')
{
acc = acc * 10 + (c - '0');
if (acc > 255) {
// Value out of [0..255] range
return false;
}
}
else if (c == '.')
{
if (dots == 3) {
// Too much dots (there must be 3 dots)
return false;
}
_address.bytes[dots++] = acc;
acc = 0;
}
else
{
// Invalid char
return false;
}
}
if (dots != 3) {
// Too few dots (there must be 3 dots)
return false;
}
_address.bytes[3] = acc;
return true;
}
IPAddress& IPAddress::operator=(const uint8_t *address) IPAddress& IPAddress::operator=(const uint8_t *address)
{ {
memcpy(_address.bytes, address, sizeof(_address.bytes)); memcpy(_address.bytes, address, sizeof(_address.bytes));

View File

@ -46,6 +46,9 @@ public:
IPAddress(uint32_t address); IPAddress(uint32_t address);
IPAddress(const uint8_t *address); IPAddress(const uint8_t *address);
bool fromString(const char *address);
bool fromString(const String &address) { return fromString(address.c_str()); }
// Overloaded cast operator to allow IPAddress objects to be used where a pointer // Overloaded cast operator to allow IPAddress objects to be used where a pointer
// to a four-byte uint8_t array is expected // to a four-byte uint8_t array is expected
operator uint32_t() const { return _address.dword; }; operator uint32_t() const { return _address.dword; };

View File

@ -60,13 +60,13 @@ size_t Print::write(const void *buffer, uint32 size) {
uint8 *ch = (uint8*)buffer; uint8 *ch = (uint8*)buffer;
while (size--) { while (size--) {
write(*ch++); write(*ch++);
n++; n++;
} }
return n; return n;
} }
size_t Print::print(uint8 b, int base) { size_t Print::print(uint8 b, int base) {
print((uint64)b, base); return print((uint64)b, base);
} }
size_t Print::print(const String &s) size_t Print::print(const String &s)
@ -124,6 +124,18 @@ size_t Print::print(double n, int digits) {
return printFloat(n, digits); return printFloat(n, digits);
} }
size_t Print::print(const __FlashStringHelper *ifsh)
{
size_t n = print(ifsh);
n += println();
return n;
}
size_t Print::print(const Printable& x)
{
return x.printTo(*this);
}
size_t Print::println(void) size_t Print::println(void)
{ {
size_t n = print('\r'); size_t n = print('\r');
@ -198,6 +210,20 @@ size_t Print::println(double n, int digits) {
return s; return s;
} }
size_t Print::println(const __FlashStringHelper *ifsh)
{
size_t n = print(ifsh);
n += println();
return n;
}
size_t Print::println(const Printable& x)
{
size_t n = print(x);
n += println();
return n;
}
#ifdef SUPPORTS_PRINTF #ifdef SUPPORTS_PRINTF
#include <stdio.h> #include <stdio.h>
#include <stdarg.h> #include <stdarg.h>

View File

@ -25,6 +25,7 @@
#include <libmaple/libmaple_types.h> #include <libmaple/libmaple_types.h>
#include "WString.h" #include "WString.h"
#include "Printable.h"
enum { enum {
BYTE = 0, BYTE = 0,
@ -51,6 +52,8 @@ public:
size_t print(long long, int=DEC); size_t print(long long, int=DEC);
size_t print(unsigned long long, int=DEC); size_t print(unsigned long long, int=DEC);
size_t print(double, int=2); size_t print(double, int=2);
size_t print(const __FlashStringHelper *);
size_t print(const Printable&);
size_t println(void); size_t println(void);
size_t println(const String &s); size_t println(const String &s);
size_t println(char); size_t println(char);
@ -63,6 +66,8 @@ public:
size_t println(long long, int=DEC); size_t println(long long, int=DEC);
size_t println(unsigned long long, int=DEC); size_t println(unsigned long long, int=DEC);
size_t println(double, int=2); size_t println(double, int=2);
size_t println(const __FlashStringHelper *);
size_t println(const Printable&);
#ifdef SUPPORTS_PRINTF #ifdef SUPPORTS_PRINTF
// Roger Clark. Work in progress to add printf support // Roger Clark. Work in progress to add printf support
int printf(const char * format, ...); int printf(const char * format, ...);

View File

@ -268,3 +268,68 @@ String Stream::readStringUntil(char terminator)
return ret; return ret;
} }
int Stream::findMulti( struct Stream::MultiTarget *targets, int tCount) {
// any zero length target string automatically matches and would make
// a mess of the rest of the algorithm.
for (struct MultiTarget *t = targets; t < targets+tCount; ++t) {
if (t->len <= 0)
return t - targets;
}
while (1) {
int c = timedRead();
if (c < 0)
return -1;
for (struct MultiTarget *t = targets; t < targets+tCount; ++t) {
// the simple case is if we match, deal with that first.
if (c == t->str[t->index]) {
if (++t->index == t->len)
return t - targets;
else
continue;
}
// if not we need to walk back and see if we could have matched further
// down the stream (ie '1112' doesn't match the first position in '11112'
// but it will match the second position so we can't just reset the current
// index to 0 when we find a mismatch.
if (t->index == 0)
continue;
int origIndex = t->index;
do {
--t->index;
// first check if current char works against the new current index
if (c != t->str[t->index])
continue;
// if it's the only char then we're good, nothing more to check
if (t->index == 0) {
t->index++;
break;
}
// otherwise we need to check the rest of the found string
int diff = origIndex - t->index;
size_t i;
for (i = 0; i < t->index; ++i) {
if (t->str[i] != t->str[i + diff])
break;
}
// if we successfully got through the previous loop then our current
// index is good.
if (i == t->index) {
t->index++;
break;
}
// otherwise we just try the next index
} while (t->index);
}
}
// unreachable
return -1;
}

View File

@ -55,6 +55,7 @@ class Stream : public Print
// parsing methods // parsing methods
void setTimeout(unsigned long timeout); // sets maximum milliseconds to wait for stream data, default is 1 second void setTimeout(unsigned long timeout); // sets maximum milliseconds to wait for stream data, default is 1 second
unsigned long getTimeout(void) { return _timeout; }
bool find(char *target); // reads data from the stream until the target string is found bool find(char *target); // reads data from the stream until the target string is found
bool find(uint8_t *target) { return find ((char *)target); } bool find(uint8_t *target) { return find ((char *)target); }
@ -64,6 +65,8 @@ class Stream : public Print
bool find(uint8_t *target, size_t length) { return find ((char *)target, length); } bool find(uint8_t *target, size_t length) { return find ((char *)target, length); }
// returns true if target string is found, false if timed out // returns true if target string is found, false if timed out
bool find(char target) { return find (&target, 1); }
bool findUntil(char *target, char *terminator); // as find but search ends if the terminator string is found bool findUntil(char *target, char *terminator); // as find but search ends if the terminator string is found
bool findUntil(uint8_t *target, char *terminator) { return findUntil((char *)target, terminator); } bool findUntil(uint8_t *target, char *terminator) { return findUntil((char *)target, terminator); }
@ -97,6 +100,16 @@ class Stream : public Print
// this allows format characters (typically commas) in values to be ignored // this allows format characters (typically commas) in values to be ignored
float parseFloat(char skipChar); // as above but the given skipChar is ignored float parseFloat(char skipChar); // as above but the given skipChar is ignored
struct MultiTarget {
const char *str; // string you're searching for
size_t len; // length of string you're searching for
size_t index; // index used by the search routine.
};
// This allows you to search for an arbitrary number of strings.
// Returns index of the target that is found first or -1 if timeout occurs.
int findMulti(struct MultiTarget *targets, int tCount);
}; };
#endif #endif

View File

@ -195,7 +195,7 @@ String & String::copy(const __FlashStringHelper *pstr, unsigned int length)
void String::move(String &rhs) void String::move(String &rhs)
{ {
if (buffer) { if (buffer) {
if (capacity >= rhs.len) { if (rhs && capacity >= rhs.len) {
strcpy(buffer, rhs.buffer); strcpy(buffer, rhs.buffer);
len = rhs.len; len = rhs.len;
rhs.len = 0; rhs.len = 0;

View File

@ -161,6 +161,10 @@ public:
void toCharArray(char *buf, unsigned int bufsize, unsigned int index=0) const void toCharArray(char *buf, unsigned int bufsize, unsigned int index=0) const
{getBytes((unsigned char *)buf, bufsize, index);} {getBytes((unsigned char *)buf, bufsize, index);}
const char * c_str() const { return buffer; } const char * c_str() const { return buffer; }
char* begin() { return buffer; }
char* end() { return buffer + length(); }
const char* begin() const { return c_str(); }
const char* end() const { return c_str() + length(); }
// search // search
int indexOf( char ch ) const; int indexOf( char ch ) const;