mux | 40048ad | 2014-01-24 17:14:13 +0200 | [diff] [blame] | 1 | #include <stdio.h> |
| 2 | #include <stm32f4xx.h> |
| 3 | |
| 4 | #include "misc.h" |
| 5 | #include "mpconfig.h" |
mux | 40048ad | 2014-01-24 17:14:13 +0200 | [diff] [blame] | 6 | #include "qstr.h" |
| 7 | #include "obj.h" |
| 8 | #include "file.h" |
| 9 | #include "ff.h" |
| 10 | |
| 11 | typedef struct _pyb_file_obj_t { |
| 12 | mp_obj_base_t base; |
| 13 | FIL fp; |
| 14 | } pyb_file_obj_t; |
| 15 | |
| 16 | void file_obj_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) { |
| 17 | printf("<file %p>", self_in); |
| 18 | } |
| 19 | |
| 20 | mp_obj_t file_obj_read(mp_obj_t self_in, mp_obj_t arg) { |
| 21 | pyb_file_obj_t *self = self_in; |
| 22 | int n = mp_obj_get_int(arg); |
| 23 | byte *buf = m_new(byte, n); |
| 24 | UINT n_out; |
| 25 | f_read(&self->fp, buf, n, &n_out); |
| 26 | return mp_obj_new_str(buf, n_out, false); |
| 27 | } |
| 28 | |
| 29 | mp_obj_t file_obj_write(mp_obj_t self_in, mp_obj_t arg) { |
| 30 | pyb_file_obj_t *self = self_in; |
| 31 | uint l; |
Damien George | 698ec21 | 2014-02-08 18:17:23 +0000 | [diff] [blame] | 32 | const char *s = mp_obj_str_get_data(arg, &l); |
mux | 40048ad | 2014-01-24 17:14:13 +0200 | [diff] [blame] | 33 | UINT n_out; |
| 34 | FRESULT res = f_write(&self->fp, s, l, &n_out); |
| 35 | if (res != FR_OK) { |
| 36 | printf("File error: could not write to file; error code %d\n", res); |
| 37 | } else if (n_out != l) { |
| 38 | printf("File error: could not write all data to file; wrote %d / %d bytes\n", n_out, l); |
| 39 | } |
| 40 | return mp_const_none; |
| 41 | } |
| 42 | |
| 43 | mp_obj_t file_obj_close(mp_obj_t self_in) { |
| 44 | pyb_file_obj_t *self = self_in; |
| 45 | f_close(&self->fp); |
| 46 | return mp_const_none; |
| 47 | } |
| 48 | |
| 49 | static MP_DEFINE_CONST_FUN_OBJ_2(file_obj_read_obj, file_obj_read); |
| 50 | static MP_DEFINE_CONST_FUN_OBJ_2(file_obj_write_obj, file_obj_write); |
| 51 | static MP_DEFINE_CONST_FUN_OBJ_1(file_obj_close_obj, file_obj_close); |
| 52 | |
| 53 | // TODO gc hook to close the file if not already closed |
| 54 | |
| 55 | static const mp_method_t file_methods[] = { |
| 56 | { "read", &file_obj_read_obj }, |
| 57 | { "write", &file_obj_write_obj }, |
| 58 | { "close", &file_obj_close_obj }, |
| 59 | {NULL, NULL}, |
| 60 | }; |
| 61 | |
| 62 | static const mp_obj_type_t file_obj_type = { |
Damien George | c596612 | 2014-02-15 16:10:44 +0000 | [diff] [blame^] | 63 | { &mp_type_type }, |
Damien George | a71c83a | 2014-02-15 11:34:50 +0000 | [diff] [blame] | 64 | .name = MP_QSTR_File, |
mux | 40048ad | 2014-01-24 17:14:13 +0200 | [diff] [blame] | 65 | .print = file_obj_print, |
| 66 | .methods = file_methods, |
| 67 | }; |
| 68 | |
| 69 | mp_obj_t pyb_io_open(mp_obj_t o_filename, mp_obj_t o_mode) { |
| 70 | const char *filename = mp_obj_str_get_str(o_filename); |
| 71 | const char *mode = mp_obj_str_get_str(o_mode); |
| 72 | pyb_file_obj_t *self = m_new_obj(pyb_file_obj_t); |
| 73 | self->base.type = &file_obj_type; |
| 74 | if (mode[0] == 'r') { |
| 75 | // open for reading |
| 76 | FRESULT res = f_open(&self->fp, filename, FA_READ); |
| 77 | if (res != FR_OK) { |
| 78 | printf("FileNotFoundError: [Errno 2] No such file or directory: '%s'\n", filename); |
| 79 | return mp_const_none; |
| 80 | } |
| 81 | } else if (mode[0] == 'w') { |
| 82 | // open for writing, truncate the file first |
| 83 | FRESULT res = f_open(&self->fp, filename, FA_WRITE | FA_CREATE_ALWAYS); |
| 84 | if (res != FR_OK) { |
| 85 | printf("?FileError: could not create file: '%s'\n", filename); |
| 86 | return mp_const_none; |
| 87 | } |
| 88 | } else { |
| 89 | printf("ValueError: invalid mode: '%s'\n", mode); |
| 90 | return mp_const_none; |
| 91 | } |
| 92 | return self; |
| 93 | } |