1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/skia/trunk/src/ports/SkOSFile_win.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,111 @@ 1.4 +/* 1.5 + * Copyright 2013 Google Inc. 1.6 + * 1.7 + * Use of this source code is governed by a BSD-style license that can be 1.8 + * found in the LICENSE file. 1.9 + */ 1.10 + 1.11 +#include "SkOSFile.h" 1.12 + 1.13 +#include "SkTFitsIn.h" 1.14 + 1.15 +#include <io.h> 1.16 +#include <stdio.h> 1.17 +#include <sys/stat.h> 1.18 + 1.19 +typedef struct { 1.20 + ULONGLONG fVolume; 1.21 + ULONGLONG fLsbSize; 1.22 + ULONGLONG fMsbSize; 1.23 +} SkFILEID; 1.24 + 1.25 +static bool sk_ino(SkFILE* f, SkFILEID* id) { 1.26 + int fileno = _fileno((FILE*)f); 1.27 + if (fileno < 0) { 1.28 + return false; 1.29 + } 1.30 + 1.31 + HANDLE file = (HANDLE)_get_osfhandle(fileno); 1.32 + if (INVALID_HANDLE_VALUE == file) { 1.33 + return false; 1.34 + } 1.35 + 1.36 + //TODO: call GetFileInformationByHandleEx on Vista and later with FileIdInfo. 1.37 + BY_HANDLE_FILE_INFORMATION info; 1.38 + if (0 == GetFileInformationByHandle(file, &info)) { 1.39 + return false; 1.40 + } 1.41 + id->fVolume = info.dwVolumeSerialNumber; 1.42 + id->fLsbSize = info.nFileIndexLow + (((ULONGLONG)info.nFileIndexHigh) << 32); 1.43 + id->fMsbSize = 0; 1.44 + 1.45 + return true; 1.46 +} 1.47 + 1.48 +bool sk_fidentical(SkFILE* a, SkFILE* b) { 1.49 + SkFILEID aID, bID; 1.50 + return sk_ino(a, &aID) && sk_ino(b, &bID) 1.51 + && aID.fLsbSize == bID.fLsbSize 1.52 + && aID.fMsbSize == bID.fMsbSize 1.53 + && aID.fVolume == bID.fVolume; 1.54 +} 1.55 + 1.56 +class SkAutoNullKernelHandle : SkNoncopyable { 1.57 +public: 1.58 + SkAutoNullKernelHandle(const HANDLE handle) : fHandle(handle) { } 1.59 + ~SkAutoNullKernelHandle() { CloseHandle(fHandle); } 1.60 + operator HANDLE() const { return fHandle; } 1.61 + bool isValid() const { return NULL != fHandle; } 1.62 +private: 1.63 + HANDLE fHandle; 1.64 +}; 1.65 +typedef SkAutoNullKernelHandle SkAutoWinMMap; 1.66 + 1.67 +void sk_fmunmap(const void* addr, size_t) { 1.68 + UnmapViewOfFile(addr); 1.69 +} 1.70 + 1.71 +void* sk_fdmmap(int fileno, size_t* length) { 1.72 + HANDLE file = (HANDLE)_get_osfhandle(fileno); 1.73 + if (INVALID_HANDLE_VALUE == file) { 1.74 + return NULL; 1.75 + } 1.76 + 1.77 + LARGE_INTEGER fileSize; 1.78 + if (0 == GetFileSizeEx(file, &fileSize)) { 1.79 + //TODO: use SK_TRACEHR(GetLastError(), "Could not get file size.") to report. 1.80 + return NULL; 1.81 + } 1.82 + if (!SkTFitsIn<size_t>(fileSize.QuadPart)) { 1.83 + return NULL; 1.84 + } 1.85 + 1.86 + SkAutoWinMMap mmap(CreateFileMapping(file, NULL, PAGE_READONLY, 0, 0, NULL)); 1.87 + if (!mmap.isValid()) { 1.88 + //TODO: use SK_TRACEHR(GetLastError(), "Could not create file mapping.") to report. 1.89 + return NULL; 1.90 + } 1.91 + 1.92 + // Eventually call UnmapViewOfFile 1.93 + void* addr = MapViewOfFile(mmap, FILE_MAP_READ, 0, 0, 0); 1.94 + if (NULL == addr) { 1.95 + //TODO: use SK_TRACEHR(GetLastError(), "Could not map view of file.") to report. 1.96 + return NULL; 1.97 + } 1.98 + 1.99 + *length = static_cast<size_t>(fileSize.QuadPart); 1.100 + return addr; 1.101 +} 1.102 + 1.103 +int sk_fileno(SkFILE* f) { 1.104 + return _fileno((FILE*)f); 1.105 +} 1.106 + 1.107 +void* sk_fmmap(SkFILE* f, size_t* length) { 1.108 + int fileno = sk_fileno(f); 1.109 + if (fileno < 0) { 1.110 + return NULL; 1.111 + } 1.112 + 1.113 + return sk_fdmmap(fileno, length); 1.114 +}