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 *
get_io_state(PyObject * module)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 *
get_io_state_by_cls(PyTypeObject * cls)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 *
find_io_state_by_def(PyTypeObject * type)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