Arduino TinyFTP
Loading...
Searching...
No Matches
FTPFile.h
1#pragma once
2
3#include "Arduino.h"
4#include "FTPBasicAPI.h" // You'll need to create this or include the API definitions
5#include "Stream.h"
6
7namespace ftp_client {
8
16class FTPFile : public Stream {
17 public:
18 FTPFile() { is_open = false; }
19
20 FTPFile(FTPBasicAPI *api_ptr, const char *name, FileMode mode,
21 bool autoClose = true) {
22 FTPLogger::writeLog(LOG_DEBUG, "FTPFile", name);
23 auto_close = autoClose;
24 if (name != nullptr) file_name = name;
25 this->mode = mode;
26 this->api_ptr = api_ptr;
27 }
28
29 ~FTPFile() {
30 if (auto_close) close();
31 }
32
33 size_t write(uint8_t data) {
34 if (!is_open) return 0;
35 FTPLogger::writeLog(LOG_DEBUG, "FTPFile", "write");
36 if (mode == READ_MODE) {
37 FTPLogger::writeLog(LOG_ERROR, "FTPFile", "Cannot write in READ_MODE");
38 return 0;
39 }
40 Stream *result_ptr = api_ptr->write(file_name.c_str(), mode);
41 return result_ptr->write(data);
42 }
43
44 size_t write(const uint8_t *data, size_t len) override {
45 if (!is_open) return 0;
46 FTPLogger::writeLog(LOG_DEBUG, "FTPFile", "write");
47 if (mode == READ_MODE) {
48 FTPLogger::writeLog(LOG_ERROR, "FTPFile", "Cannot write in READ_MODE");
49 return 0;
50 }
51 Stream *result_ptr = api_ptr->write(file_name.c_str(), mode);
52 return result_ptr->write(data, len);
53 }
54
55 size_t write(const char *data, int len) {
56 return write((const uint8_t *)data, len);
57 }
58
59 int read() {
60 if (!is_open) return -1;
61 FTPLogger::writeLog(LOG_DEBUG, "FTPFile", "read");
62 Stream *result_ptr = api_ptr->read(file_name.c_str());
63 return result_ptr->read();
64 }
65
66 size_t readBytes(char *buf, size_t nbyte) {
67 return readBytes((uint8_t *)buf, nbyte);
68 }
69
70 size_t readBytes(uint8_t *buf, size_t nbyte) {
71 if (!is_open) return 0;
72 FTPLogger::writeLog(LOG_DEBUG, "FTPFile", "readBytes");
73 memset(buf, 0, nbyte);
74 Stream *result_ptr = api_ptr->read(file_name.c_str());
75 return result_ptr->readBytes((char *)buf, nbyte);
76 }
77
78 size_t readln(char *buf, size_t nbyte) {
79 if (!is_open) return 0;
80 FTPLogger::writeLog(LOG_DEBUG, "FTPFile", "readln");
81 memset(buf, 0, nbyte);
82 Stream *result_ptr = api_ptr->read(file_name.c_str());
83 return result_ptr->readBytesUntil(eol[0], (char *)buf, nbyte);
84 }
85
86 int peek() {
87 if (!is_open) return -1;
88 FTPLogger::writeLog(LOG_DEBUG, "FTPFile", "peek");
89 Stream *result_ptr = api_ptr->read(file_name.c_str());
90 return result_ptr->peek();
91 }
92
93 int available() {
94 if (api_ptr->currentOperation() == IS_EOF) return 0;
95 if (!is_open) return 0;
96
97 char msg[80];
98 Stream *result_ptr = api_ptr->read(file_name.c_str());
99 int len = result_ptr->available();
100 sprintf(msg, "available: %d", len);
101 FTPLogger::writeLog(LOG_DEBUG, "FTPFile", msg);
102 return len;
103 }
104
105 void flush() {
106 if (!is_open) return;
107 if (api_ptr->currentOperation() == WRITE_OP) {
108 FTPLogger::writeLog(LOG_DEBUG, "FTPFile", "flush");
109 api_ptr->flush();
110 }
111 }
112
113 void reopen() { is_open = true; }
114
115 void close() {
116 if (is_open) {
117 FTPLogger::writeLog(LOG_DEBUG, "FTPFile", "close");
118 if (api_ptr->currentOperation() == WRITE_OP) {
119 // end of write operation !!!
120 api_ptr->data_ptr->stop();
121 const char *ok[] = {"226", "250", nullptr};
122 api_ptr->checkResult(ok, "close-write", true);
123 } else if (api_ptr->currentOperation() == READ_OP) {
124 // end of read operation !!!
125 api_ptr->data_ptr->stop();
126 const char *ok[] = {"226", "250", nullptr};
127 api_ptr->checkResult(ok, "close-read", true);
128 }
129 api_ptr->setCurrentOperation(NOP);
130 is_open = false;
131 }
132 }
133
134 bool cancel() {
135 if (is_open) {
136 FTPLogger::writeLog(LOG_INFO, "FTPFile", "cancel");
137 bool result = api_ptr->abort();
138 is_open = false;
139 return result;
140 }
141 return true;
142 }
143
144 const char *name() const { return file_name.c_str(); }
145
146 size_t size() const {
147 if (!is_open) return 0;
148 char msg[80];
149 size_t size = api_ptr->size(file_name.c_str());
150 sprintf(msg, "size: %ld", size);
151 FTPLogger::writeLog(LOG_DEBUG, "FTPFile", msg);
152 return size;
153 }
154
155 void setEOL(char *eol) {
156 FTPLogger::writeLog(LOG_DEBUG, "FTPFile", "setEOL");
157 this->eol = eol;
158 }
159
160 bool isDirectory() const {
161 if (!is_open) return false;
162 FTPLogger::writeLog(LOG_DEBUG, "FTPFile", "isDirectory");
163 return api_ptr->objectType(file_name.c_str()) == TypeDirectory;
164 }
165
166 operator bool() { return is_open && file_name.length() > 0; }
167
168 protected:
169 String file_name;
170 const char *eol = "\n";
171 FileMode mode;
172 FTPBasicAPI *api_ptr;
173 ObjectType object_type = TypeUndefined;
174 bool is_open = true;
175 bool auto_close = false;
176};
177
178} // namespace ftp_client
FTPBasicAPI Implementation of Low Level FTP protocol. In order to simplify the logic we always use Pa...
Definition FTPBasicAPI.h:17
FTPFile A single file which supports read and write operations. This class is implemented as an Ardui...
Definition FTPFile.h:16