c5966128c7
Each built-in exception is now a type, with base type BaseException. C exceptions are created by passing a pointer to the exception type to make an instance of. When raising an exception from the VM, an instance is created automatically if an exception type is raised (as opposed to an exception instance). Exception matching (RT_BINARY_OP_EXCEPTION_MATCH) is now proper. Handling of parse error changed to match new exceptions. mp_const_type renamed to mp_type_type for consistency.
94 lines
2.8 KiB
C
94 lines
2.8 KiB
C
#include <stdio.h>
|
|
#include <stm32f4xx.h>
|
|
|
|
#include "misc.h"
|
|
#include "mpconfig.h"
|
|
#include "qstr.h"
|
|
#include "obj.h"
|
|
#include "file.h"
|
|
#include "ff.h"
|
|
|
|
typedef struct _pyb_file_obj_t {
|
|
mp_obj_base_t base;
|
|
FIL fp;
|
|
} pyb_file_obj_t;
|
|
|
|
void file_obj_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
|
|
printf("<file %p>", self_in);
|
|
}
|
|
|
|
mp_obj_t file_obj_read(mp_obj_t self_in, mp_obj_t arg) {
|
|
pyb_file_obj_t *self = self_in;
|
|
int n = mp_obj_get_int(arg);
|
|
byte *buf = m_new(byte, n);
|
|
UINT n_out;
|
|
f_read(&self->fp, buf, n, &n_out);
|
|
return mp_obj_new_str(buf, n_out, false);
|
|
}
|
|
|
|
mp_obj_t file_obj_write(mp_obj_t self_in, mp_obj_t arg) {
|
|
pyb_file_obj_t *self = self_in;
|
|
uint l;
|
|
const char *s = mp_obj_str_get_data(arg, &l);
|
|
UINT n_out;
|
|
FRESULT res = f_write(&self->fp, s, l, &n_out);
|
|
if (res != FR_OK) {
|
|
printf("File error: could not write to file; error code %d\n", res);
|
|
} else if (n_out != l) {
|
|
printf("File error: could not write all data to file; wrote %d / %d bytes\n", n_out, l);
|
|
}
|
|
return mp_const_none;
|
|
}
|
|
|
|
mp_obj_t file_obj_close(mp_obj_t self_in) {
|
|
pyb_file_obj_t *self = self_in;
|
|
f_close(&self->fp);
|
|
return mp_const_none;
|
|
}
|
|
|
|
static MP_DEFINE_CONST_FUN_OBJ_2(file_obj_read_obj, file_obj_read);
|
|
static MP_DEFINE_CONST_FUN_OBJ_2(file_obj_write_obj, file_obj_write);
|
|
static MP_DEFINE_CONST_FUN_OBJ_1(file_obj_close_obj, file_obj_close);
|
|
|
|
// TODO gc hook to close the file if not already closed
|
|
|
|
static const mp_method_t file_methods[] = {
|
|
{ "read", &file_obj_read_obj },
|
|
{ "write", &file_obj_write_obj },
|
|
{ "close", &file_obj_close_obj },
|
|
{NULL, NULL},
|
|
};
|
|
|
|
static const mp_obj_type_t file_obj_type = {
|
|
{ &mp_type_type },
|
|
.name = MP_QSTR_File,
|
|
.print = file_obj_print,
|
|
.methods = file_methods,
|
|
};
|
|
|
|
mp_obj_t pyb_io_open(mp_obj_t o_filename, mp_obj_t o_mode) {
|
|
const char *filename = mp_obj_str_get_str(o_filename);
|
|
const char *mode = mp_obj_str_get_str(o_mode);
|
|
pyb_file_obj_t *self = m_new_obj(pyb_file_obj_t);
|
|
self->base.type = &file_obj_type;
|
|
if (mode[0] == 'r') {
|
|
// open for reading
|
|
FRESULT res = f_open(&self->fp, filename, FA_READ);
|
|
if (res != FR_OK) {
|
|
printf("FileNotFoundError: [Errno 2] No such file or directory: '%s'\n", filename);
|
|
return mp_const_none;
|
|
}
|
|
} else if (mode[0] == 'w') {
|
|
// open for writing, truncate the file first
|
|
FRESULT res = f_open(&self->fp, filename, FA_WRITE | FA_CREATE_ALWAYS);
|
|
if (res != FR_OK) {
|
|
printf("?FileError: could not create file: '%s'\n", filename);
|
|
return mp_const_none;
|
|
}
|
|
} else {
|
|
printf("ValueError: invalid mode: '%s'\n", mode);
|
|
return mp_const_none;
|
|
}
|
|
return self;
|
|
}
|