Skip to content

Commit adf0f2a

Browse files
committed
py: Change stream protocol API: fns return uint; is_text for text.
1 parent 05c255f commit adf0f2a

File tree

7 files changed

+45
-41
lines changed

7 files changed

+45
-41
lines changed

py/obj.h

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -228,13 +228,14 @@ bool mp_get_buffer(mp_obj_t obj, mp_buffer_info_t *bufinfo, int flags);
228228
void mp_get_buffer_raise(mp_obj_t obj, mp_buffer_info_t *bufinfo, int flags);
229229

230230
// Stream protocol
231+
#define MP_STREAM_ERROR (-1)
231232
typedef struct _mp_stream_p_t {
232-
// On error, functions should return -1 and fill in *errcode (values are
233-
// implementation-dependent, but will be exposed to user, e.g. via exception).
234-
mp_int_t (*read)(mp_obj_t obj, void *buf, mp_uint_t size, int *errcode);
235-
mp_int_t (*write)(mp_obj_t obj, const void *buf, mp_uint_t size, int *errcode);
233+
// On error, functions should return MP_STREAM_ERROR and fill in *errcode (values
234+
// are implementation-dependent, but will be exposed to user, e.g. via exception).
235+
mp_uint_t (*read)(mp_obj_t obj, void *buf, mp_uint_t size, int *errcode);
236+
mp_uint_t (*write)(mp_obj_t obj, const void *buf, mp_uint_t size, int *errcode);
236237
// add seek() ?
237-
int is_bytes : 1;
238+
int is_text : 1; // default is bytes, set this for text stream
238239
} mp_stream_p_t;
239240

