Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(51)

Unified Diff: base/files/memory_mapped_file_posix.cc

Issue 394313002: Add support for loading pak files from arbitrary file regions. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Move Region to MemoryMappedFile Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: base/files/memory_mapped_file_posix.cc
diff --git a/base/files/memory_mapped_file_posix.cc b/base/files/memory_mapped_file_posix.cc
index 5d7e0079992d835d32aad565d4836600257cb4b5..ebf38779f039708835242eb19ed7223927a28f40 100644
--- a/base/files/memory_mapped_file_posix.cc
+++ b/base/files/memory_mapped_file_posix.cc
@@ -16,22 +16,63 @@ namespace base {
MemoryMappedFile::MemoryMappedFile() : data_(NULL), length_(0) {
}
-bool MemoryMappedFile::MapFileToMemory() {
+bool MemoryMappedFile::MapFileRegionToMemory(
+ const MemoryMappedFile::Region& region) {
ThreadRestrictions::AssertIOAllowed();
- struct stat file_stat;
- if (fstat(file_.GetPlatformFile(), &file_stat) == -1 ) {
- DPLOG(ERROR) << "fstat " << file_.GetPlatformFile();
- return false;
+ off_t map_start = 0;
+ size_t map_size = 0;
+ int32 data_offset = 0;
+
+ if (region == MemoryMappedFile::Region::kWholeFile) {
+ int64 file_len = file_.GetLength();
+ if (file_len == -1) {
+ DPLOG(ERROR) << "fstat " << file_.GetPlatformFile();
+ return false;
+ }
+ map_size = static_cast<size_t>(file_len);
+ length_ = map_size;
+ } else {
+ // The region can be arbitrarily aligned. mmap, instead, requires both the
+ // start and size to be page-aligned. Hence, we map here the page-aligned
+ // outer region [|aligned_start|, |aligned_start| + |size|] which contains
+ // |region| and then add up the |data_offset| displacement.
+ int64 aligned_start = 0;
+ int64 aligned_size = 0;
+ CalculateVMAlignedBoundaries(region.offset,
+ region.size,
+ &aligned_start,
+ &aligned_size,
+ &data_offset);
+
+ // Ensure that the casts in the mmap call below are sane.
+ if (aligned_start < 0 || aligned_size < 0 ||
+ aligned_start > std::numeric_limits<off_t>::max() ||
+ static_cast<uint64>(aligned_size) >
+ std::numeric_limits<size_t>::max() ||
+ static_cast<uint64>(region.size) > std::numeric_limits<size_t>::max()) {
+ DLOG(ERROR) << "Region bounds are not valid for mmap";
+ return false;
+ }
+
+ map_start = static_cast<off_t>(aligned_start);
+ map_size = static_cast<size_t>(aligned_size);
+ length_ = static_cast<size_t>(region.size);
}
- length_ = file_stat.st_size;
- data_ = static_cast<uint8*>(
- mmap(NULL, length_, PROT_READ, MAP_SHARED, file_.GetPlatformFile(), 0));
- if (data_ == MAP_FAILED)
+ data_ = static_cast<uint8*>(mmap(NULL,
+ map_size,
+ PROT_READ,
+ MAP_SHARED,
+ file_.GetPlatformFile(),
+ map_start));
+ if (data_ == MAP_FAILED) {
DPLOG(ERROR) << "mmap " << file_.GetPlatformFile();
+ return false;
+ }
- return data_ != MAP_FAILED;
+ data_ += data_offset;
+ return true;
}
void MemoryMappedFile::CloseHandles() {

Powered by Google App Engine
This is Rietveld 408576698