Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
TASTE
uPython-mirror
Commits
838eb1fa
Commit
838eb1fa
authored
Nov 17, 2014
by
Paul Sokolovsky
Browse files
stream: Implement seek operation support via ioctl, wrapped in generic method.
Also, implement for unix port.
parent
f4a6a577
Changes
6
Hide whitespace changes
Inline
Side-by-side
py/obj.h
View file @
838eb1fa
...
...
@@ -231,8 +231,6 @@ void mp_get_buffer_raise(mp_obj_t obj, mp_buffer_info_t *bufinfo, mp_uint_t flag
// Stream protocol
#define MP_STREAM_ERROR (-1)
#define MP_STREAM_FLUSH (1)
#define MP_STREAM_POLL (2)
typedef
struct
_mp_stream_p_t
{
// On error, functions should return MP_STREAM_ERROR and fill in *errcode (values
// are implementation-dependent, but will be exposed to user, e.g. via exception).
...
...
@@ -242,6 +240,17 @@ typedef struct _mp_stream_p_t {
mp_uint_t
is_text
:
1
;
// default is bytes, set this for text stream
}
mp_stream_p_t
;
// Stream ioctl request codes
#define MP_STREAM_FLUSH (1)
#define MP_STREAM_SEEK (2)
#define MP_STREAM_POLL (3)
// Argument structure for MP_STREAM_SEEK
struct
mp_stream_seek_t
{
mp_off_t
offset
;
int
whence
;
};
struct
_mp_obj_type_t
{
mp_obj_base_t
base
;
qstr
name
;
...
...
py/qstrdefs.h
View file @
838eb1fa
...
...
@@ -455,6 +455,7 @@ Q(readall)
Q
(
readinto
)
Q
(
readline
)
Q
(
readlines
)
Q
(
seek
)
Q
(
FileIO
)
Q
(
TextIOWrapper
)
Q
(
StringIO
)
...
...
py/stream.c
View file @
838eb1fa
...
...
@@ -380,6 +380,32 @@ mp_obj_t mp_stream_unbuffered_iter(mp_obj_t self) {
return
MP_OBJ_STOP_ITERATION
;
}
STATIC
mp_obj_t
stream_seek
(
mp_uint_t
n_args
,
const
mp_obj_t
*
args
)
{
struct
_mp_obj_base_t
*
o
=
(
struct
_mp_obj_base_t
*
)
args
[
0
];
if
(
o
->
type
->
stream_p
==
NULL
||
o
->
type
->
stream_p
->
read
==
NULL
)
{
// CPython: io.UnsupportedOperation, OSError subclass
nlr_raise
(
mp_obj_new_exception_msg
(
&
mp_type_OSError
,
"Operation not supported"
));
}
struct
mp_stream_seek_t
seek_s
;
// TODO: Could be uint64
seek_s
.
offset
=
mp_obj_get_int
(
args
[
1
]);
seek_s
.
whence
=
0
;
if
(
n_args
==
3
)
{
seek_s
.
whence
=
mp_obj_get_int
(
args
[
2
]);
}
int
error
;
mp_uint_t
res
=
o
->
type
->
stream_p
->
ioctl
(
o
,
MP_STREAM_SEEK
,
(
mp_uint_t
)
&
seek_s
,
&
error
);
if
(
res
==
MP_STREAM_ERROR
)
{
nlr_raise
(
mp_obj_new_exception_arg1
(
&
mp_type_OSError
,
MP_OBJ_NEW_SMALL_INT
(
error
)));
}
// TODO: Could be uint64
return
mp_obj_new_int_from_uint
(
seek_s
.
offset
);
}
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN
(
mp_stream_seek_obj
,
2
,
3
,
stream_seek
);
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN
(
mp_stream_read_obj
,
1
,
2
,
stream_read
);
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN
(
mp_stream_readinto_obj
,
2
,
3
,
stream_readinto
);
MP_DEFINE_CONST_FUN_OBJ_1
(
mp_stream_readall_obj
,
stream_readall
);
...
...
py/stream.h
View file @
838eb1fa
...
...
@@ -30,6 +30,7 @@ MP_DECLARE_CONST_FUN_OBJ(mp_stream_readall_obj);
MP_DECLARE_CONST_FUN_OBJ
(
mp_stream_unbuffered_readline_obj
);
MP_DECLARE_CONST_FUN_OBJ
(
mp_stream_unbuffered_readlines_obj
);
MP_DECLARE_CONST_FUN_OBJ
(
mp_stream_write_obj
);
MP_DECLARE_CONST_FUN_OBJ
(
mp_stream_seek_obj
);
// Iterator which uses mp_stream_unbuffered_readline_obj
mp_obj_t
mp_stream_unbuffered_iter
(
mp_obj_t
self
);
...
...
unix/file.c
View file @
838eb1fa
...
...
@@ -88,6 +88,23 @@ STATIC mp_uint_t fdfile_write(mp_obj_t o_in, const void *buf, mp_uint_t size, in
return
r
;
}
STATIC
mp_uint_t
fdfile_ioctl
(
mp_obj_t
o_in
,
mp_uint_t
request
,
mp_uint_t
arg
,
int
*
errcode
)
{
mp_obj_fdfile_t
*
o
=
o_in
;
if
(
request
==
MP_STREAM_SEEK
)
{
struct
mp_stream_seek_t
*
s
=
(
struct
mp_stream_seek_t
*
)
arg
;
off_t
off
=
lseek
(
o
->
fd
,
s
->
offset
,
s
->
whence
);
if
(
off
==
(
off_t
)
-
1
)
{
*
errcode
=
errno
;
return
MP_STREAM_ERROR
;
}
s
->
offset
=
off
;
return
0
;
}
else
{
*
errcode
=
EINVAL
;
return
MP_STREAM_ERROR
;
}
}
STATIC
mp_obj_t
fdfile_flush
(
mp_obj_t
self_in
)
{
mp_obj_fdfile_t
*
self
=
self_in
;
check_fd_is_open
(
self
);
...
...
@@ -192,6 +209,7 @@ STATIC const mp_map_elem_t rawfile_locals_dict_table[] = {
{
MP_OBJ_NEW_QSTR
(
MP_QSTR_readline
),
(
mp_obj_t
)
&
mp_stream_unbuffered_readline_obj
},
{
MP_OBJ_NEW_QSTR
(
MP_QSTR_readlines
),
(
mp_obj_t
)
&
mp_stream_unbuffered_readlines_obj
},
{
MP_OBJ_NEW_QSTR
(
MP_QSTR_write
),
(
mp_obj_t
)
&
mp_stream_write_obj
},
{
MP_OBJ_NEW_QSTR
(
MP_QSTR_seek
),
(
mp_obj_t
)
&
mp_stream_seek_obj
},
{
MP_OBJ_NEW_QSTR
(
MP_QSTR_flush
),
(
mp_obj_t
)
&
fdfile_flush_obj
},
{
MP_OBJ_NEW_QSTR
(
MP_QSTR_close
),
(
mp_obj_t
)
&
fdfile_close_obj
},
{
MP_OBJ_NEW_QSTR
(
MP_QSTR___enter__
),
(
mp_obj_t
)
&
mp_identity_obj
},
...
...
@@ -204,6 +222,7 @@ STATIC MP_DEFINE_CONST_DICT(rawfile_locals_dict, rawfile_locals_dict_table);
STATIC
const
mp_stream_p_t
fileio_stream_p
=
{
.
read
=
fdfile_read
,
.
write
=
fdfile_write
,
.
ioctl
=
fdfile_ioctl
,
};
const
mp_obj_type_t
mp_type_fileio
=
{
...
...
unix/mpconfigport.h
View file @
838eb1fa
...
...
@@ -122,6 +122,13 @@ typedef unsigned int mp_uint_t; // must be pointer size
#define BYTES_PER_WORD sizeof(mp_int_t)
// Cannot include <sys/types.h>, as it may lead to symbol name clashes
#if _FILE_OFFSET_BITS == 64 && !defined(__LP64__)
typedef
long
long
mp_off_t
;
#else
typedef
long
mp_off_t
;
#endif
typedef
void
*
machine_ptr_t
;
// must be of pointer size
typedef
const
void
*
machine_const_ptr_t
;
// must be of pointer size
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment