diff options
author | bungeman@google.com <bungeman@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2013-05-29 13:43:31 +0000 |
---|---|---|
committer | bungeman@google.com <bungeman@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2013-05-29 13:43:31 +0000 |
commit | f209ac2ecbb61b92348872f4642fa7f72103da2c (patch) | |
tree | 713a6dd94a5ab762cc8582f3788313dd0300caaf /ports/SkOSFile_win.cpp | |
parent | aa62052fd968fb037fc17a1f2a3c1be34b4342bb (diff) | |
download | src-f209ac2ecbb61b92348872f4642fa7f72103da2c.tar.gz |
Change SkStream.
https://codereview.chromium.org/15298009/
git-svn-id: http://skia.googlecode.com/svn/trunk/src@9312 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'ports/SkOSFile_win.cpp')
-rw-r--r-- | ports/SkOSFile_win.cpp | 99 |
1 files changed, 99 insertions, 0 deletions
diff --git a/ports/SkOSFile_win.cpp b/ports/SkOSFile_win.cpp new file mode 100644 index 00000000..fdf9ca50 --- /dev/null +++ b/ports/SkOSFile_win.cpp @@ -0,0 +1,99 @@ +/* + * 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 <io.h> +#include <stdio.h> +#include <sys/stat.h> + +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; +} + +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; + +void sk_fmunmap(const void* addr, size_t) { + UnmapViewOfFile(addr); +} + +void* sk_fmmap(SkFILE* f, size_t* length) { + size_t fileSize = sk_fgetsize(f); + if (0 == fileSize) { + 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; + } + + *length = fileSize; + return addr; +} |