• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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