* Read a file into the provided array, or create (and possibly grow) an * array to read into. * * @param s The stream object/struct providing reading capabilities used by * the tokenizer. * @param max_rows The number of rows to read, or -1. If negative * all rows are read. * @param num_field_types The number of field types stored in `field_types`. * @param field_types Inform
| 153 | * is always a new reference (even when `data_array` was passed in). |
| 154 | */ |
| 155 | NPY_NO_EXPORT PyArrayObject * |
| 156 | read_rows(stream *s, |
| 157 | npy_intp max_rows, Py_ssize_t num_field_types, field_type *field_types, |
| 158 | parser_config *pconfig, Py_ssize_t num_usecols, Py_ssize_t *usecols, |
| 159 | Py_ssize_t skiplines, PyObject *converters, |
| 160 | PyArrayObject *data_array, PyArray_Descr *out_descr, |
| 161 | bool homogeneous) |
| 162 | { |
| 163 | char *data_ptr = NULL; |
| 164 | Py_ssize_t current_num_fields; |
| 165 | npy_intp row_size = out_descr->elsize; |
| 166 | PyObject **conv_funcs = NULL; |
| 167 | |
| 168 | bool needs_init = PyDataType_FLAGCHK(out_descr, NPY_NEEDS_INIT); |
| 169 | |
| 170 | int ndim = homogeneous ? 2 : 1; |
| 171 | npy_intp result_shape[2] = {0, 1}; |
| 172 | |
| 173 | bool data_array_allocated = data_array == NULL; |
| 174 | /* Make sure we own `data_array` for the purpose of error handling */ |
| 175 | Py_XINCREF(data_array); |
| 176 | size_t rows_per_block = 1; /* will be increased depending on row size */ |
| 177 | npy_intp data_allocated_rows = 0; |
| 178 | |
| 179 | /* We give a warning if max_rows is used and an empty line is encountered */ |
| 180 | bool give_empty_row_warning = max_rows >= 0; |
| 181 | |
| 182 | int ts_result = 0; |
| 183 | tokenizer_state ts; |
| 184 | if (npy_tokenizer_init(&ts, pconfig) < 0) { |
| 185 | goto error; |
| 186 | } |
| 187 | |
| 188 | /* Set the actual number of fields if it is already known, otherwise -1 */ |
| 189 | Py_ssize_t actual_num_fields = -1; |
| 190 | if (usecols != NULL) { |
| 191 | assert(homogeneous || num_field_types == num_usecols); |
| 192 | actual_num_fields = num_usecols; |
| 193 | } |
| 194 | else if (!homogeneous) { |
| 195 | assert(usecols == NULL || num_field_types == num_usecols); |
| 196 | actual_num_fields = num_field_types; |
| 197 | } |
| 198 | |
| 199 | for (Py_ssize_t i = 0; i < skiplines; i++) { |
| 200 | ts.state = TOKENIZE_GOTO_LINE_END; |
| 201 | ts_result = npy_tokenize(s, &ts, pconfig); |
| 202 | if (ts_result < 0) { |
| 203 | goto error; |
| 204 | } |
| 205 | else if (ts_result != 0) { |
| 206 | /* Fewer lines than skiplines is acceptable */ |
| 207 | break; |
| 208 | } |
| 209 | } |
| 210 | |
| 211 | Py_ssize_t row_count = 0; /* number of rows actually processed */ |
| 212 | while ((max_rows < 0 || row_count < max_rows) && ts_result == 0) { |
no test coverage detected