From 4b3167263d81e6fa44938c5fb2c9830c8981f510 Mon Sep 17 00:00:00 2001 From: Hieromon Ikasamo Date: Sun, 14 Apr 2019 00:02:57 +0900 Subject: [PATCH] Supports AutoConnectFile --- mkdocs/acelements.md | 6 ++--- mkdocs/acupload.md | 44 +++++++++++++++++++++++-------------- src/AutoConnectAux.h | 7 ++++-- src/AutoConnectUpload.h | 2 +- src/AutoConnectUploadImpl.h | 8 ++++--- 5 files changed, 42 insertions(+), 25 deletions(-) diff --git a/mkdocs/acelements.md b/mkdocs/acelements.md index d17ce0e..b3f2c67 100644 --- a/mkdocs/acelements.md +++ b/mkdocs/acelements.md @@ -194,9 +194,9 @@ A `label` is an optional string. A label is always arranged on the left side of Specifies the destination to save the uploaded file. The destination can be specified the following values ​​in the *ACFile_t* enumeration type. -- AC_File_FS: Save as the SPIFFS file in flash of ESP8266/ESP32 module. -- AC_File_SD: Save to an external SD device connected to ESP8266/ESP32 module. -- AC_File_Extern: Pass the content of the uploaded file to the uploader which is declared by the sketch individually. Its uploader must inherit [**AutoConnectUploadHandler**](acupload.md#to-upload-to-a-device-other-than-flash-or-sd) class and implements *_open*, *_write* and *_close* function. +- **`AC_File_FS`** : Save as the SPIFFS file in flash of ESP8266/ESP32 module. +- **`AC_File_SD`** : Save to an external SD device connected to ESP8266/ESP32 module. +- **`AC_File_Extern`** : Pass the content of the uploaded file to the uploader which is declared by the sketch individually. Its uploader must inherit [**AutoConnectUploadHandler**](acupload.md#to-upload-to-a-device-other-than-flash-or-sd) class and implements *_open*, *_write* and *_close* function. !!! note "Built-in uploader is ready." AutoConnect already equips the built-in uploader for saving to the SPIFFS as AC_File_FS and the external SD as AC_File_SD. It is already implemented inside AutoConnect and will store uploaded file automatically. diff --git a/mkdocs/acupload.md b/mkdocs/acupload.md index 83b482a..b7180d0 100644 --- a/mkdocs/acupload.md +++ b/mkdocs/acupload.md @@ -149,19 +149,21 @@ Also, the substance of AC_File_SD (sd) is a FAT file of Arduino SD library porte ## When it will be uploaded -The below diagram shows the file uploading sequence. Upload handler will be launched by ESP8266WebServer/WebServer(ESP32) library which is triggered by receiving an HTTP stream of POST BODY including file content. Its launching occurs before invoking the page handler. +Upload handler will be launched by ESP8266WebServer/WebServer(ESP32) library which is triggered by receiving an HTTP stream of POST BODY including file content. Its launching occurs before invoking the page handler. -At the time of the page handler behaves, the uploaded file already saved to the device, and the [member variables](acelements.md#name_3) of AutoConnectFile reflects the file name and transfer size. +The following diagram illustrates the file uploading sequence: +At the time of the page handler behaves, the uploaded file already saved to the device, and the [member variables](acelements.md#name_3) of AutoConnectFile reflects the file name and transfer size. + ## The file name for the uploaded file AutoConnetFile saves the uploaded file with the file name you selected by `` tag on the browser. The file name used for uploading is stored in the AutoConnetFile's value member, which you can access after uploading. (i.e. In the handler of the destination page by the AutoConnectSubmit element.) You can not save it with a different name. It can be renamed after upload if you need to change the name. -## To upload to a device other than Flash or SD +## Upload to a device other than Flash or SD -You can output the file to any device using a custom uploader by specifying [**extern**](acjson.md#acfile) with the [store](acjson.md#acfile) attribute of AutoConnectFile (or specifying [**AC_File_Extern**](acelements.md#store) for the store member variable) and can customize the uploader according to the need to upload files to other than Flash or SD. Implements your own uploader with inheriting the [**AutoConnectUploadHandler**](#upload-handler-base-class) class which is the base class of the upload handler. +You can output the file to any device using a custom uploader by specifying [**extern**](acjson.md#acfile) with the [store](acjson.md#acfile) attribute of [AutoConnectFile (or specifying [**AC_File_Extern**](acelements.md#store) for the store member variable) and can customize the uploader according to the need to upload files to other than Flash or SD. Implements your own uploader with inheriting the [**AutoConnectUploadHandler**](#upload-handler-base-class) class which is the base class of the upload handler. !!! note "It's not so difficult" Implementing the custom uploader requires a little knowledge of the c++ language. If you are less attuned to programming c++, you may find it difficult. But don't worry. You can make it in various situations by just modifying the sketch skeleton that appears at the end of this page. @@ -205,17 +207,17 @@ typedef struct { -The upload handler needs to implement processing based on the enumeration value of HTTPUpload.status HTTPUploadStatus enum type. HTTPUploadStatus enumeration is as follows: +The upload handler needs to implement processing based on the enumeration value of HTTPUpload.status as **HTTPUploadStatus** enum type. HTTPUploadStatus enumeration is as follows: -- UPLOAD_FILE_START: Invokes to the \_open. -- UPLOAD_FILE_WRITE: Invokes to the \_write. -- UPLOAD_FILE_END: Invokes to the \_close. -- UPLOAD_FILE_ABORTED: Invokes to the \_close. +- **`UPLOAD_FILE_START`** : Invokes to the \_open. +- **`UPLOAD_FILE_WRITE`** : Invokes to the \_write. +- **`UPLOAD_FILE_END`** : Invokes to the \_close. +- **`UPLOAD_FILE_ABORTED`** : Invokes to the \_close. ```cpp protected virtual bool _open(const char* filename, const char* mode) = 0 ``` -The \_open function will be invoked when HTTPUploadStatus is **UPLOAD_FILE_START**. Usually, the implementation of an inherited class will usually open the file. +The \_open function will be invoked when HTTPUploadStatus is **UPLOAD_FILE_START**. Usually, the implementation of an inherited class will open the file.
**Parameters**
filenameUploading file name.
@@ -226,7 +228,7 @@ The \_open function will be invoked when HTTPUploadStatus is **UPLOAD_FILE_START
```cpp -protected virtual size_t _write(const uint8_t *buf, size_t size))= 0 +protected virtual size_t _write(const uint8_t *buf, const size_t size))= 0 ``` The \_write function will be invoked when HTTPUploadStatus is **UPLOAD_FILE_WRITE**. The content of the upload file is divided and the \_write will be invoked in multiple times. Usually, the implementation of an inherited class will write data.
@@ -242,7 +244,7 @@ protected virtual void _close(void) = 0 ``` The \_close function will be invoked when HTTPUploadStatus is **UPLOAD_FILE_END** or **UPLOAD_FILE_ABORTED**. Usually, the implementation of an inherited class will close the file. -For reference, the following AutoConnectUploadFS class is AutoConnect built-in uploader. This class implementation also inherits from AutoConnectUploadHandler. +For reference, the following AutoConnectUploadFS class is an implementation of AutoConnect built-in uploader and inherits from AutoConnectUploadHandler. ```cpp class AutoConnectUploadFS : public AutoConnectUploadHandler { @@ -259,7 +261,7 @@ class AutoConnectUploadFS : public AutoConnectUploadHandler { return false; } - size_t _write(const uint8_t* buf, size_t size) override { + size_t _write(const uint8_t* buf, const size_t size) override { if (_file) return _file.write(buf, size); else @@ -272,6 +274,7 @@ class AutoConnectUploadFS : public AutoConnectUploadHandler { _media->end(); } + private: SPIFFST* _media; SPIFileT _file; }; @@ -281,6 +284,15 @@ class AutoConnectUploadFS : public AutoConnectUploadHandler { In order to upload a file by the custom uploader, it is necessary to register it to the custom Web page beforehand. To register a custom uploader, specify the custom uploader class name in the template argument of the [AutoConnectAux::onUpload](apiaux.md#onupload) function and invokes it. +```cpp +void AutoConnectAux::onUpload(T& uploadClass) +``` +
+
**Parameters**
+
TSpecifies a class name of the custom uploader. This class name is a class that you implemented by inheriting AutoConnectUploadHandler for custom upload.
+
uploadClassSpecifies the custom upload class instance.
+
+ The rough structure of the sketches that completed these implementations will be as follows: ```cpp @@ -320,17 +332,17 @@ public: protected: bool _open(const char* filename, const char* mode) override; - size_t _write(const uint8_t *buf, size_t size) override; + size_t _write(const uint8_t *buf, const size_t size) override; void _close(void) override; }; // _open for custom open bool CustomUploader::_open(const char* filename, const char* mode) { // Here, an implementation for the open file. -}) +} // _open for custom write -size_t CustomUploader::_write(const uint8_t *buf, size_t size) { +size_t CustomUploader::_write(const uint8_t *buf, const size_t size) { // Here, an implementation for the writing the file data. } diff --git a/src/AutoConnectAux.h b/src/AutoConnectAux.h index 3bac93b..d9e443c 100644 --- a/src/AutoConnectAux.h +++ b/src/AutoConnectAux.h @@ -14,6 +14,7 @@ #include #include #include +#include #ifdef AUTOCONNECT_USE_JSON #include #endif // !AUTOCONNECT_USE_JSON @@ -63,8 +64,10 @@ class AutoConnectAux : public PageBuilder { void setTitle(const String& title) { _title = title; } /**< Set a title of the auxiliary page */ void on(const AuxHandlerFunctionT handler, const AutoConnectExitOrder_t order = AC_EXIT_AHEAD) { _handler = handler; _order = order; } /**< Set user handler */ void onUpload(PageBuilder::UploadFuncT uploadFunc) override { _uploadHandler = uploadFunc; } - template - void onUpload(T& uploadClass) { _uploadHandler = std::bind(&T::upload, &uploadClass, std::placeholders::_1, std::placeholders::_2); } + template::value>::type> + void onUpload(T& uploadClass) { + _uploadHandler = std::bind(&T::upload, &uploadClass, std::placeholders::_1, std::placeholders::_2); + } #ifdef AUTOCONNECT_USE_JSON bool load(const String& in); /**< Load whole elements to AutoConnectAux Page */ diff --git a/src/AutoConnectUpload.h b/src/AutoConnectUpload.h index 2ccbc9d..9004991 100644 --- a/src/AutoConnectUpload.h +++ b/src/AutoConnectUpload.h @@ -31,7 +31,7 @@ class AutoConnectUploadHandler { protected: virtual bool _open(const char* filename, const char* mode) = 0; - virtual size_t _write(const uint8_t *buf, size_t size) = 0; + virtual size_t _write(const uint8_t *buf, const size_t size) = 0; virtual void _close(void) = 0; }; diff --git a/src/AutoConnectUploadImpl.h b/src/AutoConnectUploadImpl.h index 98aedb0..75ec614 100644 --- a/src/AutoConnectUploadImpl.h +++ b/src/AutoConnectUploadImpl.h @@ -55,7 +55,7 @@ void AutoConnectUploadHandler::upload(const String& requestUri, const HTTPUpload break; } case UPLOAD_FILE_WRITE: - (void)_write(upload.buf, upload.currentSize); + (void)_write(upload.buf, (const size_t)upload.currentSize); break; case UPLOAD_FILE_ABORTED: case UPLOAD_FILE_END: @@ -83,7 +83,7 @@ class AutoConnectUploadFS : public AutoConnectUploadHandler { return false; } - size_t _write(const uint8_t* buf, size_t size) override { + size_t _write(const uint8_t* buf, const size_t size) override { if (_file) return _file.write(buf, size); else @@ -96,6 +96,7 @@ class AutoConnectUploadFS : public AutoConnectUploadHandler { _media->end(); } + private: SPIFFST* _media; SPIFileT _file; }; @@ -121,7 +122,7 @@ class AutoConnectUploadSD : public AutoConnectUploadHandler { return false; } - size_t _write(const uint8_t* buf, size_t size) override { + size_t _write(const uint8_t* buf, const size_t size) override { if (_file) return _file.write(buf, size); else @@ -134,6 +135,7 @@ class AutoConnectUploadSD : public AutoConnectUploadHandler { _media->end(); } + private: SDClassT* _media; SDFileT _file; uint8_t _cs;