Paul Sokolovsky | e98cf40 | 2014-01-08 02:43:48 +0200 | [diff] [blame^] | 1 | #include <string.h> |
| 2 | |
| 3 | #include "nlr.h" |
| 4 | #include "misc.h" |
| 5 | #include "mpconfig.h" |
| 6 | #include "mpqstr.h" |
| 7 | #include "obj.h" |
| 8 | #include "stream.h" |
| 9 | |
| 10 | // This file defines generic Python stream read/write methods which |
| 11 | // dispatch to the underlying stream interface of an object. |
| 12 | |
| 13 | static mp_obj_t stream_read(mp_obj_t self_in, mp_obj_t arg) { |
| 14 | struct _mp_obj_base_t *o = (struct _mp_obj_base_t *)self_in; |
| 15 | if (o->type->stream_p.read == NULL) { |
| 16 | // CPython: io.UnsupportedOperation, OSError subclass |
| 17 | nlr_jump(mp_obj_new_exception_msg(MP_QSTR_OSError, "Operation not supported")); |
| 18 | } |
| 19 | |
| 20 | machine_int_t sz = mp_obj_get_int(arg); |
| 21 | // +1 because so far we mark end of string with \0 |
| 22 | char *buf = m_new(char, sz + 1); |
| 23 | int error; |
| 24 | machine_int_t out_sz = o->type->stream_p.read(self_in, buf, sz, &error); |
| 25 | if (out_sz == -1) { |
| 26 | nlr_jump(mp_obj_new_exception_msg_1_arg(MP_QSTR_OSError, "[Errno %d]", (const char *)error)); |
| 27 | } else { |
| 28 | buf[out_sz] = 0; |
| 29 | return mp_obj_new_str(qstr_from_str_take(buf, /*out_sz,*/ sz + 1)); |
| 30 | } |
| 31 | } |
| 32 | |
| 33 | static mp_obj_t stream_write(mp_obj_t self_in, mp_obj_t arg) { |
| 34 | struct _mp_obj_base_t *o = (struct _mp_obj_base_t *)self_in; |
| 35 | if (o->type->stream_p.write == NULL) { |
| 36 | // CPython: io.UnsupportedOperation, OSError subclass |
| 37 | nlr_jump(mp_obj_new_exception_msg(MP_QSTR_OSError, "Operation not supported")); |
| 38 | } |
| 39 | |
| 40 | const char *buf = qstr_str(mp_obj_get_qstr(arg)); |
| 41 | machine_int_t sz = strlen(buf); |
| 42 | int error; |
| 43 | machine_int_t out_sz = o->type->stream_p.write(self_in, buf, sz, &error); |
| 44 | if (out_sz == -1) { |
| 45 | nlr_jump(mp_obj_new_exception_msg_1_arg(MP_QSTR_OSError, "[Errno %d]", (const char *)error)); |
| 46 | } else { |
| 47 | // http://docs.python.org/3/library/io.html#io.RawIOBase.write |
| 48 | // "None is returned if the raw stream is set not to block and no single byte could be readily written to it." |
| 49 | // Do they mean that instead of 0 they return None? |
| 50 | return MP_OBJ_NEW_SMALL_INT(out_sz); |
| 51 | } |
| 52 | } |
| 53 | |
| 54 | MP_DEFINE_CONST_FUN_OBJ_2(mp_stream_read_obj, stream_read); |
| 55 | MP_DEFINE_CONST_FUN_OBJ_2(mp_stream_write_obj, stream_write); |