| 1240 | |
| 1241 | template <typename SetItemFn> |
| 1242 | static int read_primitive_sequence_indexed(Buffer *buffer, Py_ssize_t size, |
| 1243 | uint8_t type_id, |
| 1244 | SetItemFn set_item) { |
| 1245 | Error error; |
| 1246 | switch (static_cast<TypeId>(type_id)) { |
| 1247 | case TypeId::STRING: |
| 1248 | for (Py_ssize_t i = 0; i < size; ++i) { |
| 1249 | PyObject *item = read_python_string(buffer); |
| 1250 | if (FORY_PREDICT_FALSE(item == nullptr)) { |
| 1251 | return -1; |
| 1252 | } |
| 1253 | set_item(i, item); |
| 1254 | } |
| 1255 | return 0; |
| 1256 | case TypeId::VARINT64: { |
| 1257 | const uint8_t *data = buffer->data(); |
| 1258 | const uint8_t *ptr = data + buffer->reader_index(); |
| 1259 | const uint8_t *end = data + buffer->size(); |
| 1260 | for (Py_ssize_t i = 0; i < size; ++i) { |
| 1261 | if (FORY_PREDICT_FALSE(ptr >= end)) { |
| 1262 | PyErr_SetString(PyExc_BufferError, |
| 1263 | "buffer out of bound while reading varint64"); |
| 1264 | return -1; |
| 1265 | } |
| 1266 | uint64_t raw = 0; |
| 1267 | const uint8_t b0 = *ptr++; |
| 1268 | if ((b0 & 0x80) == 0) { |
| 1269 | raw = b0; |
| 1270 | } else { |
| 1271 | if (FORY_PREDICT_FALSE(ptr >= end)) { |
| 1272 | PyErr_SetString(PyExc_BufferError, |
| 1273 | "buffer out of bound while reading varint64"); |
| 1274 | return -1; |
| 1275 | } |
| 1276 | const uint8_t b1 = *ptr++; |
| 1277 | raw = static_cast<uint64_t>(b0 & 0x7F) | |
| 1278 | (static_cast<uint64_t>(b1 & 0x7F) << 7); |
| 1279 | if (FORY_PREDICT_FALSE((b1 & 0x80) != 0)) { |
| 1280 | const uint32_t offset = static_cast<uint32_t>((ptr - data) - 2); |
| 1281 | uint32_t read_bytes = 0; |
| 1282 | raw = buffer->get_var_uint64(offset, &read_bytes); |
| 1283 | if (FORY_PREDICT_FALSE(read_bytes == 0)) { |
| 1284 | PyErr_SetString(PyExc_BufferError, |
| 1285 | "buffer out of bound while reading varint64"); |
| 1286 | return -1; |
| 1287 | } |
| 1288 | ptr = data + offset + read_bytes; |
| 1289 | } |
| 1290 | } |
| 1291 | const int64_t v = |
| 1292 | static_cast<int64_t>((raw >> 1) ^ -static_cast<int64_t>(raw & 1ULL)); |
| 1293 | PyObject *item = PyLong_FromLongLong(v); |
| 1294 | if (FORY_PREDICT_FALSE(item == nullptr)) { |
| 1295 | return -1; |
| 1296 | } |
| 1297 | set_item(i, item); |
| 1298 | } |
| 1299 | buffer->reader_index(static_cast<uint32_t>(ptr - data)); |
no test coverage detected