Skip to content

Commit

Permalink
Reimplement SD.h write methods exactly in File (#5861)
Browse files Browse the repository at this point in the history
* Reimplement SD.h write methods exactly in File

Replace the individual override with the existing SD.h File's
implementation for all methods of File::write.

Fixes #5846

* Add add'l tests

* Fix Print and File incompatible writes w/casts

Print and File have ambiguous resolutions for single-argument
write(0)s.

Fix by adding explicit methods.  A write of any integer will not be a
const char* write (i.e. won't write a string) but will instead just
write the integer truncated to 8 bits (as makes sense).

* Use 256byte chunks in ::write template

Reduce stack requirements for templated writes to 256bytes, matching the
size uses in WiFiClient/etc. (from 512bytes).  Reduces the chance of
stack overflow.

* Move write(int) methods up to Print.h

Remove some technical debt by moving the ::write(int/short/long) methods
out of FS and HardwareSerial and up into Print.h.
  • Loading branch information
earlephilhower authored Mar 12, 2019
1 parent 192aaa4 commit 02f54e8
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 17 deletions.
24 changes: 23 additions & 1 deletion cores/esp8266/FS.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,29 @@ class File : public Stream
bool isDirectory() const;

// Arduino "class SD" methods for compatibility
size_t write(const char *str) { return write((const uint8_t*)str, strlen(str)); }
template<typename T> size_t write(T &src){
uint8_t obuf[256];
size_t doneLen = 0;
size_t sentLen;
int i;

while (src.available() > sizeof(obuf)){
src.read(obuf, sizeof(obuf));
sentLen = write(obuf, sizeof(obuf));
doneLen = doneLen + sentLen;
if(sentLen != sizeof(obuf)){
return doneLen;
}
}

size_t leftLen = src.available();
src.read(obuf, leftLen);
sentLen = write(obuf, leftLen);
doneLen = doneLen + sentLen;
return doneLen;
}
using Print::write;

void rewindDirectory();
File openNextFile();

Expand Down
16 changes: 0 additions & 16 deletions cores/esp8266/HardwareSerial.h
Original file line number Diff line number Diff line change
Expand Up @@ -152,22 +152,6 @@ class HardwareSerial: public Stream
{
return uart_write_char(_uart, c);
}
inline size_t write(unsigned long n)
{
return write((uint8_t) n);
}
inline size_t write(long n)
{
return write((uint8_t) n);
}
inline size_t write(unsigned int n)
{
return write((uint8_t) n);
}
inline size_t write(int n)
{
return write((uint8_t) n);
}
size_t write(const uint8_t *buffer, size_t size) override
{
return uart_write(_uart, (const char*)buffer, size);
Expand Down
7 changes: 7 additions & 0 deletions cores/esp8266/Print.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,13 @@ class Print {
size_t write(const char *buffer, size_t size) {
return write((const uint8_t *) buffer, size);
}
// These handle ambiguity for write(0) case, because (0) can be a pointer or an integer
size_t write(short t) { return write((uint8_t)t); }
size_t write(unsigned short t) { return write((uint8_t)t); }
size_t write(int t) { return write((uint8_t)t); }
size_t write(unsigned int t) { return write((uint8_t)t); }
size_t write(long t) { return write((uint8_t)t); }
size_t write(unsigned long t) { return write((uint8_t)t); }

size_t printf(const char * format, ...) __attribute__ ((format (printf, 2, 3)));
size_t printf_P(PGM_P format, ...) __attribute__((format(printf, 2, 3)));
Expand Down
28 changes: 28 additions & 0 deletions tests/host/fs/test_fs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -331,3 +331,31 @@ TEST_CASE("Listfiles.ino example", "[sd]")
REQUIRE(readFileSD("/dir2/dir3/file4") == "bonjour");
}

TEST_CASE("Multisplendored File::writes", "[fs]")
{
SDFS_MOCK_DECLARE();
SDFS.end();
SDFS.setConfig(SDFSConfig(0, SD_SCK_MHZ(1)));
REQUIRE(SDFS.format());
REQUIRE(SD.begin(4));

File f = SD.open("/file.txt", FILE_WRITE);
f.write('a');
f.write(65);
f.write("bbcc");
f.write("theend", 6);
char block[3]={'x','y','z'};
f.write(block, 3);
uint32_t bigone = 0x40404040;
f.write((const uint8_t*)&bigone, 4);
f.close();
REQUIRE(readFileSD("/file.txt") == "aAbbcctheendxyz@@@@");
File g = SD.open("/file.txt", FILE_WRITE);
g.write(0);
g.close();
g = SD.open("/file.txt", FILE_READ);
uint8_t u = 0x66;
g.read(&u, 1);
g.close();
REQUIRE(u == 0);
}

0 comments on commit 02f54e8

Please sign in to comment.