| 530 | |
| 531 | |
| 532 | MapContext mapFile(const std::string& filename, bool readOnly, uintmax_t pos, uintmax_t size) |
| 533 | { |
| 534 | MapContext ctx; |
| 535 | |
| 536 | if (!readOnly) |
| 537 | { |
| 538 | ctx.m_error = "readOnly must be true."; |
| 539 | return ctx; |
| 540 | } |
| 541 | |
| 542 | if (size == 0) |
| 543 | { |
| 544 | size = FileUtils::fileSize(filename); |
| 545 | if (size == 0) |
| 546 | { |
| 547 | ctx.m_error = "File doesn't exist or isn't a regular file. Perhaps provide a size?"; |
| 548 | return ctx; |
| 549 | } |
| 550 | } |
| 551 | |
| 552 | #ifndef PDAL_WIN32_STL |
| 553 | ctx.m_fd = ::open(filename.c_str(), readOnly ? O_RDONLY : O_RDWR); |
| 554 | #else |
| 555 | ctx.m_fd = ::_wopen(toNative(filename).data(), readOnly ? O_RDONLY : O_RDWR); |
| 556 | #endif |
| 557 | |
| 558 | if (ctx.m_fd == -1) |
| 559 | { |
| 560 | ctx.m_error = "Mapped file couldn't be opened."; |
| 561 | return ctx; |
| 562 | } |
| 563 | ctx.m_size = size; |
| 564 | |
| 565 | #ifndef _WIN32 |
| 566 | ctx.m_addr = ::mmap(0, size, PROT_READ, MAP_SHARED, ctx.m_fd, (off_t)pos); |
| 567 | if (ctx.m_addr == MAP_FAILED) |
| 568 | { |
| 569 | ctx.m_addr = nullptr; |
| 570 | ctx.m_error = "Couldn't map file"; |
| 571 | } |
| 572 | #else |
| 573 | ctx.m_handle = CreateFileMapping((HANDLE)_get_osfhandle(ctx.m_fd), |
| 574 | NULL, PAGE_READONLY, 0, 0, NULL); |
| 575 | uint32_t low = pos & 0xFFFFFFFF; |
| 576 | uint32_t high = (uint32_t)(pos >> 8); |
| 577 | ctx.m_addr = MapViewOfFile(ctx.m_handle, FILE_MAP_READ, high, low, |
| 578 | ctx.m_size); |
| 579 | if (ctx.m_addr == nullptr) |
| 580 | ctx.m_error = "Couldn't map file"; |
| 581 | #endif |
| 582 | |
| 583 | return ctx; |
| 584 | } |
| 585 | |
| 586 | MapContext unmapFile(MapContext ctx) |
| 587 | { |