diff options
author | commit-bot@chromium.org <commit-bot@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2013-04-24 20:03:00 +0000 |
---|---|---|
committer | commit-bot@chromium.org <commit-bot@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2013-04-24 20:03:00 +0000 |
commit | 9711e446676e6bf84b3fff916fd1d7537933a110 (patch) | |
tree | 652dc51c7f8ad24dcd205b6663be6ca14519c190 /src/core/SkData.cpp | |
parent | d0419019de2a15a87d390fb0eed929acf9029d75 (diff) |
Move MMap to SkData.
R=reed@google.com
Author: bungeman@google.com
Review URL: https://chromiumcodereview.appspot.com/14336003
git-svn-id: http://skia.googlecode.com/svn/trunk@8848 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'src/core/SkData.cpp')
-rw-r--r-- | src/core/SkData.cpp | 102 |
1 files changed, 88 insertions, 14 deletions
diff --git a/src/core/SkData.cpp b/src/core/SkData.cpp index 8c222002ca..53d5f232ab 100644 --- a/src/core/SkData.cpp +++ b/src/core/SkData.cpp @@ -7,12 +7,16 @@ #include "SkData.h" #include "SkFlattenableBuffers.h" +#include "SkOSFile.h" #if SK_MMAP_SUPPORT #include <unistd.h> #include <sys/mman.h> #include <fcntl.h> #include <errno.h> + #include <unistd.h> +#else + #include <io.h> #endif SK_DEFINE_INST_COUNT(SkData) @@ -94,6 +98,90 @@ static void sk_dataref_releaseproc(const void*, size_t, void* context) { src->unref(); } +#if SK_MMAP_SUPPORT + +static void sk_munmap_releaseproc(const void* addr, size_t length, void*) { + munmap(const_cast<void*>(addr), length); +} + +SkData* SkData::NewFromFILE(SkFILE* f) { + size_t size = sk_fgetsize(f); + if (0 == size) { + return NULL; + } + + int fd = fileno((FILE*)f); + if (fd < 0) { + return NULL; + } + + void* addr = mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0); + if (MAP_FAILED == addr) { + return NULL; + } + + return SkData::NewWithProc(addr, size, sk_munmap_releaseproc, NULL); +} + +#elif SK_BUILD_FOR_WIN32 + +template <typename HandleType, HandleType InvalidValue, BOOL (WINAPI * Close)(HandleType)> +class SkAutoTHandle : SkNoncopyable { +public: + SkAutoTHandle(HandleType handle) : fHandle(handle) { } + ~SkAutoTHandle() { Close(fHandle); } + operator HandleType() { return fHandle; } + bool isValid() { return InvalidValue != fHandle; } +private: + HandleType fHandle; +}; +typedef SkAutoTHandle<HANDLE, INVALID_HANDLE_VALUE, CloseHandle> SkAutoWinFile; +typedef SkAutoTHandle<HANDLE, NULL, CloseHandle> SkAutoWinMMap; + +static void sk_munmap_releaseproc(const void* addr, size_t, void*) { + UnmapViewOfFile(addr); +} + +SkData* SkData::NewFromFILE(SkFILE* f) { + size_t size = sk_fgetsize(f); + if (0 == size) { + return NULL; + } + + int fileno = _fileno((FILE*)f); + if (fileno < 0) { + return NULL; + } + + HANDLE file = (HANDLE)_get_osfhandle(fileno); + if (INVALID_HANDLE_VALUE == file) { + return NULL; + } + + SkAutoWinMMap mmap(CreateFileMapping(file, NULL, PAGE_READONLY, 0, 0, NULL)); + if (!mmap.isValid()) { + //TODO: use SK_TRACEHR(GetLastError(), "Could not create file mapping.") to report. + return NULL; + } + + // Eventually call UnmapViewOfFile + void* addr = MapViewOfFile(mmap, FILE_MAP_READ, 0, 0, 0); + if (NULL == addr) { + //TODO: use SK_TRACEHR(GetLastError(), "Could not map view of file.") to report. + return NULL; + } + + return SkData::NewWithProc(addr, size, sk_munmap_releaseproc, NULL); +} + +#else + +SkData* SkData::NewFromFILE(SkFILE* f) { + return NULL; +} + +#endif + SkData* SkData::NewSubset(const SkData* src, size_t offset, size_t length) { /* We could, if we wanted/need to, just make a deep copy of src's data, @@ -127,20 +215,6 @@ SkData* SkData::NewWithCString(const char cstr[]) { return NewWithCopy(cstr, size); } -#if SK_MMAP_SUPPORT -static void sk_munmap_releaseproc(const void* addr, size_t length, void*) { - munmap(const_cast<void*>(addr), length); -} - -SkData* SkData::NewFromMMap(const void* addr, size_t length) { - return SkNEW_ARGS(SkData, (addr, length, sk_munmap_releaseproc, NULL)); -} -#else -SkData* SkData::NewFromMMap(const void* addr, size_t length) { - return NULL; -} -#endif - /////////////////////////////////////////////////////////////////////////////// void SkData::flatten(SkFlattenableWriteBuffer& buffer) const { |