diff -r 000000000000 -r 6474c204b198 gfx/skia/trunk/src/ports/SkOSFile_win.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gfx/skia/trunk/src/ports/SkOSFile_win.cpp Wed Dec 31 06:09:35 2014 +0100 @@ -0,0 +1,111 @@ +/* + * Copyright 2013 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "SkOSFile.h" + +#include "SkTFitsIn.h" + +#include +#include +#include + +typedef struct { + ULONGLONG fVolume; + ULONGLONG fLsbSize; + ULONGLONG fMsbSize; +} SkFILEID; + +static bool sk_ino(SkFILE* f, SkFILEID* id) { + int fileno = _fileno((FILE*)f); + if (fileno < 0) { + return false; + } + + HANDLE file = (HANDLE)_get_osfhandle(fileno); + if (INVALID_HANDLE_VALUE == file) { + return false; + } + + //TODO: call GetFileInformationByHandleEx on Vista and later with FileIdInfo. + BY_HANDLE_FILE_INFORMATION info; + if (0 == GetFileInformationByHandle(file, &info)) { + return false; + } + id->fVolume = info.dwVolumeSerialNumber; + id->fLsbSize = info.nFileIndexLow + (((ULONGLONG)info.nFileIndexHigh) << 32); + id->fMsbSize = 0; + + return true; +} + +bool sk_fidentical(SkFILE* a, SkFILE* b) { + SkFILEID aID, bID; + return sk_ino(a, &aID) && sk_ino(b, &bID) + && aID.fLsbSize == bID.fLsbSize + && aID.fMsbSize == bID.fMsbSize + && aID.fVolume == bID.fVolume; +} + +class SkAutoNullKernelHandle : SkNoncopyable { +public: + SkAutoNullKernelHandle(const HANDLE handle) : fHandle(handle) { } + ~SkAutoNullKernelHandle() { CloseHandle(fHandle); } + operator HANDLE() const { return fHandle; } + bool isValid() const { return NULL != fHandle; } +private: + HANDLE fHandle; +}; +typedef SkAutoNullKernelHandle SkAutoWinMMap; + +void sk_fmunmap(const void* addr, size_t) { + UnmapViewOfFile(addr); +} + +void* sk_fdmmap(int fileno, size_t* length) { + HANDLE file = (HANDLE)_get_osfhandle(fileno); + if (INVALID_HANDLE_VALUE == file) { + return NULL; + } + + LARGE_INTEGER fileSize; + if (0 == GetFileSizeEx(file, &fileSize)) { + //TODO: use SK_TRACEHR(GetLastError(), "Could not get file size.") to report. + return NULL; + } + if (!SkTFitsIn(fileSize.QuadPart)) { + 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; + } + + *length = static_cast(fileSize.QuadPart); + return addr; +} + +int sk_fileno(SkFILE* f) { + return _fileno((FILE*)f); +} + +void* sk_fmmap(SkFILE* f, size_t* length) { + int fileno = sk_fileno(f); + if (fileno < 0) { + return NULL; + } + + return sk_fdmmap(fileno, length); +}