Merge remote-tracking branch 'refs/remotes/rogerclarkmelbourne/master'

This commit is contained in:
stevstrong 2016-10-31 22:06:09 +01:00
commit 529f844ff9
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));
}
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)
{
memcpy(_address.bytes, address, sizeof(_address.bytes));

View File

@ -46,6 +46,9 @@ public:
IPAddress(uint32_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
// to a four-byte uint8_t array is expected
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);
}
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 n = print('\r');
@ -198,6 +210,20 @@ size_t Print::println(double n, int digits) {
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
#include <stdio.h>
#include <stdarg.h>

View File

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

View File

@ -268,3 +268,68 @@ String Stream::readStringUntil(char terminator)
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
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(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); }
// 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(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
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

View File

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

View File

@ -161,6 +161,10 @@ public:
void toCharArray(char *buf, unsigned int bufsize, unsigned int index=0) const
{getBytes((unsigned char *)buf, bufsize, index);}
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
int indexOf( char ch ) const;

View File

@ -44,6 +44,48 @@ IPAddress::IPAddress(const uint8_t *address)
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)
{
memcpy(_address.bytes, address, sizeof(_address.bytes));

View File

@ -46,6 +46,9 @@ public:
IPAddress(uint32_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
// to a four-byte uint8_t array is expected
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;
while (size--) {
write(*ch++);
n++;
n++;
}
return n;
}
size_t Print::print(uint8 b, int base) {
print((uint64)b, base);
return print((uint64)b, base);
}
size_t Print::print(const String &s)
@ -124,6 +124,18 @@ size_t Print::print(double n, int 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 n = print('\r');
@ -198,6 +210,20 @@ size_t Print::println(double n, int digits) {
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
#include <stdio.h>
#include <stdarg.h>

View File

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

View File

@ -268,3 +268,68 @@ String Stream::readStringUntil(char terminator)
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
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(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); }
// 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(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
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

View File

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

View File

@ -161,6 +161,10 @@ public:
void toCharArray(char *buf, unsigned int bufsize, unsigned int index=0) const
{getBytes((unsigned char *)buf, bufsize, index);}
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
int indexOf( char ch ) const;