MCPcopy Create free account
hub / github.com/OSGeo/PROJ / read

Method read

src/networkfilemanager.cpp:1349–1474  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

1347// ---------------------------------------------------------------------------
1348
1349size_t NetworkFile::read(void *buffer, size_t sizeBytes) {
1350
1351 if (sizeBytes == 0)
1352 return 0;
1353
1354 auto iterOffset = m_pos;
1355 while (sizeBytes) {
1356 const auto chunkIdxToDownload = iterOffset / DOWNLOAD_CHUNK_SIZE;
1357 const auto offsetToDownload = chunkIdxToDownload * DOWNLOAD_CHUNK_SIZE;
1358 std::vector<unsigned char> region;
1359 auto pChunk = gNetworkChunkCache.get(m_ctx, m_url, chunkIdxToDownload);
1360 if (pChunk != nullptr) {
1361 region = *pChunk;
1362 } else {
1363 if (offsetToDownload == m_lastDownloadedOffset) {
1364 // In case of consecutive reads (of small size), we use a
1365 // heuristic that we will read the file sequentially, so
1366 // we double the requested size to decrease the number of
1367 // client/server roundtrips.
1368 if (m_nBlocksToDownload < 100)
1369 m_nBlocksToDownload *= 2;
1370 } else {
1371 // Random reads. Cancel the above heuristics.
1372 m_nBlocksToDownload = 1;
1373 }
1374
1375 // Ensure that we will request at least the number of blocks
1376 // to satisfy the remaining buffer size to read.
1377 const auto endOffsetToDownload =
1378 ((iterOffset + sizeBytes + DOWNLOAD_CHUNK_SIZE - 1) /
1379 DOWNLOAD_CHUNK_SIZE) *
1380 DOWNLOAD_CHUNK_SIZE;
1381 const auto nMinBlocksToDownload = static_cast<size_t>(
1382 (endOffsetToDownload - offsetToDownload) / DOWNLOAD_CHUNK_SIZE);
1383 if (m_nBlocksToDownload < nMinBlocksToDownload)
1384 m_nBlocksToDownload = nMinBlocksToDownload;
1385
1386 // Avoid reading already cached data.
1387 // Note: this might get evicted if concurrent reads are done, but
1388 // this should not cause bugs. Just missed optimization.
1389 for (size_t i = 1; i < m_nBlocksToDownload; i++) {
1390 if (gNetworkChunkCache.get(m_ctx, m_url,
1391 chunkIdxToDownload + i) != nullptr) {
1392 m_nBlocksToDownload = i;
1393 break;
1394 }
1395 }
1396
1397 if (m_nBlocksToDownload > MAX_CHUNKS)
1398 m_nBlocksToDownload = MAX_CHUNKS;
1399
1400 region.resize(m_nBlocksToDownload * DOWNLOAD_CHUNK_SIZE);
1401 size_t nRead = 0;
1402 std::string errorBuffer;
1403 errorBuffer.resize(1024);
1404 if (!m_handle) {
1405 m_handle = m_ctx->networking.open(
1406 m_ctx, m_url.c_str(), offsetToDownload,

Callers

nothing calls this directly

Calls 8

proj_context_errno_setFunction · 0.85
pj_logFunction · 0.85
sizeMethod · 0.80
clearMemoryCacheMethod · 0.80
getMethod · 0.45
openMethod · 0.45
emptyMethod · 0.45
insertMethod · 0.45

Tested by

no test coverage detected