Arduino TinyFTP
All Classes Functions Pages
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 
7 namespace ftp_client {
8 
16 class 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