sd_stdio_c_iface.cpp
Go to the documentation of this file.
1 /******************************************************************************/
38 /******************************************************************************/
39 
40 #include "sd_stdio_c_iface.h"
41 #include <SD.h>
42 
47 struct _SD_File {
48  File f;
49  int8_t eof;
51 };
52 
53 int
55  SD_FILE *stream
56 ) {
57  if (stream) {
58  stream->f.close();
59  }
60 
61  delete stream;
62  return 0;
63 }
64 
65 int
67  SD_FILE *stream
68 ) {
69  if (stream->eof == 1) {
70 #if DEBUG
71  Serial.println("EOF");
72 #endif
73  return -1; /* end of file has been reached */
74  }
75  else {
76 #if DEBUG
77  Serial.println("NOT EOF");
78 #endif
79  return 0; /* end of file has not been reached */
80  }
81 }
82 
83 int
85  SD_FILE *stream
86 ) {
87  stream->f.flush();
88  return 0;
89 }
90 
91 int
93  SD_FILE *stream,
94  ion_fpos_t *pos
95 ) {
96  return (stream) ? !(stream->f.seek(*pos)) : 1;
97 }
98 
99 int
101  SD_FILE *stream,
102  ion_fpos_t *pos
103 ) {
104  *pos = (stream) ? stream->f.position() : 0;
105  return 0;
106 }
107 
108 SD_FILE *
110  char *filename,
111  char *mode
112 ) {
113  uint8_t operation;
114  ion_boolean_t seek_start = boolean_false;
115 
116  if ((strcmp(mode, "r") == 0) || (strcmp(mode, "rb") == 0)) {
117  /* Open a file for reading. The file must exist. */
118  /* check to see if file exists */
119 
120  if (!SD.exists(filename)) {
121  return NULL;
122  }
123 
124  operation = FILE_READ;
125  }
126  else if ((strcmp(mode, "w") == 0) || (strcmp(mode, "wb") == 0)) {
127  /* Create an empty file for writing. */
128  /* If a file with the same name already exists */
129  /* its content is erased and the file is */
130  /* considered as a new empty file. */
131 
132  if (SD.exists(filename)) {
133  SD.remove(filename);
134  }
135 
136  operation = FILE_WRITE;
137  /* Open a file for update both reading and writing. The file must exist. */
138  }
139  else if (strstr(mode, "r+") != NULL) {
140  if (!SD.exists(filename)) {
141  return NULL;
142  }
143 
144  operation = FILE_WRITE;
145  seek_start = boolean_true;
146  }
147  /* Create an empty file for both reading and writing. */
148  else if (strstr(mode, "w+") != NULL) {
149  if (SD.exists(filename)) {
150  SD.remove(filename);
151  }
152 
153  operation = FILE_WRITE;
154  }
155  else if (strcmp(mode, "a+") == 0) {
156  operation = FILE_WRITE;
157  }
158  else {
159  return 0; /*incorrect args */
160  }
161 
162  _SD_File *file = new struct _SD_File ();
163 
164  (file)->f = SD.open(filename, operation);
165 
166  if (!((file)->f)) {
167  return 0;
168  }
169 
170  if (seek_start) {
171  file->f.seek(0);
172  }
173 
174  return file;
175 }
176 
177 size_t
179  void *ptr,
180  size_t size,
181  size_t nmemb,
182  SD_FILE *stream
183 ) {
184  /* read is the size of bytes * num of size-bytes */
185  int num_bytes = stream->f.read((char *) ptr, size * nmemb);
186 
187 #if DEBUG
188  Serial.print("Bytes read : ");
189  Serial.println(num_bytes);
190 #endif
191 
192  if (num_bytes < size * nmemb) {
193 #if DEBUG
194  Serial.println("End of file");
195 #endif
196  stream->eof = 1;
197  }
198 
199  return num_bytes / size;
200 }
201 
202 int
204  SD_FILE *stream,
205  long int offset,
206  int whence
207 ) {
208  if (NULL == stream) {
209  return -1;
210  }
211 
212  unsigned long cur_pos = stream->f.position();
213  unsigned long cur_end = stream->f.size();
214 
215  stream->eof = 0;
216 
217  switch (whence) {
218  case SEEK_SET: /* seek from current position */
219  {
220  if (offset < 0) {
221  return -1; /* can't seek before file */
222  }
223 
224  if (offset > cur_end) {
225  if (!stream->f.seek(cur_end)) {
226  return -1;
227  }
228 
229  unsigned long bytes_to_pad = offset - cur_end;
230  char payload = 0x0;
231  size_t num_written = sd_fwrite(&payload, sizeof(payload), bytes_to_pad, stream);
232 
233  if (num_written != bytes_to_pad) {
234  return -1;
235  }
236 
237  /* The file-position indicator has been implicitly moved by the write - no seek needed to be done now */
238  return 0;
239  }
240 
241  return stream->f.seek(offset) ? 0 : -1;
242  break;
243  }
244 
245  case SEEK_CUR: {
246  if (offset + cur_pos > cur_end) {
247  if (!stream->f.seek(cur_end)) {
248  return -1;
249  }
250 
251  unsigned long bytes_to_pad = (offset + cur_pos) - cur_end;
252  char payload = 0x0;
253  size_t num_written = sd_fwrite(&payload, sizeof(payload), bytes_to_pad, stream);
254 
255  if (num_written != bytes_to_pad) {
256  return -1;
257  }
258 
259  /* The file-position indicator has been implicitly moved by the write - no seek needed to be done now */
260  return 0;
261  }
262 
263  if (offset - cur_pos < 0) {
264  return -1; /* too far past beginning of the file - assumes that offset is negative */
265  }
266 
267  return stream->f.seek(cur_pos + offset) ? 0 : -1;
268  break;
269  }
270 
271  case SEEK_END: {
272  if (offset > 0) {
273  if (!stream->f.seek(cur_end)) {
274  return -1;
275  }
276 
277  unsigned long bytes_to_pad = offset;
278  char payload = 0x0;
279  size_t num_written = sd_fwrite(&payload, sizeof(payload), bytes_to_pad, stream);
280 
281  if (num_written != bytes_to_pad) {
282  return -1;
283  }
284 
285  /* The file-position indicator has been implicitly moved by the write - no seek needed to be done now */
286  return 0;
287  }
288 
289  return stream->f.seek(cur_end + offset) ? 0 : -1;
290  break;
291  }
292 
293  default:
294  return -1;
295  }
296 }
297 
298 long int
300  SD_FILE *stream
301 ) {
302  long int pos = (stream) ? stream->f.position() : -1;
303 
304 #if DEBUG
305  Serial.print("cur pos: ");
306  Serial.println(pos);
307 #endif
308  return pos;
309 }
310 
311 size_t
313  void *ptr,
314  size_t size,
315  size_t nmemb,
316  SD_FILE *stream
317 ) {
318  size_t idx;
319  size_t bytes_written = 0;
320  size_t total_count = 0;
321 
322  /* for each element, continue to write */
323  for (idx = 0; idx < nmemb; idx++) {
324  bytes_written = stream->f.write((uint8_t *) ptr, size);
325 
326  if (bytes_written != size) {
327  return total_count;
328  }
329 
330  total_count += 1;
331  }
332 
333  if (total_count != nmemb) {
334  return -1;
335  }
336  else {
337  return total_count;
338  }
339 }
340 
341 int
343  char *filename
344 ) {
345  return SD.remove(filename) ? 0 : 1;
346 }
347 
348 void
350  SD_FILE *stream
351 ) {
352  stream->eof = 0;
353  stream->f.seek(0);
354 }
355 
356 int
358  uint8_t csPin
359 ) {
360  return SD.begin(csPin);
361 }
362 
363 void
365  int i
366 ) {
367  Serial.println(i);
368 }
369 
370 int
372  char *filepath
373 ) {
374  return (int) (SD.exists(filepath));
375 }
376 
377 int
379 ) {
380  File root = SD.open("/");
381 
382  while (true) {
383  File entry = root.openNextFile();
384 
385  if (!entry) {
386  break;
387  }
388 
389  entry.close();
390 
391  bool is_ok = SD.remove(entry.name());
392 
393  if (!is_ok) {
394  return false;
395  }
396  }
397 
398  return true;
399 }
long int sd_ftell(SD_FILE *stream)
size_t sd_fread(void *ptr, size_t size, size_t nmemb, SD_FILE *stream)
int sd_fgetpos(SD_FILE *stream, ion_fpos_t *pos)
A structure that translates a file object to a C-compatible struct.
int sd_fclose(SD_FILE *stream)
size_t sd_fwrite(void *ptr, size_t size, size_t nmemb, SD_FILE *stream)
int sd_fseek(SD_FILE *stream, long int offset, int whence)
int SD_File_Delete_All()
int SD_File_Begin(uint8_t csPin)
int SD_File_Exists(char *filepath)
int sd_feof(SD_FILE *stream)
This code contains definitions for stdio.h file functions for Arduino flash libraries.
void sd_printint(int i)
int sd_fflush(SD_FILE *stream)
void sd_rewind(SD_FILE *stream)
int sd_remove(char *filename)
SD_FILE * sd_fopen(char *filename, char *mode)
int sd_fsetpos(SD_FILE *stream, ion_fpos_t *pos)
long ion_fpos_t
A file position type.
Definition: kv_system.h:237
char ion_boolean_t
A boolean type.
Definition: kv_system.h:269