240241
struct _mp_obj_type_t {

py/objstringio.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ STATIC void stringio_print(void (*print)(void *env, const char *fmt, ...), void
5151
print(env, self->base.type == &mp_type_stringio ? "<io.StringIO 0x%x>" : "<io.BytesIO 0x%x>", self->vstr);
5252
}
5353

54-
STATIC mp_int_t stringio_read(mp_obj_t o_in, void *buf, mp_uint_t size, int *errcode) {
54+
STATIC mp_uint_t stringio_read(mp_obj_t o_in, void *buf, mp_uint_t size, int *errcode) {
5555
mp_obj_stringio_t *o = o_in;
5656
mp_uint_t remaining = o->vstr->len - o->pos;
5757
if (size > remaining) {
@@ -62,7 +62,7 @@ STATIC mp_int_t stringio_read(mp_obj_t o_in, void *buf, mp_uint_t size, int *err
6262
return size;
6363
}
6464

65-
STATIC mp_int_t stringio_write(mp_obj_t o_in, const void *buf, mp_uint_t size, int *errcode) {
65+
STATIC mp_uint_t stringio_write(mp_obj_t o_in, const void *buf, mp_uint_t size, int *errcode) {
6666
mp_obj_stringio_t *o = o_in;
6767
mp_uint_t remaining = o->vstr->alloc - o->pos;
6868
if (size > remaining) {
@@ -137,12 +137,12 @@ STATIC MP_DEFINE_CONST_DICT(stringio_locals_dict, stringio_locals_dict_table);
137137
STATIC const mp_stream_p_t stringio_stream_p = {
138138
.read = stringio_read,
139139
.write = stringio_write,
140+
.is_text = true,
140141
};
141142

142143
STATIC const mp_stream_p_t bytesio_stream_p = {
143144
.read = stringio_read,
144145
.write = stringio_write,
145-
.is_bytes = true,
146146
};
147147

148148
const mp_obj_type_t mp_type_stringio = {

py/stream.c

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ STATIC mp_obj_t stream_readall(mp_obj_t self_in);
5858
#define is_nonblocking_error(errno) (0)
5959
#endif
6060

61-
#define STREAM_CONTENT_TYPE(stream) (((stream)->is_bytes) ? &mp_type_bytes : &mp_type_str)
61+
#define STREAM_CONTENT_TYPE(stream) (((stream)->is_text) ? &mp_type_str : &mp_type_bytes)
6262

6363
STATIC mp_obj_t stream_read(uint n_args, const mp_obj_t *args) {
6464
struct _mp_obj_base_t *o = (struct _mp_obj_base_t *)args[0];
@@ -76,7 +76,7 @@ STATIC mp_obj_t stream_read(uint n_args, const mp_obj_t *args) {
7676
}
7777

7878
#if MICROPY_PY_BUILTINS_STR_UNICODE
79-
if (!o->type->stream_p->is_bytes) {
79+
if (o->type->stream_p->is_text) {
8080
// We need to read sz number of unicode characters. Because we don't have any
8181
// buffering, and because the stream API can only read bytes, we must read here
8282
// in units of bytes and must never over read. If we want sz chars, then reading
@@ -96,8 +96,8 @@ STATIC mp_obj_t stream_read(uint n_args, const mp_obj_t *args) {
9696
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_MemoryError, "out of memory"));
9797
}
9898
int error;
99-
mp_int_t out_sz = o->type->stream_p->read(o, p, more_bytes, &error);
100-
if (out_sz == -1) {
99+
mp_uint_t out_sz = o->type->stream_p->read(o, p, more_bytes, &error);
100+
if (out_sz == MP_STREAM_ERROR) {
101101
vstr_cut_tail_bytes(&vstr, more_bytes);
102102
if (is_nonblocking_error(error)) {
103103
// With non-blocking streams, we read as much as we can.
@@ -113,7 +113,7 @@ STATIC mp_obj_t stream_read(uint n_args, const mp_obj_t *args) {
113113
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, "[Errno %d]", error));
114114
}
115115

116-
if ((mp_uint_t)out_sz < more_bytes) {
116+
if (out_sz < more_bytes) {
117117
// Finish reading.
118118
// TODO what if we have read only half a non-ASCII char?
119119
vstr_cut_tail_bytes(&vstr, more_bytes - out_sz);
@@ -168,8 +168,8 @@ STATIC mp_obj_t stream_read(uint n_args, const mp_obj_t *args) {
168168

169169
byte *buf = m_new(byte, sz);
170170
int error;
171-
mp_int_t out_sz = o->type->stream_p->read(o, buf, sz, &error);
172-
if (out_sz == -1) {
171+
mp_uint_t out_sz = o->type->stream_p->read(o, buf, sz, &error);
172+
if (out_sz == MP_STREAM_ERROR) {
173173
if (is_nonblocking_error(error)) {
174174
// https://docs.python.org/3.4/library/io.html#io.RawIOBase.read
175175
// "If the object is in non-blocking mode and no bytes are available,
@@ -194,8 +194,8 @@ mp_obj_t mp_stream_write(mp_obj_t self_in, const void *buf, mp_uint_t len) {
194194
}
195195

196196
int error;
197-
mp_int_t out_sz = o->type->stream_p->write(self_in, buf, len, &error);
198-
if (out_sz == -1) {
197+
mp_uint_t out_sz = o->type->stream_p->write(self_in, buf, len, &error);
198+
if (out_sz == MP_STREAM_ERROR) {
199199
if (is_nonblocking_error(error)) {
200200
// http://docs.python.org/3/library/io.html#io.RawIOBase.write
201201
// "None is returned if the raw stream is set not to block and
@@ -230,8 +230,8 @@ STATIC mp_obj_t stream_readall(mp_obj_t self_in) {
230230
int error;
231231
int current_read = DEFAULT_BUFFER_SIZE;
232232
while (true) {
233-
mp_int_t out_sz = o->type->stream_p->read(self_in, p, current_read, &error);
234-
if (out_sz == -1) {
233+
mp_uint_t out_sz = o->type->stream_p->read(self_in, p, current_read, &error);
234+
if (out_sz == MP_STREAM_ERROR) {
235235
if (is_nonblocking_error(error)) {
236236
// With non-blocking streams, we read as much as we can.
237237
// If we read nothing, return None, just like read().
@@ -292,16 +292,15 @@ STATIC mp_obj_t stream_unbuffered_readline(uint n_args, const mp_obj_t *args) {
292292
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_MemoryError, "out of memory"));
293293
}
294294

295-
mp_int_t out_sz = o->type->stream_p->read(o, p, 1, &error);
296-
if (out_sz == -1) {
295+
mp_uint_t out_sz = o->type->stream_p->read(o, p, 1, &error);
296+
if (out_sz == MP_STREAM_ERROR) {
297297
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, "[Errno %d]", error));
298298
}
299299
if (out_sz == 0) {
300300
// Back out previously added byte
301-
// TODO: This is a bit hacky, does it supported by vstr API contract?
302301
// Consider, what's better - read a char and get OutOfMemory (so read
303302
// char is lost), or allocate first as we do.
304-
vstr_add_len(vstr, -1);
303+
vstr_cut_tail_bytes(vstr, 1);
305304
break;
306305
}
307306
if (*p == '\n') {

stmhal/file.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -73,24 +73,24 @@ void file_obj_print(void (*print)(void *env, const char *fmt, ...), void *env, m
7373
print(env, "<io.%s %p>", mp_obj_get_type_str(self_in), self_in);
7474
}
7575

76-
STATIC mp_int_t file_obj_read(mp_obj_t self_in, void *buf, mp_uint_t size, int *errcode) {
76+
STATIC mp_uint_t file_obj_read(mp_obj_t self_in, void *buf, mp_uint_t size, int *errcode) {
7777
pyb_file_obj_t *self = self_in;
7878
UINT sz_out;
7979
FRESULT res = f_read(&self->fp, buf, size, &sz_out);
8080
if (res != FR_OK) {
8181
*errcode = fresult_to_errno_table[res];
82-
return -1;
82+
return MP_STREAM_ERROR;
8383
}
8484
return sz_out;
8585
}
8686

87-
STATIC mp_int_t file_obj_write(mp_obj_t self_in, const void *buf, mp_uint_t size, int *errcode) {
87+
STATIC mp_uint_t file_obj_write(mp_obj_t self_in, const void *buf, mp_uint_t size, int *errcode) {
8888
pyb_file_obj_t *self = self_in;
8989
UINT sz_out;
9090
FRESULT res = f_write(&self->fp, buf, size, &sz_out);
9191
if (res != FR_OK) {
9292
*errcode = fresult_to_errno_table[res];
93-
return -1;
93+
return MP_STREAM_ERROR;
9494
}
9595
return sz_out;
9696
}
@@ -240,7 +240,6 @@ STATIC MP_DEFINE_CONST_DICT(rawfile_locals_dict, rawfile_locals_dict_table);
240240
STATIC const mp_stream_p_t fileio_stream_p = {
241241
.read = file_obj_read,
242242
.write = file_obj_write,
243-
.is_bytes = true,
244243
};
245244

246245
const mp_obj_type_t mp_type_fileio = {
@@ -258,6 +257,7 @@ const mp_obj_type_t mp_type_fileio = {
258257
STATIC const mp_stream_p_t textio_stream_p = {
259258
.read = file_obj_read,
260259
.write = file_obj_write,
260+
.is_text = true,
261261
};
262262

263263
const mp_obj_type_t mp_type_textio = {

stmhal/pybstdio.c

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#include <stdio.h>
2828
#include <stdint.h>
2929
#include <string.h>
30+
#include <errno.h>
3031

3132
#include "mpconfig.h"
3233
#include "misc.h"
@@ -109,7 +110,7 @@ void stdio_obj_print(void (*print)(void *env, const char *fmt, ...), void *env,
109110
print(env, "<io.FileIO %d>", self->fd);
110111
}
111112

112-
STATIC mp_int_t stdio_read(mp_obj_t self_in, void *buf, mp_uint_t size, int *errcode) {
113+
STATIC mp_uint_t stdio_read(mp_obj_t self_in, void *buf, mp_uint_t size, int *errcode) {
113114
pyb_stdio_obj_t *self = self_in;
114115
if (self->fd == STDIO_FD_IN) {
115116
for (uint i = 0; i < size; i++) {
@@ -119,23 +120,21 @@ STATIC mp_int_t stdio_read(mp_obj_t self_in, void *buf, mp_uint_t size, int *err
119120
}
120121
((byte*)buf)[i] = c;
121122
}
122-
*errcode = 0;
123123
return size;
124124
} else {
125-
*errcode = 1;
126-
return 0;
125+
*errcode = EPERM;
126+
return MP_STREAM_ERROR;
127127
}
128128
}
129129

130-
STATIC mp_int_t stdio_write(mp_obj_t self_in, const void *buf, mp_uint_t size, int *errcode) {
130+
STATIC mp_uint_t stdio_write(mp_obj_t self_in, const void *buf, mp_uint_t size, int *errcode) {
131131
pyb_stdio_obj_t *self = self_in;
132132
if (self->fd == STDIO_FD_OUT || self->fd == STDIO_FD_ERR) {
133133
stdout_tx_strn_cooked(buf, size);
134-
*errcode = 0;
135134
return size;
136135
} else {
137-
*errcode = 1;
138-
return 0;
136+
*errcode = EPERM;
137+
return MP_STREAM_ERROR;
139138
}
140139
}
141140

@@ -162,6 +161,7 @@ STATIC MP_DEFINE_CONST_DICT(stdio_locals_dict, stdio_locals_dict_table);
162161
STATIC const mp_stream_p_t stdio_obj_stream_p = {
163162
.read = stdio_read,
164163
.write = stdio_write,
164+
.is_text = true,
165165
};
166166

167167
STATIC const mp_obj_type_t stdio_obj_type = {

unix/file.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -66,22 +66,24 @@ STATIC void fdfile_print(void (*print)(void *env, const char *fmt, ...), void *e
6666
print(env, "<io.%s %d>", mp_obj_get_type_str(self), self->fd);
6767
}
6868

69-
STATIC mp_int_t fdfile_read(mp_obj_t o_in, void *buf, mp_uint_t size, int *errcode) {
69+
STATIC mp_uint_t fdfile_read(mp_obj_t o_in, void *buf, mp_uint_t size, int *errcode) {
7070
mp_obj_fdfile_t *o = o_in;
7171
check_fd_is_open(o);
7272
mp_int_t r = read(o->fd, buf, size);
7373
if (r == -1) {
7474
*errcode = errno;
75+
return MP_STREAM_ERROR;
7576
}
7677
return r;
7778
}
7879

79-
STATIC mp_int_t fdfile_write(mp_obj_t o_in, const void *buf, mp_uint_t size, int *errcode) {
80+
STATIC mp_uint_t fdfile_write(mp_obj_t o_in, const void *buf, mp_uint_t size, int *errcode) {
8081
mp_obj_fdfile_t *o = o_in;
8182
check_fd_is_open(o);
8283
mp_int_t r = write(o->fd, buf, size);
8384
if (r == -1) {
8485
*errcode = errno;
86+
return MP_STREAM_ERROR;
8587
}
8688
return r;
8789
}
@@ -190,7 +192,6 @@ STATIC MP_DEFINE_CONST_DICT(rawfile_locals_dict, rawfile_locals_dict_table);
190192
STATIC const mp_stream_p_t fileio_stream_p = {
191193
.read = fdfile_read,
192194
.write = fdfile_write,
193-
.is_bytes = true,
194195
};
195196

196197
const mp_obj_type_t mp_type_fileio = {
@@ -208,6 +209,7 @@ const mp_obj_type_t mp_type_fileio = {
208209
STATIC const mp_stream_p_t textio_stream_p = {
209210
.read = fdfile_read,
210211
.write = fdfile_write,
212+
.is_text = true,
211213
};
212214

213215
const mp_obj_type_t mp_type_textio = {

unix/modsocket.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,20 +91,22 @@ STATIC void socket_print(void (*print)(void *env, const char *fmt, ...), void *e
9191
print(env, "<_socket %d>", self->fd);
9292
}
9393

94-
STATIC mp_int_t socket_read(mp_obj_t o_in, void *buf, mp_uint_t size, int *errcode) {
94+
STATIC mp_uint_t socket_read(mp_obj_t o_in, void *buf, mp_uint_t size, int *errcode) {
9595
mp_obj_socket_t *o = o_in;
9696
mp_int_t r = read(o->fd, buf, size);
9797
if (r == -1) {
9898
*errcode = errno;
99+
return MP_STREAM_ERROR;
99100
}
100101
return r;
101102
}
102103

103-
STATIC mp_int_t socket_write(mp_obj_t o_in, const void *buf, mp_uint_t size, int *errcode) {
104+
STATIC mp_uint_t socket_write(mp_obj_t o_in, const void *buf, mp_uint_t size, int *errcode) {
104105
mp_obj_socket_t *o = o_in;
105106
mp_int_t r = write(o->fd, buf, size);
106107
if (r == -1) {
107108
*errcode = errno;
109+
return MP_STREAM_ERROR;
108110
}
109111
return r;
110112
}

0 commit comments

Comments
 (0)