Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
allendowney
GitHub Repository: allendowney/cpython
Path: blob/main/Modules/_io/_iomodule.h
12 views
1
/*
2
* Declarations shared between the different parts of the io module
3
*/
4
5
#include "exports.h"
6
7
#include "pycore_moduleobject.h" // _PyModule_GetState()
8
#include "pycore_typeobject.h" // _PyType_GetModuleState()
9
#include "structmember.h"
10
11
/* Type specs */
12
extern PyType_Spec bufferediobase_spec;
13
extern PyType_Spec bufferedrandom_spec;
14
extern PyType_Spec bufferedreader_spec;
15
extern PyType_Spec bufferedrwpair_spec;
16
extern PyType_Spec bufferedwriter_spec;
17
extern PyType_Spec bytesio_spec;
18
extern PyType_Spec bytesiobuf_spec;
19
extern PyType_Spec fileio_spec;
20
extern PyType_Spec iobase_spec;
21
extern PyType_Spec nldecoder_spec;
22
extern PyType_Spec rawiobase_spec;
23
extern PyType_Spec stringio_spec;
24
extern PyType_Spec textiobase_spec;
25
extern PyType_Spec textiowrapper_spec;
26
27
#ifdef HAVE_WINDOWS_CONSOLE_IO
28
extern PyType_Spec winconsoleio_spec;
29
#endif
30
31
/* These functions are used as METH_NOARGS methods, are normally called
32
* with args=NULL, and return a new reference.
33
* BUT when args=Py_True is passed, they return a borrowed reference.
34
*/
35
typedef struct _io_state _PyIO_State; // Forward decl.
36
extern PyObject* _PyIOBase_check_readable(_PyIO_State *state,
37
PyObject *self, PyObject *args);
38
extern PyObject* _PyIOBase_check_writable(_PyIO_State *state,
39
PyObject *self, PyObject *args);
40
extern PyObject* _PyIOBase_check_seekable(_PyIO_State *state,
41
PyObject *self, PyObject *args);
42
extern PyObject* _PyIOBase_check_closed(PyObject *self, PyObject *args);
43
44
/* Helper for finalization.
45
This function will revive an object ready to be deallocated and try to
46
close() it. It returns 0 if the object can be destroyed, or -1 if it
47
is alive again. */
48
extern int _PyIOBase_finalize(PyObject *self);
49
50
/* Returns true if the given FileIO object is closed.
51
Doesn't check the argument type, so be careful! */
52
extern int _PyFileIO_closed(PyObject *self);
53
54
/* Shortcut to the core of the IncrementalNewlineDecoder.decode method */
55
extern PyObject *_PyIncrementalNewlineDecoder_decode(
56
PyObject *self, PyObject *input, int final);
57
58
/* Finds the first line ending between `start` and `end`.
59
If found, returns the index after the line ending and doesn't touch
60
`*consumed`.
61
If not found, returns -1 and sets `*consumed` to the number of characters
62
which can be safely put aside until another search.
63
64
NOTE: for performance reasons, `end` must point to a NUL character ('\0').
65
Otherwise, the function will scan further and return garbage.
66
67
There are three modes, in order of priority:
68
* translated: Only find \n (assume newlines already translated)
69
* universal: Use universal newlines algorithm
70
* Otherwise, the line ending is specified by readnl, a str object */
71
extern Py_ssize_t _PyIO_find_line_ending(
72
int translated, int universal, PyObject *readnl,
73
int kind, const char *start, const char *end, Py_ssize_t *consumed);
74
75
/* Return 1 if an OSError with errno == EINTR is set (and then
76
clears the error indicator), 0 otherwise.
77
Should only be called when PyErr_Occurred() is true.
78
*/
79
extern int _PyIO_trap_eintr(void);
80
81
#define DEFAULT_BUFFER_SIZE (8 * 1024) /* bytes */
82
83
/*
84
* Offset type for positioning.
85
*/
86
87
/* Printing a variable of type off_t (with e.g., PyUnicode_FromFormat)
88
correctly and without producing compiler warnings is surprisingly painful.
89
We identify an integer type whose size matches off_t and then: (1) cast the
90
off_t to that integer type and (2) use the appropriate conversion
91
specification. The cast is necessary: gcc complains about formatting a
92
long with "%lld" even when both long and long long have the same
93
precision. */
94
95
#ifdef MS_WINDOWS
96
97
/* Windows uses long long for offsets */
98
typedef long long Py_off_t;
99
# define PyLong_AsOff_t PyLong_AsLongLong
100
# define PyLong_FromOff_t PyLong_FromLongLong
101
# define PY_OFF_T_MAX LLONG_MAX
102
# define PY_OFF_T_MIN LLONG_MIN
103
# define PY_OFF_T_COMPAT long long /* type compatible with off_t */
104
# define PY_PRIdOFF "lld" /* format to use for that type */
105
106
#else
107
108
/* Other platforms use off_t */
109
typedef off_t Py_off_t;
110
#if (SIZEOF_OFF_T == SIZEOF_SIZE_T)
111
# define PyLong_AsOff_t PyLong_AsSsize_t
112
# define PyLong_FromOff_t PyLong_FromSsize_t
113
# define PY_OFF_T_MAX PY_SSIZE_T_MAX
114
# define PY_OFF_T_MIN PY_SSIZE_T_MIN
115
# define PY_OFF_T_COMPAT Py_ssize_t
116
# define PY_PRIdOFF "zd"
117
#elif (SIZEOF_OFF_T == SIZEOF_LONG_LONG)
118
# define PyLong_AsOff_t PyLong_AsLongLong
119
# define PyLong_FromOff_t PyLong_FromLongLong
120
# define PY_OFF_T_MAX LLONG_MAX
121
# define PY_OFF_T_MIN LLONG_MIN
122
# define PY_OFF_T_COMPAT long long
123
# define PY_PRIdOFF "lld"
124
#elif (SIZEOF_OFF_T == SIZEOF_LONG)
125
# define PyLong_AsOff_t PyLong_AsLong
126
# define PyLong_FromOff_t PyLong_FromLong
127
# define PY_OFF_T_MAX LONG_MAX
128
# define PY_OFF_T_MIN LONG_MIN
129
# define PY_OFF_T_COMPAT long
130
# define PY_PRIdOFF "ld"
131
#else
132
# error off_t does not match either size_t, long, or long long!
133
#endif
134
135
#endif
136
137
extern Py_off_t PyNumber_AsOff_t(PyObject *item, PyObject *err);
138
139
/* Implementation details */
140
141
/* IO module structure */
142
143
extern PyModuleDef _PyIO_Module;
144
145
struct _io_state {
146
int initialized;
147
PyObject *unsupported_operation;
148
149
/* Types */
150
PyTypeObject *PyIOBase_Type;
151
PyTypeObject *PyIncrementalNewlineDecoder_Type;
152
PyTypeObject *PyRawIOBase_Type;
153
PyTypeObject *PyBufferedIOBase_Type;
154
PyTypeObject *PyBufferedRWPair_Type;
155
PyTypeObject *PyBufferedRandom_Type;
156
PyTypeObject *PyBufferedReader_Type;
157
PyTypeObject *PyBufferedWriter_Type;
158
PyTypeObject *PyBytesIOBuffer_Type;
159
PyTypeObject *PyBytesIO_Type;
160
PyTypeObject *PyFileIO_Type;
161
PyTypeObject *PyStringIO_Type;
162
PyTypeObject *PyTextIOBase_Type;
163
PyTypeObject *PyTextIOWrapper_Type;
164
#ifdef HAVE_WINDOWS_CONSOLE_IO
165
PyTypeObject *PyWindowsConsoleIO_Type;
166
#endif
167
};
168
169
static inline _PyIO_State *
170
get_io_state(PyObject *module)
171
{
172
void *state = _PyModule_GetState(module);
173
assert(state != NULL);
174
return (_PyIO_State *)state;
175
}
176
177
static inline _PyIO_State *
178
get_io_state_by_cls(PyTypeObject *cls)
179
{
180
void *state = _PyType_GetModuleState(cls);
181
assert(state != NULL);
182
return (_PyIO_State *)state;
183
}
184
185
static inline _PyIO_State *
186
find_io_state_by_def(PyTypeObject *type)
187
{
188
PyObject *mod = PyType_GetModuleByDef(type, &_PyIO_Module);
189
assert(mod != NULL);
190
return get_io_state(mod);
191
}
192
193
extern PyObject *_PyIOBase_cannot_pickle(PyObject *self, PyObject *args);
194
195
#ifdef HAVE_WINDOWS_CONSOLE_IO
196
extern char _PyIO_get_console_type(PyObject *);
197
#endif
198
199