1
0
mirror of https://github.com/esp8266/Arduino.git synced 2025-04-19 23:22:16 +03:00

Clean up core files

- remove ICACHE_FLASH_ATTR
- remove unneeded SDK includes
- split spiffs_api into .h and .cpp
This commit is contained in:
Ivan Grokhotkov 2016-03-03 02:13:22 +03:00
parent aa67d1c492
commit 1f32b7f66e
8 changed files with 634 additions and 582 deletions

View File

@ -21,8 +21,8 @@
#ifndef FS_H #ifndef FS_H
#define FS_H #define FS_H
#include <Arduino.h>
#include <memory> #include <memory>
#include <Arduino.h>
namespace fs { namespace fs {

View File

@ -25,18 +25,14 @@
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <math.h> #include <math.h>
#include "Arduino.h" #include <Arduino.h>
#include "Print.h" #include "Print.h"
extern "C" {
#include "c_types.h"
#include "ets_sys.h"
}
// Public Methods ////////////////////////////////////////////////////////////// // Public Methods //////////////////////////////////////////////////////////////
/* default implementation: may be overridden */ /* default implementation: may be overridden */
size_t ICACHE_FLASH_ATTR Print::write(const uint8_t *buffer, size_t size) { size_t Print::write(const uint8_t *buffer, size_t size) {
size_t n = 0; size_t n = 0;
while(size--) { while(size--) {
n += write(*buffer++); n += write(*buffer++);
@ -67,7 +63,7 @@ size_t Print::printf(const char *format, ...) {
return len; return len;
} }
size_t ICACHE_FLASH_ATTR Print::print(const __FlashStringHelper *ifsh) { size_t Print::print(const __FlashStringHelper *ifsh) {
PGM_P p = reinterpret_cast<PGM_P>(ifsh); PGM_P p = reinterpret_cast<PGM_P>(ifsh);
size_t n = 0; size_t n = 0;
@ -79,31 +75,31 @@ size_t ICACHE_FLASH_ATTR Print::print(const __FlashStringHelper *ifsh) {
return n; return n;
} }
size_t ICACHE_FLASH_ATTR Print::print(const String &s) { size_t Print::print(const String &s) {
return write(s.c_str(), s.length()); return write(s.c_str(), s.length());
} }
size_t ICACHE_FLASH_ATTR Print::print(const char str[]) { size_t Print::print(const char str[]) {
return write(str); return write(str);
} }
size_t ICACHE_FLASH_ATTR Print::print(char c) { size_t Print::print(char c) {
return write(c); return write(c);
} }
size_t ICACHE_FLASH_ATTR Print::print(unsigned char b, int base) { size_t Print::print(unsigned char b, int base) {
return print((unsigned long) b, base); return print((unsigned long) b, base);
} }
size_t ICACHE_FLASH_ATTR Print::print(int n, int base) { size_t Print::print(int n, int base) {
return print((long) n, base); return print((long) n, base);
} }
size_t ICACHE_FLASH_ATTR Print::print(unsigned int n, int base) { size_t Print::print(unsigned int n, int base) {
return print((unsigned long) n, base); return print((unsigned long) n, base);
} }
size_t ICACHE_FLASH_ATTR Print::print(long n, int base) { size_t Print::print(long n, int base) {
if(base == 0) { if(base == 0) {
return write(n); return write(n);
} else if(base == 10) { } else if(base == 10) {
@ -118,86 +114,86 @@ size_t ICACHE_FLASH_ATTR Print::print(long n, int base) {
} }
} }
size_t ICACHE_FLASH_ATTR Print::print(unsigned long n, int base) { size_t Print::print(unsigned long n, int base) {
if(base == 0) if(base == 0)
return write(n); return write(n);
else else
return printNumber(n, base); return printNumber(n, base);
} }
size_t ICACHE_FLASH_ATTR Print::print(double n, int digits) { size_t Print::print(double n, int digits) {
return printFloat(n, digits); return printFloat(n, digits);
} }
size_t ICACHE_FLASH_ATTR Print::println(const __FlashStringHelper *ifsh) { size_t Print::println(const __FlashStringHelper *ifsh) {
size_t n = print(ifsh); size_t n = print(ifsh);
n += println(); n += println();
return n; return n;
} }
size_t ICACHE_FLASH_ATTR Print::print(const Printable& x) { size_t Print::print(const Printable& x) {
return x.printTo(*this); return x.printTo(*this);
} }
size_t ICACHE_FLASH_ATTR Print::println(void) { size_t Print::println(void) {
return print("\r\n"); return print("\r\n");
} }
size_t ICACHE_FLASH_ATTR Print::println(const String &s) { size_t Print::println(const String &s) {
size_t n = print(s); size_t n = print(s);
n += println(); n += println();
return n; return n;
} }
size_t ICACHE_FLASH_ATTR Print::println(const char c[]) { size_t Print::println(const char c[]) {
size_t n = print(c); size_t n = print(c);
n += println(); n += println();
return n; return n;
} }
size_t ICACHE_FLASH_ATTR Print::println(char c) { size_t Print::println(char c) {
size_t n = print(c); size_t n = print(c);
n += println(); n += println();
return n; return n;
} }
size_t ICACHE_FLASH_ATTR Print::println(unsigned char b, int base) { size_t Print::println(unsigned char b, int base) {
size_t n = print(b, base); size_t n = print(b, base);
n += println(); n += println();
return n; return n;
} }
size_t ICACHE_FLASH_ATTR Print::println(int num, int base) { size_t Print::println(int num, int base) {
size_t n = print(num, base); size_t n = print(num, base);
n += println(); n += println();
return n; return n;
} }
size_t ICACHE_FLASH_ATTR Print::println(unsigned int num, int base) { size_t Print::println(unsigned int num, int base) {
size_t n = print(num, base); size_t n = print(num, base);
n += println(); n += println();
return n; return n;
} }
size_t ICACHE_FLASH_ATTR Print::println(long num, int base) { size_t Print::println(long num, int base) {
size_t n = print(num, base); size_t n = print(num, base);
n += println(); n += println();
return n; return n;
} }
size_t ICACHE_FLASH_ATTR Print::println(unsigned long num, int base) { size_t Print::println(unsigned long num, int base) {
size_t n = print(num, base); size_t n = print(num, base);
n += println(); n += println();
return n; return n;
} }
size_t ICACHE_FLASH_ATTR Print::println(double num, int digits) { size_t Print::println(double num, int digits) {
size_t n = print(num, digits); size_t n = print(num, digits);
n += println(); n += println();
return n; return n;
} }
size_t ICACHE_FLASH_ATTR Print::println(const Printable& x) { size_t Print::println(const Printable& x) {
size_t n = print(x); size_t n = print(x);
n += println(); n += println();
return n; return n;
@ -205,7 +201,7 @@ size_t ICACHE_FLASH_ATTR Print::println(const Printable& x) {
// Private Methods ///////////////////////////////////////////////////////////// // Private Methods /////////////////////////////////////////////////////////////
size_t ICACHE_FLASH_ATTR Print::printNumber(unsigned long n, uint8_t base) { size_t Print::printNumber(unsigned long n, uint8_t base) {
char buf[8 * sizeof(long) + 1]; // Assumes 8-bit chars plus zero byte. char buf[8 * sizeof(long) + 1]; // Assumes 8-bit chars plus zero byte.
char *str = &buf[sizeof(buf) - 1]; char *str = &buf[sizeof(buf) - 1];
@ -225,7 +221,7 @@ size_t ICACHE_FLASH_ATTR Print::printNumber(unsigned long n, uint8_t base) {
return write(str); return write(str);
} }
size_t ICACHE_FLASH_ATTR Print::printFloat(double number, uint8_t digits) { size_t Print::printFloat(double number, uint8_t digits) {
size_t n = 0; size_t n = 0;
if(isnan(number)) if(isnan(number))

View File

@ -20,16 +20,13 @@
parsing functions based on TextFinder library by Michael Margolis parsing functions based on TextFinder library by Michael Margolis
*/ */
#include "Arduino.h" #include <Arduino.h>
#include "Stream.h" #include <Stream.h>
extern "C" {
#include "c_types.h"
}
#define PARSE_TIMEOUT 1000 // default number of milli-seconds to wait #define PARSE_TIMEOUT 1000 // default number of milli-seconds to wait
#define NO_SKIP_CHAR 1 // a magic char not found in a valid ASCII numeric field #define NO_SKIP_CHAR 1 // a magic char not found in a valid ASCII numeric field
// private method to read stream with timeout // private method to read stream with timeout
int ICACHE_FLASH_ATTR Stream::timedRead() { int Stream::timedRead() {
int c; int c;
_startMillis = millis(); _startMillis = millis();
do { do {
@ -42,7 +39,7 @@ int ICACHE_FLASH_ATTR Stream::timedRead() {
} }
// private method to peek stream with timeout // private method to peek stream with timeout
int ICACHE_FLASH_ATTR Stream::timedPeek() { int Stream::timedPeek() {
int c; int c;
_startMillis = millis(); _startMillis = millis();
do { do {
@ -56,7 +53,7 @@ int ICACHE_FLASH_ATTR Stream::timedPeek() {
// returns peek of the next digit in the stream or -1 if timeout // returns peek of the next digit in the stream or -1 if timeout
// discards non-numeric characters // discards non-numeric characters
int ICACHE_FLASH_ATTR Stream::peekNextDigit() { int Stream::peekNextDigit() {
int c; int c;
while(1) { while(1) {
c = timedPeek(); c = timedPeek();
@ -73,31 +70,31 @@ int ICACHE_FLASH_ATTR Stream::peekNextDigit() {
// Public Methods // Public Methods
////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////
void ICACHE_FLASH_ATTR Stream::setTimeout(unsigned long timeout) // sets the maximum number of milliseconds to wait void Stream::setTimeout(unsigned long timeout) // sets the maximum number of milliseconds to wait
{ {
_timeout = timeout; _timeout = timeout;
} }
// find returns true if the target string is found // find returns true if the target string is found
bool ICACHE_FLASH_ATTR Stream::find(const char *target) { bool Stream::find(const char *target) {
return findUntil(target, (char*) ""); return findUntil(target, (char*) "");
} }
// reads data from the stream until the target string of given length is found // reads data from the stream until the target string of given length is found
// returns true if target string is found, false if timed out // returns true if target string is found, false if timed out
bool ICACHE_FLASH_ATTR Stream::find(const char *target, size_t length) { bool Stream::find(const char *target, size_t length) {
return findUntil(target, length, NULL, 0); return findUntil(target, length, NULL, 0);
} }
// as find but search ends if the terminator string is found // as find but search ends if the terminator string is found
bool ICACHE_FLASH_ATTR Stream::findUntil(const char *target, const char *terminator) { bool Stream::findUntil(const char *target, const char *terminator) {
return findUntil(target, strlen(target), terminator, strlen(terminator)); return findUntil(target, strlen(target), terminator, strlen(terminator));
} }
// reads data from the stream until the target string of the given length is found // reads data from the stream until the target string of the given length is found
// search terminated if the terminator string is found // search terminated if the terminator string is found
// returns true if target string is found, false if terminated or timed out // returns true if target string is found, false if terminated or timed out
bool ICACHE_FLASH_ATTR Stream::findUntil(const char *target, size_t targetLen, const char *terminator, size_t termLen) { bool Stream::findUntil(const char *target, size_t targetLen, const char *terminator, size_t termLen) {
size_t index = 0; // maximum target string length is 64k bytes! size_t index = 0; // maximum target string length is 64k bytes!
size_t termIndex = 0; size_t termIndex = 0;
int c; int c;
@ -128,13 +125,13 @@ bool ICACHE_FLASH_ATTR Stream::findUntil(const char *target, size_t targetLen, c
// returns the first valid (long) integer value from the current position. // returns the first valid (long) integer value from the current position.
// initial characters that are not digits (or the minus sign) are skipped // initial characters that are not digits (or the minus sign) are skipped
// function is terminated by the first character that is not a digit. // function is terminated by the first character that is not a digit.
long ICACHE_FLASH_ATTR Stream::parseInt() { long Stream::parseInt() {
return parseInt(NO_SKIP_CHAR); // terminate on first non-digit character (or timeout) return parseInt(NO_SKIP_CHAR); // terminate on first non-digit character (or timeout)
} }
// as above but a given skipChar is ignored // as above but a given skipChar is ignored
// this allows format characters (typically commas) in values to be ignored // this allows format characters (typically commas) in values to be ignored
long ICACHE_FLASH_ATTR Stream::parseInt(char skipChar) { long Stream::parseInt(char skipChar) {
boolean isNegative = false; boolean isNegative = false;
long value = 0; long value = 0;
int c; int c;
@ -161,13 +158,13 @@ long ICACHE_FLASH_ATTR Stream::parseInt(char skipChar) {
} }
// as parseInt but returns a floating point value // as parseInt but returns a floating point value
float ICACHE_FLASH_ATTR Stream::parseFloat() { float Stream::parseFloat() {
return parseFloat(NO_SKIP_CHAR); return parseFloat(NO_SKIP_CHAR);
} }
// as above but the given skipChar is ignored // as above but the given skipChar is ignored
// this allows format characters (typically commas) in values to be ignored // this allows format characters (typically commas) in values to be ignored
float ICACHE_FLASH_ATTR Stream::parseFloat(char skipChar) { float Stream::parseFloat(char skipChar) {
boolean isNegative = false; boolean isNegative = false;
boolean isFraction = false; boolean isFraction = false;
long value = 0; long value = 0;
@ -208,7 +205,7 @@ float ICACHE_FLASH_ATTR Stream::parseFloat(char skipChar) {
// returns the number of characters placed in the buffer // returns the number of characters placed in the buffer
// the buffer is NOT null terminated. // the buffer is NOT null terminated.
// //
size_t ICACHE_FLASH_ATTR Stream::readBytes(char *buffer, size_t length) { size_t Stream::readBytes(char *buffer, size_t length) {
size_t count = 0; size_t count = 0;
while(count < length) { while(count < length) {
int c = timedRead(); int c = timedRead();
@ -224,7 +221,7 @@ size_t ICACHE_FLASH_ATTR Stream::readBytes(char *buffer, size_t length) {
// terminates if length characters have been read, timeout, or if the terminator character detected // terminates if length characters have been read, timeout, or if the terminator character detected
// returns the number of characters placed in the buffer (0 means no valid data found) // returns the number of characters placed in the buffer (0 means no valid data found)
size_t ICACHE_FLASH_ATTR Stream::readBytesUntil(char terminator, char *buffer, size_t length) { size_t Stream::readBytesUntil(char terminator, char *buffer, size_t length) {
if(length < 1) if(length < 1)
return 0; return 0;
size_t index = 0; size_t index = 0;
@ -238,7 +235,7 @@ size_t ICACHE_FLASH_ATTR Stream::readBytesUntil(char terminator, char *buffer, s
return index; // return number of characters, not including null terminator return index; // return number of characters, not including null terminator
} }
String ICACHE_FLASH_ATTR Stream::readString() { String Stream::readString() {
String ret; String ret;
int c = timedRead(); int c = timedRead();
while(c >= 0) { while(c >= 0) {
@ -248,7 +245,7 @@ String ICACHE_FLASH_ATTR Stream::readString() {
return ret; return ret;
} }
String ICACHE_FLASH_ATTR Stream::readStringUntil(char terminator) { String Stream::readStringUntil(char terminator) {
String ret; String ret;
int c = timedRead(); int c = timedRead();
while(c >= 0 && c != terminator) { while(c >= 0 && c != terminator) {

View File

@ -21,48 +21,43 @@
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/ */
#include <Arduino.h>
#include "WString.h" #include "WString.h"
#include "stdlib_noniso.h" #include "stdlib_noniso.h"
extern "C" {
#include "osapi.h"
#include "ets_sys.h"
#include "mem.h"
#include "c_types.h"
}
/*********************************************/ /*********************************************/
/* Constructors */ /* Constructors */
/*********************************************/ /*********************************************/
ICACHE_FLASH_ATTR String::String(const char *cstr) { String::String(const char *cstr) {
init(); init();
if(cstr) if(cstr)
copy(cstr, strlen(cstr)); copy(cstr, strlen(cstr));
} }
ICACHE_FLASH_ATTR String::String(const String &value) { String::String(const String &value) {
init(); init();
*this = value; *this = value;
} }
ICACHE_FLASH_ATTR String::String(const __FlashStringHelper *pstr) { String::String(const __FlashStringHelper *pstr) {
init(); init();
*this = pstr; // see operator = *this = pstr; // see operator =
} }
#ifdef __GXX_EXPERIMENTAL_CXX0X__ #ifdef __GXX_EXPERIMENTAL_CXX0X__
ICACHE_FLASH_ATTR String::String(String &&rval) { String::String(String &&rval) {
init(); init();
move(rval); move(rval);
} }
ICACHE_FLASH_ATTR String::String(StringSumHelper &&rval) { String::String(StringSumHelper &&rval) {
init(); init();
move(rval); move(rval);
} }
#endif #endif
ICACHE_FLASH_ATTR String::String(char c) { String::String(char c) {
init(); init();
char buf[2]; char buf[2];
buf[0] = c; buf[0] = c;
@ -70,54 +65,54 @@ ICACHE_FLASH_ATTR String::String(char c) {
*this = buf; *this = buf;
} }
ICACHE_FLASH_ATTR String::String(unsigned char value, unsigned char base) { String::String(unsigned char value, unsigned char base) {
init(); init();
char buf[1 + 8 * sizeof(unsigned char)]; char buf[1 + 8 * sizeof(unsigned char)];
utoa(value, buf, base); utoa(value, buf, base);
*this = buf; *this = buf;
} }
ICACHE_FLASH_ATTR String::String(int value, unsigned char base) { String::String(int value, unsigned char base) {
init(); init();
char buf[2 + 8 * sizeof(int)]; char buf[2 + 8 * sizeof(int)];
itoa(value, buf, base); itoa(value, buf, base);
*this = buf; *this = buf;
} }
ICACHE_FLASH_ATTR String::String(unsigned int value, unsigned char base) { String::String(unsigned int value, unsigned char base) {
init(); init();
char buf[1 + 8 * sizeof(unsigned int)]; char buf[1 + 8 * sizeof(unsigned int)];
utoa(value, buf, base); utoa(value, buf, base);
*this = buf; *this = buf;
} }
ICACHE_FLASH_ATTR String::String(long value, unsigned char base) { String::String(long value, unsigned char base) {
init(); init();
char buf[2 + 8 * sizeof(long)]; char buf[2 + 8 * sizeof(long)];
ltoa(value, buf, base); ltoa(value, buf, base);
*this = buf; *this = buf;
} }
ICACHE_FLASH_ATTR String::String(unsigned long value, unsigned char base) { String::String(unsigned long value, unsigned char base) {
init(); init();
char buf[1 + 8 * sizeof(unsigned long)]; char buf[1 + 8 * sizeof(unsigned long)];
ultoa(value, buf, base); ultoa(value, buf, base);
*this = buf; *this = buf;
} }
ICACHE_FLASH_ATTR String::String(float value, unsigned char decimalPlaces) { String::String(float value, unsigned char decimalPlaces) {
init(); init();
char buf[33]; char buf[33];
*this = dtostrf(value, (decimalPlaces + 2), decimalPlaces, buf); *this = dtostrf(value, (decimalPlaces + 2), decimalPlaces, buf);
} }
ICACHE_FLASH_ATTR String::String(double value, unsigned char decimalPlaces) { String::String(double value, unsigned char decimalPlaces) {
init(); init();
char buf[33]; char buf[33];
*this = dtostrf(value, (decimalPlaces + 2), decimalPlaces, buf); *this = dtostrf(value, (decimalPlaces + 2), decimalPlaces, buf);
} }
ICACHE_FLASH_ATTR String::~String() { String::~String() {
if(buffer) { if(buffer) {
free(buffer); free(buffer);
} }
@ -134,13 +129,13 @@ inline void String::init(void) {
len = 0; len = 0;
} }
void ICACHE_FLASH_ATTR String::invalidate(void) { void String::invalidate(void) {
if(buffer) if(buffer)
free(buffer); free(buffer);
init(); init();
} }
unsigned char ICACHE_FLASH_ATTR String::reserve(unsigned int size) { unsigned char String::reserve(unsigned int size) {
if(buffer && capacity >= size) if(buffer && capacity >= size)
return 1; return 1;
if(changeBuffer(size)) { if(changeBuffer(size)) {
@ -151,7 +146,7 @@ unsigned char ICACHE_FLASH_ATTR String::reserve(unsigned int size) {
return 0; return 0;
} }
unsigned char ICACHE_FLASH_ATTR String::changeBuffer(unsigned int maxStrLen) { unsigned char String::changeBuffer(unsigned int maxStrLen) {
size_t newSize = (maxStrLen + 16) & (~0xf); size_t newSize = (maxStrLen + 16) & (~0xf);
char *newbuffer = (char *) realloc(buffer, newSize); char *newbuffer = (char *) realloc(buffer, newSize);
if(newbuffer) { if(newbuffer) {
@ -172,7 +167,7 @@ unsigned char ICACHE_FLASH_ATTR String::changeBuffer(unsigned int maxStrLen) {
// /* Copy and Move */ // /* Copy and Move */
// /*********************************************/ // /*********************************************/
String & ICACHE_FLASH_ATTR String::copy(const char *cstr, unsigned int length) { String & String::copy(const char *cstr, unsigned int length) {
if(!reserve(length)) { if(!reserve(length)) {
invalidate(); invalidate();
return *this; return *this;
@ -182,7 +177,7 @@ String & ICACHE_FLASH_ATTR String::copy(const char *cstr, unsigned int length) {
return *this; return *this;
} }
String & ICACHE_FLASH_ATTR String::copy(const __FlashStringHelper *pstr, unsigned int length) { String & String::copy(const __FlashStringHelper *pstr, unsigned int length) {
if (!reserve(length)) { if (!reserve(length)) {
invalidate(); invalidate();
return *this; return *this;
@ -193,7 +188,7 @@ String & ICACHE_FLASH_ATTR String::copy(const __FlashStringHelper *pstr, unsigne
} }
#ifdef __GXX_EXPERIMENTAL_CXX0X__ #ifdef __GXX_EXPERIMENTAL_CXX0X__
void ICACHE_FLASH_ATTR String::move(String &rhs) { void String::move(String &rhs) {
if(buffer) { if(buffer) {
if(capacity >= rhs.len) { if(capacity >= rhs.len) {
strcpy(buffer, rhs.buffer); strcpy(buffer, rhs.buffer);
@ -213,7 +208,7 @@ void ICACHE_FLASH_ATTR String::move(String &rhs) {
} }
#endif #endif
String & ICACHE_FLASH_ATTR String::operator =(const String &rhs) { String & String::operator =(const String &rhs) {
if(this == &rhs) if(this == &rhs)
return *this; return *this;
@ -226,20 +221,20 @@ String & ICACHE_FLASH_ATTR String::operator =(const String &rhs) {
} }
#ifdef __GXX_EXPERIMENTAL_CXX0X__ #ifdef __GXX_EXPERIMENTAL_CXX0X__
String & ICACHE_FLASH_ATTR String::operator =(String &&rval) { String & String::operator =(String &&rval) {
if(this != &rval) if(this != &rval)
move(rval); move(rval);
return *this; return *this;
} }
String & ICACHE_FLASH_ATTR String::operator =(StringSumHelper &&rval) { String & String::operator =(StringSumHelper &&rval) {
if(this != &rval) if(this != &rval)
move(rval); move(rval);
return *this; return *this;
} }
#endif #endif
String & ICACHE_FLASH_ATTR String::operator =(const char *cstr) { String & String::operator =(const char *cstr) {
if(cstr) if(cstr)
copy(cstr, strlen(cstr)); copy(cstr, strlen(cstr));
else else
@ -248,7 +243,7 @@ String & ICACHE_FLASH_ATTR String::operator =(const char *cstr) {
return *this; return *this;
} }
String & ICACHE_FLASH_ATTR String::operator = (const __FlashStringHelper *pstr) String & String::operator = (const __FlashStringHelper *pstr)
{ {
if (pstr) copy(pstr, strlen_P((PGM_P)pstr)); if (pstr) copy(pstr, strlen_P((PGM_P)pstr));
else invalidate(); else invalidate();
@ -260,11 +255,11 @@ String & ICACHE_FLASH_ATTR String::operator = (const __FlashStringHelper *pstr)
// /* concat */ // /* concat */
// /*********************************************/ // /*********************************************/
unsigned char ICACHE_FLASH_ATTR String::concat(const String &s) { unsigned char String::concat(const String &s) {
return concat(s.buffer, s.len); return concat(s.buffer, s.len);
} }
unsigned char ICACHE_FLASH_ATTR String::concat(const char *cstr, unsigned int length) { unsigned char String::concat(const char *cstr, unsigned int length) {
unsigned int newlen = len + length; unsigned int newlen = len + length;
if(!cstr) if(!cstr)
return 0; return 0;
@ -277,62 +272,62 @@ unsigned char ICACHE_FLASH_ATTR String::concat(const char *cstr, unsigned int le
return 1; return 1;
} }
unsigned char ICACHE_FLASH_ATTR String::concat(const char *cstr) { unsigned char String::concat(const char *cstr) {
if(!cstr) if(!cstr)
return 0; return 0;
return concat(cstr, strlen(cstr)); return concat(cstr, strlen(cstr));
} }
unsigned char ICACHE_FLASH_ATTR String::concat(char c) { unsigned char String::concat(char c) {
char buf[2]; char buf[2];
buf[0] = c; buf[0] = c;
buf[1] = 0; buf[1] = 0;
return concat(buf, 1); return concat(buf, 1);
} }
unsigned char ICACHE_FLASH_ATTR String::concat(unsigned char num) { unsigned char String::concat(unsigned char num) {
char buf[1 + 3 * sizeof(unsigned char)]; char buf[1 + 3 * sizeof(unsigned char)];
itoa(num, buf, 10); itoa(num, buf, 10);
return concat(buf, strlen(buf)); return concat(buf, strlen(buf));
} }
unsigned char ICACHE_FLASH_ATTR String::concat(int num) { unsigned char String::concat(int num) {
char buf[2 + 3 * sizeof(int)]; char buf[2 + 3 * sizeof(int)];
itoa(num, buf, 10); itoa(num, buf, 10);
return concat(buf, strlen(buf)); return concat(buf, strlen(buf));
} }
unsigned char ICACHE_FLASH_ATTR String::concat(unsigned int num) { unsigned char String::concat(unsigned int num) {
char buf[1 + 3 * sizeof(unsigned int)]; char buf[1 + 3 * sizeof(unsigned int)];
utoa(num, buf, 10); utoa(num, buf, 10);
return concat(buf, strlen(buf)); return concat(buf, strlen(buf));
} }
unsigned char ICACHE_FLASH_ATTR String::concat(long num) { unsigned char String::concat(long num) {
char buf[2 + 3 * sizeof(long)]; char buf[2 + 3 * sizeof(long)];
ltoa(num, buf, 10); ltoa(num, buf, 10);
return concat(buf, strlen(buf)); return concat(buf, strlen(buf));
} }
unsigned char ICACHE_FLASH_ATTR String::concat(unsigned long num) { unsigned char String::concat(unsigned long num) {
char buf[1 + 3 * sizeof(unsigned long)]; char buf[1 + 3 * sizeof(unsigned long)];
ultoa(num, buf, 10); ultoa(num, buf, 10);
return concat(buf, strlen(buf)); return concat(buf, strlen(buf));
} }
unsigned char ICACHE_FLASH_ATTR String::concat(float num) { unsigned char String::concat(float num) {
char buf[20]; char buf[20];
char* string = dtostrf(num, 4, 2, buf); char* string = dtostrf(num, 4, 2, buf);
return concat(string, strlen(string)); return concat(string, strlen(string));
} }
unsigned char ICACHE_FLASH_ATTR String::concat(double num) { unsigned char String::concat(double num) {
char buf[20]; char buf[20];
char* string = dtostrf(num, 4, 2, buf); char* string = dtostrf(num, 4, 2, buf);
return concat(string, strlen(string)); return concat(string, strlen(string));
} }
unsigned char ICACHE_FLASH_ATTR String::concat(const __FlashStringHelper * str) { unsigned char String::concat(const __FlashStringHelper * str) {
if (!str) return 0; if (!str) return 0;
int length = strlen_P((PGM_P)str); int length = strlen_P((PGM_P)str);
if (length == 0) return 1; if (length == 0) return 1;
@ -347,77 +342,77 @@ unsigned char ICACHE_FLASH_ATTR String::concat(const __FlashStringHelper * str)
/* Concatenate */ /* Concatenate */
/*********************************************/ /*********************************************/
StringSumHelper & ICACHE_FLASH_ATTR operator +(const StringSumHelper &lhs, const String &rhs) { StringSumHelper & operator +(const StringSumHelper &lhs, const String &rhs) {
StringSumHelper &a = const_cast<StringSumHelper&>(lhs); StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
if(!a.concat(rhs.buffer, rhs.len)) if(!a.concat(rhs.buffer, rhs.len))
a.invalidate(); a.invalidate();
return a; return a;
} }
StringSumHelper & ICACHE_FLASH_ATTR operator +(const StringSumHelper &lhs, const char *cstr) { StringSumHelper & operator +(const StringSumHelper &lhs, const char *cstr) {
StringSumHelper &a = const_cast<StringSumHelper&>(lhs); StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
if(!cstr || !a.concat(cstr, strlen(cstr))) if(!cstr || !a.concat(cstr, strlen(cstr)))
a.invalidate(); a.invalidate();
return a; return a;
} }
StringSumHelper & ICACHE_FLASH_ATTR operator +(const StringSumHelper &lhs, char c) { StringSumHelper & operator +(const StringSumHelper &lhs, char c) {
StringSumHelper &a = const_cast<StringSumHelper&>(lhs); StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
if(!a.concat(c)) if(!a.concat(c))
a.invalidate(); a.invalidate();
return a; return a;
} }
StringSumHelper & ICACHE_FLASH_ATTR operator +(const StringSumHelper &lhs, unsigned char num) { StringSumHelper & operator +(const StringSumHelper &lhs, unsigned char num) {
StringSumHelper &a = const_cast<StringSumHelper&>(lhs); StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
if(!a.concat(num)) if(!a.concat(num))
a.invalidate(); a.invalidate();
return a; return a;
} }
StringSumHelper & ICACHE_FLASH_ATTR operator +(const StringSumHelper &lhs, int num) { StringSumHelper & operator +(const StringSumHelper &lhs, int num) {
StringSumHelper &a = const_cast<StringSumHelper&>(lhs); StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
if(!a.concat(num)) if(!a.concat(num))
a.invalidate(); a.invalidate();
return a; return a;
} }
StringSumHelper & ICACHE_FLASH_ATTR operator +(const StringSumHelper &lhs, unsigned int num) { StringSumHelper & operator +(const StringSumHelper &lhs, unsigned int num) {
StringSumHelper &a = const_cast<StringSumHelper&>(lhs); StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
if(!a.concat(num)) if(!a.concat(num))
a.invalidate(); a.invalidate();
return a; return a;
} }
StringSumHelper & ICACHE_FLASH_ATTR operator +(const StringSumHelper &lhs, long num) { StringSumHelper & operator +(const StringSumHelper &lhs, long num) {
StringSumHelper &a = const_cast<StringSumHelper&>(lhs); StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
if(!a.concat(num)) if(!a.concat(num))
a.invalidate(); a.invalidate();
return a; return a;
} }
StringSumHelper & ICACHE_FLASH_ATTR operator +(const StringSumHelper &lhs, unsigned long num) { StringSumHelper & operator +(const StringSumHelper &lhs, unsigned long num) {
StringSumHelper &a = const_cast<StringSumHelper&>(lhs); StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
if(!a.concat(num)) if(!a.concat(num))
a.invalidate(); a.invalidate();
return a; return a;
} }
StringSumHelper & ICACHE_FLASH_ATTR operator +(const StringSumHelper &lhs, float num) { StringSumHelper & operator +(const StringSumHelper &lhs, float num) {
StringSumHelper &a = const_cast<StringSumHelper&>(lhs); StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
if(!a.concat(num)) if(!a.concat(num))
a.invalidate(); a.invalidate();
return a; return a;
} }
StringSumHelper & ICACHE_FLASH_ATTR operator +(const StringSumHelper &lhs, double num) { StringSumHelper & operator +(const StringSumHelper &lhs, double num) {
StringSumHelper &a = const_cast<StringSumHelper&>(lhs); StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
if(!a.concat(num)) if(!a.concat(num))
a.invalidate(); a.invalidate();
return a; return a;
} }
StringSumHelper & ICACHE_FLASH_ATTR operator + (const StringSumHelper &lhs, const __FlashStringHelper *rhs) StringSumHelper & operator + (const StringSumHelper &lhs, const __FlashStringHelper *rhs)
{ {
StringSumHelper &a = const_cast<StringSumHelper&>(lhs); StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
if (!a.concat(rhs)) a.invalidate(); if (!a.concat(rhs)) a.invalidate();
@ -428,7 +423,7 @@ StringSumHelper & ICACHE_FLASH_ATTR operator + (const StringSumHelper &lhs, cons
// /* Comparison */ // /* Comparison */
// /*********************************************/ // /*********************************************/
int ICACHE_FLASH_ATTR String::compareTo(const String &s) const { int String::compareTo(const String &s) const {
if(!buffer || !s.buffer) { if(!buffer || !s.buffer) {
if(s.buffer && s.len > 0) if(s.buffer && s.len > 0)
return 0 - *(unsigned char *) s.buffer; return 0 - *(unsigned char *) s.buffer;
@ -439,11 +434,11 @@ int ICACHE_FLASH_ATTR String::compareTo(const String &s) const {
return strcmp(buffer, s.buffer); return strcmp(buffer, s.buffer);
} }
unsigned char ICACHE_FLASH_ATTR String::equals(const String &s2) const { unsigned char String::equals(const String &s2) const {
return (len == s2.len && compareTo(s2) == 0); return (len == s2.len && compareTo(s2) == 0);
} }
unsigned char ICACHE_FLASH_ATTR String::equals(const char *cstr) const { unsigned char String::equals(const char *cstr) const {
if(len == 0) if(len == 0)
return (cstr == NULL || *cstr == 0); return (cstr == NULL || *cstr == 0);
if(cstr == NULL) if(cstr == NULL)
@ -451,23 +446,23 @@ unsigned char ICACHE_FLASH_ATTR String::equals(const char *cstr) const {
return strcmp(buffer, cstr) == 0; return strcmp(buffer, cstr) == 0;
} }
unsigned char ICACHE_FLASH_ATTR String::operator<(const String &rhs) const { unsigned char String::operator<(const String &rhs) const {
return compareTo(rhs) < 0; return compareTo(rhs) < 0;
} }
unsigned char ICACHE_FLASH_ATTR String::operator>(const String &rhs) const { unsigned char String::operator>(const String &rhs) const {
return compareTo(rhs) > 0; return compareTo(rhs) > 0;
} }
unsigned char ICACHE_FLASH_ATTR String::operator<=(const String &rhs) const { unsigned char String::operator<=(const String &rhs) const {
return compareTo(rhs) <= 0; return compareTo(rhs) <= 0;
} }
unsigned char ICACHE_FLASH_ATTR String::operator>=(const String &rhs) const { unsigned char String::operator>=(const String &rhs) const {
return compareTo(rhs) >= 0; return compareTo(rhs) >= 0;
} }
unsigned char ICACHE_FLASH_ATTR String::equalsIgnoreCase(const String &s2) const { unsigned char String::equalsIgnoreCase(const String &s2) const {
if(this == &s2) if(this == &s2)
return 1; return 1;
if(len != s2.len) if(len != s2.len)
@ -483,19 +478,19 @@ unsigned char ICACHE_FLASH_ATTR String::equalsIgnoreCase(const String &s2) const
return 1; return 1;
} }
unsigned char ICACHE_FLASH_ATTR String::startsWith(const String &s2) const { unsigned char String::startsWith(const String &s2) const {
if(len < s2.len) if(len < s2.len)
return 0; return 0;
return startsWith(s2, 0); return startsWith(s2, 0);
} }
unsigned char ICACHE_FLASH_ATTR String::startsWith(const String &s2, unsigned int offset) const { unsigned char String::startsWith(const String &s2, unsigned int offset) const {
if(offset > len - s2.len || !buffer || !s2.buffer) if(offset > len - s2.len || !buffer || !s2.buffer)
return 0; return 0;
return strncmp(&buffer[offset], s2.buffer, s2.len) == 0; return strncmp(&buffer[offset], s2.buffer, s2.len) == 0;
} }
unsigned char ICACHE_FLASH_ATTR String::endsWith(const String &s2) const { unsigned char String::endsWith(const String &s2) const {
if(len < s2.len || !buffer || !s2.buffer) if(len < s2.len || !buffer || !s2.buffer)
return 0; return 0;
return strcmp(&buffer[len - s2.len], s2.buffer) == 0; return strcmp(&buffer[len - s2.len], s2.buffer) == 0;
@ -505,16 +500,16 @@ unsigned char ICACHE_FLASH_ATTR String::endsWith(const String &s2) const {
// /* Character Access */ // /* Character Access */
// /*********************************************/ // /*********************************************/
char ICACHE_FLASH_ATTR String::charAt(unsigned int loc) const { char String::charAt(unsigned int loc) const {
return operator[](loc); return operator[](loc);
} }
void ICACHE_FLASH_ATTR String::setCharAt(unsigned int loc, char c) { void String::setCharAt(unsigned int loc, char c) {
if(loc < len) if(loc < len)
buffer[loc] = c; buffer[loc] = c;
} }
char & ICACHE_FLASH_ATTR String::operator[](unsigned int index) { char & String::operator[](unsigned int index) {
static char dummy_writable_char; static char dummy_writable_char;
if(index >= len || !buffer) { if(index >= len || !buffer) {
dummy_writable_char = 0; dummy_writable_char = 0;
@ -523,13 +518,13 @@ char & ICACHE_FLASH_ATTR String::operator[](unsigned int index) {
return buffer[index]; return buffer[index];
} }
char ICACHE_FLASH_ATTR String::operator[](unsigned int index) const { char String::operator[](unsigned int index) const {
if(index >= len || !buffer) if(index >= len || !buffer)
return 0; return 0;
return buffer[index]; return buffer[index];
} }
void ICACHE_FLASH_ATTR String::getBytes(unsigned char *buf, unsigned int bufsize, unsigned int index) const { void String::getBytes(unsigned char *buf, unsigned int bufsize, unsigned int index) const {
if(!bufsize || !buf) if(!bufsize || !buf)
return; return;
if(index >= len) { if(index >= len) {
@ -546,13 +541,12 @@ void ICACHE_FLASH_ATTR String::getBytes(unsigned char *buf, unsigned int bufsize
// /*********************************************/ // /*********************************************/
// /* Search */ // /* Search */
// /*********************************************/ // /*********************************************/
ICACHE_FLASH_ATTR ICACHE_FLASH_ATTR
int ICACHE_FLASH_ATTR String::indexOf(char c) const { int String::indexOf(char c) const {
return indexOf(c, 0); return indexOf(c, 0);
} }
int ICACHE_FLASH_ATTR String::indexOf(char ch, unsigned int fromIndex) const { int String::indexOf(char ch, unsigned int fromIndex) const {
if(fromIndex >= len) if(fromIndex >= len)
return -1; return -1;
const char* temp = strchr(buffer + fromIndex, ch); const char* temp = strchr(buffer + fromIndex, ch);
@ -561,11 +555,11 @@ int ICACHE_FLASH_ATTR String::indexOf(char ch, unsigned int fromIndex) const {
return temp - buffer; return temp - buffer;
} }
int ICACHE_FLASH_ATTR String::indexOf(const String &s2) const { int String::indexOf(const String &s2) const {
return indexOf(s2, 0); return indexOf(s2, 0);
} }
int ICACHE_FLASH_ATTR String::indexOf(const String &s2, unsigned int fromIndex) const { int String::indexOf(const String &s2, unsigned int fromIndex) const {
if(fromIndex >= len) if(fromIndex >= len)
return -1; return -1;
const char *found = strstr(buffer + fromIndex, s2.buffer); const char *found = strstr(buffer + fromIndex, s2.buffer);
@ -574,11 +568,11 @@ int ICACHE_FLASH_ATTR String::indexOf(const String &s2, unsigned int fromIndex)
return found - buffer; return found - buffer;
} }
int ICACHE_FLASH_ATTR String::lastIndexOf(char theChar) const { int String::lastIndexOf(char theChar) const {
return lastIndexOf(theChar, len - 1); return lastIndexOf(theChar, len - 1);
} }
int ICACHE_FLASH_ATTR String::lastIndexOf(char ch, unsigned int fromIndex) const { int String::lastIndexOf(char ch, unsigned int fromIndex) const {
if(fromIndex >= len) if(fromIndex >= len)
return -1; return -1;
char tempchar = buffer[fromIndex + 1]; char tempchar = buffer[fromIndex + 1];
@ -590,11 +584,11 @@ int ICACHE_FLASH_ATTR String::lastIndexOf(char ch, unsigned int fromIndex) const
return temp - buffer; return temp - buffer;
} }
int ICACHE_FLASH_ATTR String::lastIndexOf(const String &s2) const { int String::lastIndexOf(const String &s2) const {
return lastIndexOf(s2, len - s2.len); return lastIndexOf(s2, len - s2.len);
} }
int ICACHE_FLASH_ATTR String::lastIndexOf(const String &s2, unsigned int fromIndex) const { int String::lastIndexOf(const String &s2, unsigned int fromIndex) const {
if(s2.len == 0 || len == 0 || s2.len > len) if(s2.len == 0 || len == 0 || s2.len > len)
return -1; return -1;
if(fromIndex >= len) if(fromIndex >= len)
@ -610,7 +604,7 @@ int ICACHE_FLASH_ATTR String::lastIndexOf(const String &s2, unsigned int fromInd
return found; return found;
} }
String ICACHE_FLASH_ATTR String::substring(unsigned int left, unsigned int right) const { String String::substring(unsigned int left, unsigned int right) const {
if(left > right) { if(left > right) {
unsigned int temp = right; unsigned int temp = right;
right = left; right = left;
@ -632,7 +626,7 @@ String ICACHE_FLASH_ATTR String::substring(unsigned int left, unsigned int right
// /* Modification */ // /* Modification */
// /*********************************************/ // /*********************************************/
void ICACHE_FLASH_ATTR String::replace(char find, char replace) { void String::replace(char find, char replace) {
if(!buffer) if(!buffer)
return; return;
for(char *p = buffer; *p; p++) { for(char *p = buffer; *p; p++) {
@ -641,7 +635,7 @@ void ICACHE_FLASH_ATTR String::replace(char find, char replace) {
} }
} }
void ICACHE_FLASH_ATTR String::replace(const String& find, const String& replace) { void String::replace(const String& find, const String& replace) {
if(len == 0 || find.len == 0) if(len == 0 || find.len == 0)
return; return;
int diff = replace.len - find.len; int diff = replace.len - find.len;
@ -686,14 +680,14 @@ void ICACHE_FLASH_ATTR String::replace(const String& find, const String& replace
} }
} }
void ICACHE_FLASH_ATTR String::remove(unsigned int index) { void String::remove(unsigned int index) {
// Pass the biggest integer as the count. The remove method // Pass the biggest integer as the count. The remove method
// below will take care of truncating it at the end of the // below will take care of truncating it at the end of the
// string. // string.
remove(index, (unsigned int) -1); remove(index, (unsigned int) -1);
} }
void ICACHE_FLASH_ATTR String::remove(unsigned int index, unsigned int count) { void String::remove(unsigned int index, unsigned int count) {
if(index >= len) { if(index >= len) {
return; return;
} }
@ -709,7 +703,7 @@ void ICACHE_FLASH_ATTR String::remove(unsigned int index, unsigned int count) {
buffer[len] = 0; buffer[len] = 0;
} }
void ICACHE_FLASH_ATTR String::toLowerCase(void) { void String::toLowerCase(void) {
if(!buffer) if(!buffer)
return; return;
for(char *p = buffer; *p; p++) { for(char *p = buffer; *p; p++) {
@ -717,7 +711,7 @@ void ICACHE_FLASH_ATTR String::toLowerCase(void) {
} }
} }
void ICACHE_FLASH_ATTR String::toUpperCase(void) { void String::toUpperCase(void) {
if(!buffer) if(!buffer)
return; return;
for(char *p = buffer; *p; p++) { for(char *p = buffer; *p; p++) {
@ -725,7 +719,7 @@ void ICACHE_FLASH_ATTR String::toUpperCase(void) {
} }
} }
void ICACHE_FLASH_ATTR String::trim(void) { void String::trim(void) {
if(!buffer || len == 0) if(!buffer || len == 0)
return; return;
char *begin = buffer; char *begin = buffer;
@ -744,13 +738,13 @@ void ICACHE_FLASH_ATTR String::trim(void) {
// /* Parsing / Conversion */ // /* Parsing / Conversion */
// /*********************************************/ // /*********************************************/
long ICACHE_FLASH_ATTR String::toInt(void) const { long String::toInt(void) const {
if(buffer) if(buffer)
return atol(buffer); return atol(buffer);
return 0; return 0;
} }
float ICACHE_FLASH_ATTR String::toFloat(void) const { float String::toFloat(void) const {
if(buffer) if(buffer)
return atof(buffer); return atof(buffer);
return 0; return 0;

View File

@ -24,10 +24,11 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <stdbool.h>
#include <stdint.h>
#include <math.h>
#include "stdlib_noniso.h" #include "stdlib_noniso.h"
#include "ets_sys.h"
#define sprintf ets_sprintf
int atoi(const char* s) { int atoi(const char* s) {
return (int) atol(s); return (int) atol(s);
@ -219,5 +220,3 @@ char * dtostrf(double number, signed char width, unsigned char prec, char *s) {
*out = 0; *out = 0;
return s; return s;
} }

View File

@ -11,12 +11,10 @@
#include <stddef.h> #include <stddef.h>
#include <stdint.h> #include <stdint.h>
#include <string.h> #include <string.h>
#include "c_types.h" #include <stdio.h>
#include "ets_sys.h"
#define c_memcpy memcpy #define c_memcpy memcpy
#define c_printf ets_printf #define c_printf printf
#define c_memset memset #define c_memset memset
typedef int16_t file_t; typedef int16_t file_t;

View File

@ -21,406 +21,12 @@
License along with this library; if not, write to the Free Software License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/ */
#include "spiffs_api.h"
#include "FS.h"
#undef max
#undef min
#include "FSImpl.h"
#include "spiffs/spiffs.h"
#include "debug.h"
#include <limits>
extern "C" {
#include "c_types.h"
#include "spi_flash.h"
}
using namespace fs; using namespace fs;
extern int32_t spiffs_hal_write(uint32_t addr, uint32_t size, uint8_t *src); FileImplPtr SPIFFSImpl::open(const char* path, OpenMode openMode, AccessMode accessMode)
extern int32_t spiffs_hal_erase(uint32_t addr, uint32_t size);
extern int32_t spiffs_hal_read(uint32_t addr, uint32_t size, uint8_t *dst);
static int getSpiffsMode(OpenMode openMode, AccessMode accessMode);
static bool isSpiffsFilenameValid(const char* name);
class SPIFFSFileImpl;
class SPIFFSDirImpl;
class SPIFFSImpl : public FSImpl {
public:
SPIFFSImpl(uint32_t start, uint32_t size, uint32_t pageSize, uint32_t blockSize, uint32_t maxOpenFds)
: _fs({0})
, _start(start)
, _size(size)
, _pageSize(pageSize)
, _blockSize(blockSize)
, _maxOpenFds(maxOpenFds)
{ {
}
FileImplPtr open(const char* path, OpenMode openMode, AccessMode accessMode) override;
bool exists(const char* path) override;
DirImplPtr openDir(const char* path) override;
bool rename(const char* pathFrom, const char* pathTo) override {
if (!isSpiffsFilenameValid(pathFrom)) {
DEBUGV("SPIFFSImpl::rename: invalid pathFrom=`%s`\r\n", pathFrom);
return false;
}
if (!isSpiffsFilenameValid(pathTo)) {
DEBUGV("SPIFFSImpl::rename: invalid pathTo=`%s` \r\n", pathTo);
return false;
}
auto rc = SPIFFS_rename(&_fs, pathFrom, pathTo);
if (rc != SPIFFS_OK) {
DEBUGV("SPIFFS_rename: rc=%d, from=`%s`, to=`%s`\r\n", rc,
pathFrom, pathTo);
return false;
}
return true;
}
bool info(FSInfo& info) override {
info.maxOpenFiles = _maxOpenFds;
info.blockSize = _blockSize;
info.pageSize = _pageSize;
info.maxOpenFiles = _maxOpenFds;
info.maxPathLength = SPIFFS_OBJ_NAME_LEN;
auto rc = SPIFFS_info(&_fs, &info.totalBytes, &info.usedBytes);
if (rc != SPIFFS_OK) {
DEBUGV("SPIFFS_info: rc=%d, err=%d\r\n", rc, _fs.err_code);
return false;
}
return true;
}
bool remove(const char* path) override {
if (!isSpiffsFilenameValid(path)) {
DEBUGV("SPIFFSImpl::remove: invalid path=`%s`\r\n", path);
return false;
}
auto rc = SPIFFS_remove(&_fs, path);
if (rc != SPIFFS_OK) {
DEBUGV("SPIFFS_remove: rc=%d path=`%s`\r\n", rc, path);
return false;
}
return true;
}
bool begin() override {
if (SPIFFS_mounted(&_fs) != 0) {
return true;
}
if (_size == 0) {
DEBUGV("SPIFFS size is zero");
return false;
}
if (_tryMount()) {
return true;
}
auto rc = SPIFFS_format(&_fs);
if (rc != SPIFFS_OK) {
DEBUGV("SPIFFS_format: rc=%d, err=%d\r\n", rc, _fs.err_code);
return false;
}
return _tryMount();
}
bool format() override {
if (_size == 0) {
DEBUGV("SPIFFS size is zero");
return false;
}
bool wasMounted = (SPIFFS_mounted(&_fs) != 0);
if (_tryMount()) {
SPIFFS_unmount(&_fs);
}
auto rc = SPIFFS_format(&_fs);
if (rc != SPIFFS_OK) {
DEBUGV("SPIFFS_format: rc=%d, err=%d\r\n", rc, _fs.err_code);
return false;
}
if (wasMounted) {
return _tryMount();
}
return true;
}
protected:
friend class SPIFFSFileImpl;
friend class SPIFFSDirImpl;
spiffs* getFs() {
return &_fs;
}
bool _tryMount() {
spiffs_config config = {0};
config.hal_read_f = &spiffs_hal_read;
config.hal_write_f = &spiffs_hal_write;
config.hal_erase_f = &spiffs_hal_erase;
config.phys_size = _size;
config.phys_addr = _start;
config.phys_erase_block = SPI_FLASH_SEC_SIZE;
config.log_block_size = _blockSize;
config.log_page_size = _pageSize;
if (((uint32_t) std::numeric_limits<spiffs_block_ix>::max()) < (_size / _blockSize)) {
DEBUGV("spiffs_block_ix type too small");
abort();
}
if (((uint32_t) std::numeric_limits<spiffs_page_ix>::max()) < (_size / _pageSize)) {
DEBUGV("spiffs_page_ix type too small");
abort();
}
if (((uint32_t) std::numeric_limits<spiffs_obj_id>::max()) < (2 + (_size / (2*_pageSize))*2)) {
DEBUGV("spiffs_obj_id type too small");
abort();
}
if (((uint32_t) std::numeric_limits<spiffs_span_ix>::max()) < (_size / _pageSize - 1)) {
DEBUGV("spiffs_span_ix type too small");
abort();
}
// hack: even though fs is not initialized at this point,
// SPIFFS_buffer_bytes_for_cache uses only fs->config.log_page_size
// suggestion: change SPIFFS_buffer_bytes_for_cache to take
// spiffs_config* instead of spiffs* as an argument
_fs.cfg.log_page_size = config.log_page_size;
size_t workBufSize = 2 * _pageSize;
size_t fdsBufSize = SPIFFS_buffer_bytes_for_filedescs(&_fs, _maxOpenFds);
size_t cacheBufSize = SPIFFS_buffer_bytes_for_cache(&_fs, _maxOpenFds);
if (!_workBuf) {
DEBUGV("SPIFFSImpl: allocating %d+%d+%d=%d bytes\r\n",
workBufSize, fdsBufSize, cacheBufSize,
workBufSize + fdsBufSize + cacheBufSize);
_workBuf.reset(new uint8_t[workBufSize]);
_fdsBuf.reset(new uint8_t[fdsBufSize]);
_cacheBuf.reset(new uint8_t[cacheBufSize]);
}
DEBUGV("SPIFFSImpl: mounting fs @%x, size=%x, block=%x, page=%x\r\n",
_start, _size, _blockSize, _pageSize);
auto err = SPIFFS_mount(&_fs, &config, _workBuf.get(),
_fdsBuf.get(), fdsBufSize, _cacheBuf.get(), cacheBufSize,
&SPIFFSImpl::_check_cb);
DEBUGV("SPIFFSImpl: mount rc=%d\r\n", err);
return err == SPIFFS_OK;
}
static void _check_cb(spiffs_check_type type, spiffs_check_report report,
uint32_t arg1, uint32_t arg2) {
// TODO: spiffs doesn't pass any context pointer along with _check_cb,
// so we can't do anything useful here other than perhaps
// feeding the watchdog
}
spiffs _fs;
uint32_t _start;
uint32_t _size;
uint32_t _pageSize;
uint32_t _blockSize;
uint32_t _maxOpenFds;
std::unique_ptr<uint8_t[]> _workBuf;
std::unique_ptr<uint8_t[]> _fdsBuf;
std::unique_ptr<uint8_t[]> _cacheBuf;
};
#define CHECKFD() while (_fd == 0) { panic(); }
class SPIFFSFileImpl : public FileImpl {
public:
SPIFFSFileImpl(SPIFFSImpl* fs, spiffs_file fd)
: _fs(fs)
, _fd(fd)
, _stat({0})
, _written(false)
{
_getStat();
}
~SPIFFSFileImpl() override {
close();
}
size_t write(const uint8_t *buf, size_t size) override {
CHECKFD();
auto result = SPIFFS_write(_fs->getFs(), _fd, (void*) buf, size);
if (result < 0) {
DEBUGV("SPIFFS_write rc=%d\r\n", result);
return 0;
}
_written = true;
return result;
}
size_t read(uint8_t* buf, size_t size) override {
CHECKFD();
auto result = SPIFFS_read(_fs->getFs(), _fd, (void*) buf, size);
if (result < 0) {
DEBUGV("SPIFFS_read rc=%d\r\n", result);
return 0;
}
return result;
}
void flush() override {
CHECKFD();
auto rc = SPIFFS_fflush(_fs->getFs(), _fd);
if (rc < 0) {
DEBUGV("SPIFFS_fflush rc=%d\r\n", rc);
}
_written = true;
}
bool seek(uint32_t pos, SeekMode mode) override {
CHECKFD();
int32_t offset = static_cast<int32_t>(pos);
if (mode == SeekEnd) {
offset = -offset;
}
auto rc = SPIFFS_lseek(_fs->getFs(), _fd, pos, (int) mode);
if (rc < 0) {
DEBUGV("SPIFFS_lseek rc=%d\r\n", rc);
return false;
}
return true;
}
size_t position() const override {
CHECKFD();
auto result = SPIFFS_lseek(_fs->getFs(), _fd, 0, SPIFFS_SEEK_CUR);
if (result < 0) {
DEBUGV("SPIFFS_tell rc=%d\r\n", result);
return 0;
}
return result;
}
size_t size() const override {
CHECKFD();
if (_written) {
_getStat();
}
return _stat.size;
}
void close() override {
CHECKFD();
SPIFFS_close(_fs->getFs(), _fd);
DEBUGV("SPIFFS_close: fd=%d\r\n", _fd);
}
const char* name() const override {
CHECKFD();
return (const char*) _stat.name;
}
protected:
void _getStat() const{
CHECKFD();
auto rc = SPIFFS_fstat(_fs->getFs(), _fd, &_stat);
if (rc != SPIFFS_OK) {
DEBUGV("SPIFFS_fstat rc=%d\r\n", rc);
_stat = {0};
}
_written = false;
}
SPIFFSImpl* _fs;
spiffs_file _fd;
mutable spiffs_stat _stat;
mutable bool _written;
};
class SPIFFSDirImpl : public DirImpl {
public:
SPIFFSDirImpl(const String& pattern, SPIFFSImpl* fs, spiffs_DIR& dir)
: _pattern(pattern)
, _fs(fs)
, _dir(dir)
, _valid(false)
{
}
~SPIFFSDirImpl() override {
SPIFFS_closedir(&_dir);
}
FileImplPtr openFile(OpenMode openMode, AccessMode accessMode) override {
if (!_valid) {
return FileImplPtr();
}
int mode = getSpiffsMode(openMode, accessMode);
auto fs = _fs->getFs();
spiffs_file fd = SPIFFS_open_by_dirent(fs, &_dirent, mode, 0);
if (fd < 0) {
DEBUGV("SPIFFSDirImpl::openFile: fd=%d path=`%s` openMode=%d accessMode=%d err=%d\r\n",
fd, _dirent.name, openMode, accessMode, fs->err_code);
return FileImplPtr();
}
return std::make_shared<SPIFFSFileImpl>(_fs, fd);
}
const char* fileName() override {
if (!_valid)
return nullptr;
return (const char*) _dirent.name;
}
size_t fileSize() override {
if (!_valid)
return 0;
return _dirent.size;
}
bool next() override {
const int n = _pattern.length();
do {
spiffs_dirent* result = SPIFFS_readdir(&_dir, &_dirent);
_valid = (result != nullptr);
} while(_valid && strncmp((const char*) _dirent.name, _pattern.c_str(), n) != 0);
return _valid;
}
protected:
String _pattern;
SPIFFSImpl* _fs;
spiffs_DIR _dir;
spiffs_dirent _dirent;
bool _valid;
};
FileImplPtr SPIFFSImpl::open(const char* path, OpenMode openMode, AccessMode accessMode) {
if (!isSpiffsFilenameValid(path)) { if (!isSpiffsFilenameValid(path)) {
DEBUGV("SPIFFSImpl::open: invalid path=`%s` \r\n", path); DEBUGV("SPIFFSImpl::open: invalid path=`%s` \r\n", path);
return FileImplPtr(); return FileImplPtr();
@ -446,7 +52,8 @@ FileImplPtr SPIFFSImpl::open(const char* path, OpenMode openMode, AccessMode acc
return std::make_shared<SPIFFSFileImpl>(this, fd); return std::make_shared<SPIFFSFileImpl>(this, fd);
} }
bool SPIFFSImpl::exists(const char* path) { bool SPIFFSImpl::exists(const char* path)
{
if (!isSpiffsFilenameValid(path)) { if (!isSpiffsFilenameValid(path)) {
DEBUGV("SPIFFSImpl::exists: invalid path=`%s` \r\n", path); DEBUGV("SPIFFSImpl::exists: invalid path=`%s` \r\n", path);
return false; return false;
@ -456,7 +63,8 @@ bool SPIFFSImpl::exists(const char* path) {
return rc == SPIFFS_OK; return rc == SPIFFS_OK;
} }
DirImplPtr SPIFFSImpl::openDir(const char* path) { DirImplPtr SPIFFSImpl::openDir(const char* path)
{
if (!isSpiffsFilenameValid(path)) { if (!isSpiffsFilenameValid(path)) {
DEBUGV("SPIFFSImpl::openDir: invalid path=`%s` \r\n", path); DEBUGV("SPIFFSImpl::openDir: invalid path=`%s` \r\n", path);
return DirImplPtr(); return DirImplPtr();
@ -470,7 +78,8 @@ DirImplPtr SPIFFSImpl::openDir(const char* path) {
return std::make_shared<SPIFFSDirImpl>(path, this, dir); return std::make_shared<SPIFFSDirImpl>(path, this, dir);
} }
static int getSpiffsMode(OpenMode openMode, AccessMode accessMode) { int getSpiffsMode(OpenMode openMode, AccessMode accessMode)
{
int mode = 0; int mode = 0;
if (openMode & OM_CREATE) { if (openMode & OM_CREATE) {
mode |= SPIFFS_CREAT; mode |= SPIFFS_CREAT;
@ -490,24 +99,32 @@ static int getSpiffsMode(OpenMode openMode, AccessMode accessMode) {
return mode; return mode;
} }
static bool isSpiffsFilenameValid(const char* name) { bool isSpiffsFilenameValid(const char* name)
if (name == nullptr) {
if (name == nullptr) {
return false; return false;
}
auto len = strlen(name); auto len = strlen(name);
return len > 0 && len < SPIFFS_OBJ_NAME_LEN; return len > 0 && len < SPIFFS_OBJ_NAME_LEN;
} }
// these symbols should be defined in the linker script for each flash layout // these symbols should be defined in the linker script for each flash layout
#ifdef ARDUINO
extern "C" uint32_t _SPIFFS_start; extern "C" uint32_t _SPIFFS_start;
extern "C" uint32_t _SPIFFS_end; extern "C" uint32_t _SPIFFS_end;
extern "C" uint32_t _SPIFFS_page; extern "C" uint32_t _SPIFFS_page;
extern "C" uint32_t _SPIFFS_block; extern "C" uint32_t _SPIFFS_block;
static SPIFFSImpl s_defaultFs( #define SPIFFS_PHYS_ADDR ((uint32_t) (&_SPIFFS_start) - 0x40200000)
(uint32_t) (&_SPIFFS_start) - 0x40200000, #define SPIFFS_PHYS_SIZE ((uint32_t) (&_SPIFFS_end) - (uint32_t) (&_SPIFFS_start))
(uint32_t) (&_SPIFFS_end) - (uint32_t) (&_SPIFFS_start), #define SPIFFS_PHYS_PAGE ((uint32_t) &_SPIFFS_page)
(uint32_t) &_SPIFFS_page, #define SPIFFS_PHYS_BLOCK ((uint32_t) &_SPIFFS_block)
(uint32_t) &_SPIFFS_block,
5);
FS SPIFFS = FS(FSImplPtr(&s_defaultFs)); FS SPIFFS = FS(FSImplPtr(new SPIFFSImpl(
SPIFFS_PHYS_ADDR,
SPIFFS_PHYS_SIZE,
SPIFFS_PHYS_PAGE,
SPIFFS_PHYS_BLOCK,
5)));
#endif

451
cores/esp8266/spiffs_api.h Normal file
View File

@ -0,0 +1,451 @@
#ifndef spiffs_api_h
#define spiffs_api_h
/*
spiffs_api.h - file system wrapper for SPIFFS
Copyright (c) 2015 Ivan Grokhotkov. All rights reserved.
This code was influenced by NodeMCU and Sming libraries, and first version of
Arduino wrapper written by Hristo Gochkov.
This file is part of the esp8266 core for Arduino environment.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <limits>
#include "FS.h"
#undef max
#undef min
#include "FSImpl.h"
#include "spiffs/spiffs.h"
#include "debug.h"
#include "flash_utils.h"
using namespace fs;
extern int32_t spiffs_hal_write(uint32_t addr, uint32_t size, uint8_t *src);
extern int32_t spiffs_hal_erase(uint32_t addr, uint32_t size);
extern int32_t spiffs_hal_read(uint32_t addr, uint32_t size, uint8_t *dst);
int getSpiffsMode(OpenMode openMode, AccessMode accessMode);
bool isSpiffsFilenameValid(const char* name);
class SPIFFSFileImpl;
class SPIFFSDirImpl;
class SPIFFSImpl : public FSImpl
{
public:
SPIFFSImpl(uint32_t start, uint32_t size, uint32_t pageSize, uint32_t blockSize, uint32_t maxOpenFds)
: _fs({0})
, _start(start)
, _size(size)
, _pageSize(pageSize)
, _blockSize(blockSize)
, _maxOpenFds(maxOpenFds)
{
}
FileImplPtr open(const char* path, OpenMode openMode, AccessMode accessMode) override;
bool exists(const char* path) override;
DirImplPtr openDir(const char* path) override;
bool rename(const char* pathFrom, const char* pathTo) override
{
if (!isSpiffsFilenameValid(pathFrom)) {
DEBUGV("SPIFFSImpl::rename: invalid pathFrom=`%s`\r\n", pathFrom);
return false;
}
if (!isSpiffsFilenameValid(pathTo)) {
DEBUGV("SPIFFSImpl::rename: invalid pathTo=`%s` \r\n", pathTo);
return false;
}
auto rc = SPIFFS_rename(&_fs, pathFrom, pathTo);
if (rc != SPIFFS_OK) {
DEBUGV("SPIFFS_rename: rc=%d, from=`%s`, to=`%s`\r\n", rc,
pathFrom, pathTo);
return false;
}
return true;
}
bool info(FSInfo& info) override
{
info.maxOpenFiles = _maxOpenFds;
info.blockSize = _blockSize;
info.pageSize = _pageSize;
info.maxOpenFiles = _maxOpenFds;
info.maxPathLength = SPIFFS_OBJ_NAME_LEN;
uint32_t totalBytes, usedBytes;
auto rc = SPIFFS_info(&_fs, &totalBytes, &usedBytes);
if (rc != SPIFFS_OK) {
DEBUGV("SPIFFS_info: rc=%d, err=%d\r\n", rc, _fs.err_code);
return false;
}
info.totalBytes = totalBytes;
info.usedBytes = usedBytes;
return true;
}
bool remove(const char* path) override
{
if (!isSpiffsFilenameValid(path)) {
DEBUGV("SPIFFSImpl::remove: invalid path=`%s`\r\n", path);
return false;
}
auto rc = SPIFFS_remove(&_fs, path);
if (rc != SPIFFS_OK) {
DEBUGV("SPIFFS_remove: rc=%d path=`%s`\r\n", rc, path);
return false;
}
return true;
}
bool begin() override
{
if (SPIFFS_mounted(&_fs) != 0) {
return true;
}
if (_size == 0) {
DEBUGV("SPIFFS size is zero");
return false;
}
if (_tryMount()) {
return true;
}
auto rc = SPIFFS_format(&_fs);
if (rc != SPIFFS_OK) {
DEBUGV("SPIFFS_format: rc=%d, err=%d\r\n", rc, _fs.err_code);
return false;
}
return _tryMount();
}
bool format() override
{
if (_size == 0) {
DEBUGV("SPIFFS size is zero");
return false;
}
bool wasMounted = (SPIFFS_mounted(&_fs) != 0);
if (_tryMount()) {
SPIFFS_unmount(&_fs);
}
auto rc = SPIFFS_format(&_fs);
if (rc != SPIFFS_OK) {
DEBUGV("SPIFFS_format: rc=%d, err=%d\r\n", rc, _fs.err_code);
return false;
}
if (wasMounted) {
return _tryMount();
}
return true;
}
protected:
friend class SPIFFSFileImpl;
friend class SPIFFSDirImpl;
spiffs* getFs()
{
return &_fs;
}
bool _tryMount()
{
spiffs_config config = {0};
config.hal_read_f = &spiffs_hal_read;
config.hal_write_f = &spiffs_hal_write;
config.hal_erase_f = &spiffs_hal_erase;
config.phys_size = _size;
config.phys_addr = _start;
config.phys_erase_block = FLASH_SECTOR_SIZE;
config.log_block_size = _blockSize;
config.log_page_size = _pageSize;
if (((uint32_t) std::numeric_limits<spiffs_block_ix>::max()) < (_size / _blockSize)) {
DEBUGV("spiffs_block_ix type too small");
abort();
}
if (((uint32_t) std::numeric_limits<spiffs_page_ix>::max()) < (_size / _pageSize)) {
DEBUGV("spiffs_page_ix type too small");
abort();
}
if (((uint32_t) std::numeric_limits<spiffs_obj_id>::max()) < (2 + (_size / (2*_pageSize))*2)) {
DEBUGV("spiffs_obj_id type too small");
abort();
}
if (((uint32_t) std::numeric_limits<spiffs_span_ix>::max()) < (_size / _pageSize - 1)) {
DEBUGV("spiffs_span_ix type too small");
abort();
}
// hack: even though fs is not initialized at this point,
// SPIFFS_buffer_bytes_for_cache uses only fs->config.log_page_size
// suggestion: change SPIFFS_buffer_bytes_for_cache to take
// spiffs_config* instead of spiffs* as an argument
_fs.cfg.log_page_size = config.log_page_size;
size_t workBufSize = 2 * _pageSize;
size_t fdsBufSize = SPIFFS_buffer_bytes_for_filedescs(&_fs, _maxOpenFds);
size_t cacheBufSize = SPIFFS_buffer_bytes_for_cache(&_fs, _maxOpenFds);
if (!_workBuf) {
DEBUGV("SPIFFSImpl: allocating %d+%d+%d=%d bytes\r\n",
workBufSize, fdsBufSize, cacheBufSize,
workBufSize + fdsBufSize + cacheBufSize);
_workBuf.reset(new uint8_t[workBufSize]);
_fdsBuf.reset(new uint8_t[fdsBufSize]);
_cacheBuf.reset(new uint8_t[cacheBufSize]);
}
DEBUGV("SPIFFSImpl: mounting fs @%x, size=%x, block=%x, page=%x\r\n",
_start, _size, _blockSize, _pageSize);
auto err = SPIFFS_mount(&_fs, &config, _workBuf.get(),
_fdsBuf.get(), fdsBufSize, _cacheBuf.get(), cacheBufSize,
&SPIFFSImpl::_check_cb);
DEBUGV("SPIFFSImpl: mount rc=%d\r\n", err);
return err == SPIFFS_OK;
}
static void _check_cb(spiffs_check_type type, spiffs_check_report report,
uint32_t arg1, uint32_t arg2)
{
// TODO: spiffs doesn't pass any context pointer along with _check_cb,
// so we can't do anything useful here other than perhaps
// feeding the watchdog
}
spiffs _fs;
uint32_t _start;
uint32_t _size;
uint32_t _pageSize;
uint32_t _blockSize;
uint32_t _maxOpenFds;
std::unique_ptr<uint8_t[]> _workBuf;
std::unique_ptr<uint8_t[]> _fdsBuf;
std::unique_ptr<uint8_t[]> _cacheBuf;
};
#define CHECKFD() while (_fd == 0) { panic(); }
class SPIFFSFileImpl : public FileImpl
{
public:
SPIFFSFileImpl(SPIFFSImpl* fs, spiffs_file fd)
: _fs(fs)
, _fd(fd)
, _stat({0})
, _written(false)
{
_getStat();
}
~SPIFFSFileImpl() override
{
close();
}
size_t write(const uint8_t *buf, size_t size) override
{
CHECKFD();
auto result = SPIFFS_write(_fs->getFs(), _fd, (void*) buf, size);
if (result < 0) {
DEBUGV("SPIFFS_write rc=%d\r\n", result);
return 0;
}
_written = true;
return result;
}
size_t read(uint8_t* buf, size_t size) override
{
CHECKFD();
auto result = SPIFFS_read(_fs->getFs(), _fd, (void*) buf, size);
if (result < 0) {
DEBUGV("SPIFFS_read rc=%d\r\n", result);
return 0;
}
return result;
}
void flush() override
{
CHECKFD();
auto rc = SPIFFS_fflush(_fs->getFs(), _fd);
if (rc < 0) {
DEBUGV("SPIFFS_fflush rc=%d\r\n", rc);
}
_written = true;
}
bool seek(uint32_t pos, SeekMode mode) override
{
CHECKFD();
int32_t offset = static_cast<int32_t>(pos);
if (mode == SeekEnd) {
offset = -offset;
}
auto rc = SPIFFS_lseek(_fs->getFs(), _fd, pos, (int) mode);
if (rc < 0) {
DEBUGV("SPIFFS_lseek rc=%d\r\n", rc);
return false;
}
return true;
}
size_t position() const override
{
CHECKFD();
auto result = SPIFFS_lseek(_fs->getFs(), _fd, 0, SPIFFS_SEEK_CUR);
if (result < 0) {
DEBUGV("SPIFFS_tell rc=%d\r\n", result);
return 0;
}
return result;
}
size_t size() const override
{
CHECKFD();
if (_written) {
_getStat();
}
return _stat.size;
}
void close() override
{
CHECKFD();
SPIFFS_close(_fs->getFs(), _fd);
DEBUGV("SPIFFS_close: fd=%d\r\n", _fd);
}
const char* name() const override
{
CHECKFD();
return (const char*) _stat.name;
}
protected:
void _getStat() const
{
CHECKFD();
auto rc = SPIFFS_fstat(_fs->getFs(), _fd, &_stat);
if (rc != SPIFFS_OK) {
DEBUGV("SPIFFS_fstat rc=%d\r\n", rc);
_stat = {0};
}
_written = false;
}
SPIFFSImpl* _fs;
spiffs_file _fd;
mutable spiffs_stat _stat;
mutable bool _written;
};
class SPIFFSDirImpl : public DirImpl
{
public:
SPIFFSDirImpl(const String& pattern, SPIFFSImpl* fs, spiffs_DIR& dir)
: _pattern(pattern)
, _fs(fs)
, _dir(dir)
, _valid(false)
{
}
~SPIFFSDirImpl() override
{
SPIFFS_closedir(&_dir);
}
FileImplPtr openFile(OpenMode openMode, AccessMode accessMode) override
{
if (!_valid) {
return FileImplPtr();
}
int mode = getSpiffsMode(openMode, accessMode);
auto fs = _fs->getFs();
spiffs_file fd = SPIFFS_open_by_dirent(fs, &_dirent, mode, 0);
if (fd < 0) {
DEBUGV("SPIFFSDirImpl::openFile: fd=%d path=`%s` openMode=%d accessMode=%d err=%d\r\n",
fd, _dirent.name, openMode, accessMode, fs->err_code);
return FileImplPtr();
}
return std::make_shared<SPIFFSFileImpl>(_fs, fd);
}
const char* fileName() override
{
if (!_valid) {
return nullptr;
}
return (const char*) _dirent.name;
}
size_t fileSize() override
{
if (!_valid) {
return 0;
}
return _dirent.size;
}
bool next() override
{
const int n = _pattern.length();
do {
spiffs_dirent* result = SPIFFS_readdir(&_dir, &_dirent);
_valid = (result != nullptr);
} while(_valid && strncmp((const char*) _dirent.name, _pattern.c_str(), n) != 0);
return _valid;
}
protected:
String _pattern;
SPIFFSImpl* _fs;
spiffs_DIR _dir;
spiffs_dirent _dirent;
bool _valid;
};
#endif//spiffs_api_h