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:
parent
aa67d1c492
commit
1f32b7f66e
@ -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 {
|
||||||
|
|
||||||
|
@ -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))
|
||||||
|
@ -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) {
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
@ -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
451
cores/esp8266/spiffs_api.h
Normal 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
|
Loading…
x
Reference in New Issue
Block a user