diff options
Diffstat (limited to 'src/core/SkStream.cpp')
-rw-r--r-- | src/core/SkStream.cpp | 64 |
1 files changed, 64 insertions, 0 deletions
diff --git a/src/core/SkStream.cpp b/src/core/SkStream.cpp index fb343ea76a..acbcfbc53d 100644 --- a/src/core/SkStream.cpp +++ b/src/core/SkStream.cpp @@ -13,6 +13,14 @@ #include "SkString.h" #include "SkOSFile.h" +#if SK_MMAP_SUPPORT + #include <unistd.h> + #include <sys/mman.h> + #include <fcntl.h> + #include <errno.h> + #include <unistd.h> +#endif + SK_DEFINE_INST_COUNT(SkStream) SK_DEFINE_INST_COUNT(SkWStream) SK_DEFINE_INST_COUNT(SkFILEStream) @@ -789,3 +797,59 @@ bool SkDebugWStream::write(const void* buffer, size_t size) #endif return true; } + +/////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// + +static bool mmap_filename(const char path[], void** addrPtr, size_t* sizePtr) { +#if SK_MMAP_SUPPORT + int fd = open(path, O_RDONLY); + if (fd < 0) { + return false; + } + + off_t offset = lseek(fd, 0, SEEK_END); // find the file size + if (offset == -1) { + close(fd); + return false; + } + (void)lseek(fd, 0, SEEK_SET); // restore file offset to beginning + + // to avoid a 64bit->32bit warning, I explicitly create a size_t size + size_t size = static_cast<size_t>(offset); + + void* addr = mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0); + close(fd); + + if (MAP_FAILED == addr) { + return false; + } + + *addrPtr = addr; + *sizePtr = size; + return true; +#else + return false; +#endif +} + +SkStream* SkStream::NewFromFile(const char path[]) { + void* addr; + size_t size; + if (mmap_filename(path, &addr, &size)) { + SkAutoTUnref<SkData> data(SkData::NewFromMMap(addr, size)); + if (data.get()) { + return SkNEW_ARGS(SkMemoryStream, (data.get())); + } + } + + // If we get here, then our attempt at using mmap failed, so try normal + // file access. + SkFILEStream* stream = SkNEW_ARGS(SkFILEStream, (path)); + if (!stream->isValid()) { + stream->unref(); + stream = NULL; + } + return stream; +} + |