From d5aea6311de36ba9fae8e865a127fab4b8195f96 Mon Sep 17 00:00:00 2001 From: PiotrekB416 Date: Sat, 2 Sep 2023 00:12:50 +0200 Subject: [PATCH 1/8] Add String.insert --- api/String.cpp | 22 +++++++++++---- api/String.h | 4 ++- test/CMakeLists.txt | 1 + test/src/String/test_insert.cpp | 47 +++++++++++++++++++++++++++++++++ 4 files changed, 68 insertions(+), 6 deletions(-) create mode 100644 test/src/String/test_insert.cpp diff --git a/api/String.cpp b/api/String.cpp index 0a5c11fe..a32fa5fa 100644 --- a/api/String.cpp +++ b/api/String.cpp @@ -234,10 +234,10 @@ void String::move(String &rhs) String & String::operator = (const String &rhs) { if (this == &rhs) return *this; - + if (rhs.buffer) copy(rhs.buffer, rhs.len); else invalidate(); - + return *this; } @@ -253,7 +253,7 @@ String & String::operator = (const char *cstr) { if (cstr) copy(cstr, strlen(cstr)); else invalidate(); - + return *this; } @@ -484,7 +484,7 @@ bool String::equalsIgnoreCase( const String &s2 ) const const char *p2 = s2.buffer; while (*p1) { if (tolower(*p1++) != tolower(*p2++)) return false; - } + } return true; } @@ -515,7 +515,7 @@ char String::charAt(unsigned int loc) const return operator[](loc); } -void String::setCharAt(unsigned int loc, char c) +void String::setCharAt(unsigned int loc, char c) { if (loc < len) buffer[loc] = c; } @@ -631,6 +631,18 @@ String String::substring(unsigned int left, unsigned int right) const /* Modification */ /*********************************************/ +void String::insert(const String &str, unsigned int index, unsigned int length) +{ + if (index > len) return; + length = length < str.len ? length : str.len; + unsigned int size = len + length; + if (size > capacity && !changeBuffer(size)) return; // XXX: tell user! + memmove(buffer + index + length, buffer + index, len - index + length); + memcpy(buffer + index, str.buffer, length); + len += length; + return; +} + void String::replace(char find, char replace) { if (!buffer) return; diff --git a/api/String.h b/api/String.h index 03ecf442..0631c503 100644 --- a/api/String.h +++ b/api/String.h @@ -206,7 +206,9 @@ class String String substring( unsigned int beginIndex, unsigned int endIndex ) const; // modification - void replace(char find, char replace); + void insert(char c, unsigned int index) { return insert(&c, index, 1); }; + void insert(const String &str, unsigned int index, unsigned int length); + void replace(char find, char replace); void replace(const String& find, const String& replace); void remove(unsigned int index); void remove(unsigned int index, unsigned int count); diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 2df2eacf..41abe8da 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -72,6 +72,7 @@ set(TEST_SRCS src/String/test_indexOf.cpp src/String/test_lastIndexOf.cpp src/String/test_length.cpp + src/String/test_insert.cpp src/String/test_move.cpp src/String/test_remove.cpp src/String/test_replace.cpp diff --git a/test/src/String/test_insert.cpp b/test/src/String/test_insert.cpp new file mode 100644 index 00000000..62527b28 --- /dev/null +++ b/test/src/String/test_insert.cpp @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2023 Arduino. All rights reserved. + */ + +/************************************************************************************** + * INCLUDE + **************************************************************************************/ + +#include + +#include + +#include "StringPrinter.h" + +/************************************************************************************** + * TEST CODE + **************************************************************************************/ + +TEST_CASE ("Testing String::insert(char, index)", "[String-insert-01]") +{ + arduino::String str = "ello"; + str.insert('h', 0); + REQUIRE(str == String("hello")); +} + +TEST_CASE ("Testing String::insert(char, index) with index > length", "[String-insert-02]") +{ + arduino::String str = "Hello Arduino"; + str.insert('!', str.length() + 1); + REQUIRE(str == String("Hello Arduino")); +} + + +TEST_CASE ("Testing String::insert(String, index, length) with length >= inserted length", "[String-insert-03]") +{ + arduino::String str = "hello "; + str.insert("world", str.length(), 5); + REQUIRE(str == String("hello world")); +} + +TEST_CASE ("Testing String::insert(String, index, length) with length < inserted length", "[String-insert-04]") +{ + arduino::String str = "Hello "; + str.insert("Arduino 1234", str.length(), 7); + REQUIRE(str == String("Hello Arduino")); +} + From feaaa31719895bd999028161a7aef3af0c32b421 Mon Sep 17 00:00:00 2001 From: Piotr Bartoszewicz <89194651+PiotrekB416@users.noreply.github.com> Date: Sat, 2 Sep 2023 00:22:12 +0200 Subject: [PATCH 2/8] Fix formatting --- api/String.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/String.h b/api/String.h index 0631c503..f544155a 100644 --- a/api/String.h +++ b/api/String.h @@ -207,8 +207,8 @@ class String // modification void insert(char c, unsigned int index) { return insert(&c, index, 1); }; - void insert(const String &str, unsigned int index, unsigned int length); - void replace(char find, char replace); + void insert(const String &str, unsigned int index, unsigned int length); + void replace(char find, char replace); void replace(const String& find, const String& replace); void remove(unsigned int index); void remove(unsigned int index, unsigned int count); From 16a22bab9cd6745245eb10617fa6994e6bb6e53d Mon Sep 17 00:00:00 2001 From: PiotrekB416 Date: Sat, 2 Sep 2023 12:07:59 +0200 Subject: [PATCH 3/8] Add Stream.readLine --- api/Stream.cpp | 8 ++++++ api/Stream.h | 5 ++-- test/src/Stream/test_readLine.cpp | 43 +++++++++++++++++++++++++++++++ 3 files changed, 54 insertions(+), 2 deletions(-) create mode 100644 test/src/Stream/test_readLine.cpp diff --git a/api/Stream.cpp b/api/Stream.cpp index f6f9bda6..fcffc2b7 100644 --- a/api/Stream.cpp +++ b/api/Stream.cpp @@ -255,6 +255,14 @@ String Stream::readStringUntil(char terminator) return ret; } +String Stream::readLine() +{ + String ret = readStringUntil('\n'); + if (ret.endsWith("\r")) + ret = ret.substring(0, ret.length() - 1); + 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. diff --git a/api/Stream.h b/api/Stream.h index e81c71ba..b407fd73 100644 --- a/api/Stream.h +++ b/api/Stream.h @@ -67,7 +67,7 @@ class Stream : public Print 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(const char *target); // reads data from the stream until the target string is found bool find(const uint8_t *target) { return find ((const char *)target); } // returns true if target string is found, false if timed out (see setTimeout) @@ -107,6 +107,7 @@ class Stream : public Print // Arduino String functions to be added here String readString(); String readStringUntil(char terminator); + String readLine(); protected: long parseInt(char ignore) { return parseInt(SKIP_ALL, ignore); } @@ -130,4 +131,4 @@ class Stream : public Print } -using arduino::Stream; \ No newline at end of file +using arduino::Stream; diff --git a/test/src/Stream/test_readLine.cpp b/test/src/Stream/test_readLine.cpp new file mode 100644 index 00000000..29455048 --- /dev/null +++ b/test/src/Stream/test_readLine.cpp @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2023 Arduino. All rights reserved. + */ + +/************************************************************************************** + * INCLUDE + **************************************************************************************/ + +#include + +#include +#include + +/************************************************************************************** + * TEST CODE + **************************************************************************************/ + +TEST_CASE ("Testing 'readLine' with no EOL character", "[Stream-readLine-01]") +{ + StreamMock mock; + mock.setTimeout(10); + millis_autoOn(); + mock << "Hello Arduino"; + REQUIRE(mock.readLine() == arduino::String("Hello Arduino")); +} + +TEST_CASE ("Testing 'readLine' with Unix EOL character", "[Stream-readLine-02]") +{ + StreamMock mock; + mock.setTimeout(10); + millis_autoOn(); + mock << "Hello\nArduino\n"; + REQUIRE(mock.readLine() == arduino::String("Hello")); +} + +TEST_CASE ("Testing 'readLine' with DOS EOL character", "[Stream-readLine-03]") +{ + StreamMock mock; + mock.setTimeout(10); + millis_autoOn(); + mock << "Hello\r\nArduino\r\n"; + REQUIRE(mock.readLine() == arduino::String("Hello")); +} From c091a9f28adb647415067dc1be1bee795b2e7a1e Mon Sep 17 00:00:00 2001 From: PiotrekB416 Date: Sat, 2 Sep 2023 15:50:30 +0200 Subject: [PATCH 4/8] Fix Valgrind errors --- api/String.cpp | 4 ++-- api/String.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/api/String.cpp b/api/String.cpp index a32fa5fa..1e4d8418 100644 --- a/api/String.cpp +++ b/api/String.cpp @@ -636,8 +636,8 @@ void String::insert(const String &str, unsigned int index, unsigned int length) if (index > len) return; length = length < str.len ? length : str.len; unsigned int size = len + length; - if (size > capacity && !changeBuffer(size)) return; // XXX: tell user! - memmove(buffer + index + length, buffer + index, len - index + length); + if (size > capacity && !reserve(size)) return; // XXX: tell user! + memmove(buffer + index + length, buffer + index, len - index + 1); memcpy(buffer + index, str.buffer, length); len += length; return; diff --git a/api/String.h b/api/String.h index f544155a..4e904a0a 100644 --- a/api/String.h +++ b/api/String.h @@ -206,7 +206,7 @@ class String String substring( unsigned int beginIndex, unsigned int endIndex ) const; // modification - void insert(char c, unsigned int index) { return insert(&c, index, 1); }; + void insert(char c, unsigned int index) { return insert(String(c), index, 1); }; void insert(const String &str, unsigned int index, unsigned int length); void replace(char find, char replace); void replace(const String& find, const String& replace); From b7564a02c856de29df0eb7c5999ca898f9360e93 Mon Sep 17 00:00:00 2001 From: PiotrekB416 Date: Sat, 2 Sep 2023 15:57:47 +0200 Subject: [PATCH 5/8] Added String.ReadLine tests to cmake --- test/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 41abe8da..fedf7029 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -60,6 +60,7 @@ set(TEST_SRCS src/Stream/test_parseInt.cpp src/Stream/test_readBytes.cpp src/Stream/test_readBytesUntil.cpp + src/Stream/test_readLine.cpp src/Stream/test_readString.cpp src/Stream/test_readStringUntil.cpp src/Stream/test_setTimeout.cpp From 66ea4059703a22cfbb99286334374c985f5f776d Mon Sep 17 00:00:00 2001 From: Piotr Bartoszewicz <89194651+PiotrekB416@users.noreply.github.com> Date: Tue, 19 Sep 2023 22:18:22 +0200 Subject: [PATCH 6/8] Fix formatting in String.h --- api/String.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/String.h b/api/String.h index 4e904a0a..f94f4add 100644 --- a/api/String.h +++ b/api/String.h @@ -207,8 +207,8 @@ class String // modification void insert(char c, unsigned int index) { return insert(String(c), index, 1); }; - void insert(const String &str, unsigned int index, unsigned int length); - void replace(char find, char replace); + void insert(const String &str, unsigned int index, unsigned int length); + void replace(char find, char replace); void replace(const String& find, const String& replace); void remove(unsigned int index); void remove(unsigned int index, unsigned int count); From b9ef2e8a8c42c0f11c13613d6bbb54dd479065ae Mon Sep 17 00:00:00 2001 From: PiotrekB416 Date: Sun, 1 Oct 2023 10:29:07 +0200 Subject: [PATCH 7/8] Updated test_instert --- test/src/String/test_insert.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/src/String/test_insert.cpp b/test/src/String/test_insert.cpp index 62527b28..4ef708b3 100644 --- a/test/src/String/test_insert.cpp +++ b/test/src/String/test_insert.cpp @@ -8,7 +8,7 @@ #include -#include +#include #include "StringPrinter.h" From 96368e26414b0697179e125d055f486876c8cd2b Mon Sep 17 00:00:00 2001 From: PiotrekB416 Date: Sun, 1 Oct 2023 16:21:02 +0200 Subject: [PATCH 8/8] Replace manually removing '\r' with string.remove --- api/Stream.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/Stream.cpp b/api/Stream.cpp index fcffc2b7..df361997 100644 --- a/api/Stream.cpp +++ b/api/Stream.cpp @@ -259,7 +259,7 @@ String Stream::readLine() { String ret = readStringUntil('\n'); if (ret.endsWith("\r")) - ret = ret.substring(0, ret.length() - 1); + ret.remove(ret.length()-1); return ret; }