Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
SkOSFile_win.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2013 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
9#if defined(SK_BUILD_FOR_WIN)
10
15#include "src/core/SkOSFile.h"
17
18#include <io.h>
19#include <new>
20#include <stdio.h>
21#include <sys/stat.h>
22
23void sk_fsync(FILE* f) {
24 _commit(sk_fileno(f));
25}
26
27bool sk_exists(const char *path, SkFILE_Flags flags) {
28 int mode = 0; // existence
30 mode |= 4; // read
31 }
33 mode |= 2; // write
34 }
35 return (0 == _access(path, mode));
36}
37
38typedef struct {
39 ULONGLONG fVolume;
40 ULONGLONG fLsbSize;
41 ULONGLONG fMsbSize;
42} SkFILEID;
43
44static bool sk_ino(FILE* f, SkFILEID* id) {
45 int fileno = _fileno((FILE*)f);
46 if (fileno < 0) {
47 return false;
48 }
49
50 HANDLE file = (HANDLE)_get_osfhandle(fileno);
51 if (INVALID_HANDLE_VALUE == file) {
52 return false;
53 }
54
55 //TODO: call GetFileInformationByHandleEx on Vista and later with FileIdInfo.
56 BY_HANDLE_FILE_INFORMATION info;
57 if (0 == GetFileInformationByHandle(file, &info)) {
58 return false;
59 }
60 id->fVolume = info.dwVolumeSerialNumber;
61 id->fLsbSize = info.nFileIndexLow + (((ULONGLONG)info.nFileIndexHigh) << 32);
62 id->fMsbSize = 0;
63
64 return true;
65}
66
67bool sk_fidentical(FILE* a, FILE* b) {
68 SkFILEID aID, bID;
69 return sk_ino(a, &aID) && sk_ino(b, &bID)
70 && aID.fLsbSize == bID.fLsbSize
71 && aID.fMsbSize == bID.fMsbSize
72 && aID.fVolume == bID.fVolume;
73}
74
75class SkAutoNullKernelHandle : SkNoncopyable {
76public:
77 SkAutoNullKernelHandle(const HANDLE handle) : fHandle(handle) { }
78 ~SkAutoNullKernelHandle() { CloseHandle(fHandle); }
79 operator HANDLE() const { return fHandle; }
80 bool isValid() const { return SkToBool(fHandle); }
81private:
82 HANDLE fHandle;
83};
84typedef SkAutoNullKernelHandle SkAutoWinMMap;
85
86void sk_fmunmap(const void* addr, size_t) {
87 UnmapViewOfFile(addr);
88}
89
90void* sk_fdmmap(int fileno, size_t* length) {
91 HANDLE file = (HANDLE)_get_osfhandle(fileno);
92 if (INVALID_HANDLE_VALUE == file) {
93 return nullptr;
94 }
95
96 LARGE_INTEGER fileSize;
97 if (0 == GetFileSizeEx(file, &fileSize)) {
98 //TODO: use SK_TRACEHR(GetLastError(), "Could not get file size.") to report.
99 return nullptr;
100 }
101 if (!SkTFitsIn<size_t>(fileSize.QuadPart)) {
102 return nullptr;
103 }
104
105 SkAutoWinMMap mmap(CreateFileMapping(file, nullptr, PAGE_READONLY, 0, 0, nullptr));
106 if (!mmap.isValid()) {
107 //TODO: use SK_TRACEHR(GetLastError(), "Could not create file mapping.") to report.
108 return nullptr;
109 }
110
111 // Eventually call UnmapViewOfFile
112 void* addr = MapViewOfFile(mmap, FILE_MAP_READ, 0, 0, 0);
113 if (nullptr == addr) {
114 //TODO: use SK_TRACEHR(GetLastError(), "Could not map view of file.") to report.
115 return nullptr;
116 }
117
118 *length = static_cast<size_t>(fileSize.QuadPart);
119 return addr;
120}
121
122int sk_fileno(FILE* f) {
123 return _fileno((FILE*)f);
124}
125
126void* sk_fmmap(FILE* f, size_t* length) {
127 int fileno = sk_fileno(f);
128 if (fileno < 0) {
129 return nullptr;
130 }
131
132 return sk_fdmmap(fileno, length);
133}
134
135size_t sk_qread(FILE* file, void* buffer, size_t count, size_t offset) {
136 int fileno = sk_fileno(file);
137 HANDLE fileHandle = (HANDLE)_get_osfhandle(fileno);
138 if (INVALID_HANDLE_VALUE == file) {
139 return SIZE_MAX;
140 }
141
142 OVERLAPPED overlapped;
143 memset(&overlapped, 0, sizeof(overlapped));
144 ULARGE_INTEGER winOffset;
145 winOffset.QuadPart = offset;
146 overlapped.Offset = winOffset.LowPart;
147 overlapped.OffsetHigh = winOffset.HighPart;
148
149 if (!SkTFitsIn<DWORD>(count)) {
150 count = std::numeric_limits<DWORD>::max();
151 }
152
153 DWORD bytesRead;
154 if (ReadFile(fileHandle, buffer, static_cast<DWORD>(count), &bytesRead, &overlapped)) {
155 return bytesRead;
156 }
157 if (GetLastError() == ERROR_HANDLE_EOF) {
158 return 0;
159 }
160 return SIZE_MAX;
161}
162
163////////////////////////////////////////////////////////////////////////////
164
165struct SkOSFileIterData {
166 SkOSFileIterData() : fHandle(0), fPath16(nullptr) { }
167 HANDLE fHandle;
168 uint16_t* fPath16;
169};
170static_assert(sizeof(SkOSFileIterData) <= SkOSFile::Iter::kStorageSize, "not_enough_space");
171
172static uint16_t* concat_to_16(const char src[], const char suffix[]) {
173 size_t i, len = strlen(src);
174 size_t len2 = 3 + (suffix ? strlen(suffix) : 0);
175 uint16_t* dst = (uint16_t*)sk_malloc_throw((len + len2) * sizeof(uint16_t));
176
177 for (i = 0; i < len; i++) {
178 dst[i] = src[i];
179 }
180
181 if (i > 0 && dst[i-1] != '/') {
182 dst[i++] = '/';
183 }
184 dst[i++] = '*';
185
186 if (suffix) {
187 while (*suffix) {
188 dst[i++] = *suffix++;
189 }
190 }
191 dst[i] = 0;
192 SkASSERT(i + 1 <= len + len2);
193
194 return dst;
195}
196
197SkOSFile::Iter::Iter() { new (fSelf) SkOSFileIterData; }
198
199SkOSFile::Iter::Iter(const char path[], const char suffix[]) {
200 new (fSelf) SkOSFileIterData;
201 this->reset(path, suffix);
202}
203
205 SkOSFileIterData& self = *reinterpret_cast<SkOSFileIterData*>(fSelf);
206 sk_free(self.fPath16);
207 if (self.fHandle) {
208 ::FindClose(self.fHandle);
209 }
210 self.~SkOSFileIterData();
211}
212
213void SkOSFile::Iter::reset(const char path[], const char suffix[]) {
214 SkOSFileIterData& self = *reinterpret_cast<SkOSFileIterData*>(fSelf);
215 if (self.fHandle) {
216 ::FindClose(self.fHandle);
217 self.fHandle = 0;
218 }
219 if (nullptr == path) {
220 path = "";
221 }
222
223 sk_free(self.fPath16);
224 self.fPath16 = concat_to_16(path, suffix);
225}
226
227static bool is_magic_dir(const uint16_t dir[]) {
228 // return true for "." and ".."
229 return dir[0] == '.' && (dir[1] == 0 || (dir[1] == '.' && dir[2] == 0));
230}
231
232static bool get_the_file(HANDLE handle, SkString* name, WIN32_FIND_DATAW* dataPtr, bool getDir) {
233 WIN32_FIND_DATAW data;
234
235 if (nullptr == dataPtr) {
236 if (::FindNextFileW(handle, &data))
237 dataPtr = &data;
238 else
239 return false;
240 }
241
242 for (;;) {
243 if (getDir) {
244 if ((dataPtr->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) &&
245 !is_magic_dir((uint16_t*)dataPtr->cFileName))
246 {
247 break;
248 }
249 } else {
250 if (!(dataPtr->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
251 break;
252 }
253 }
254 if (!::FindNextFileW(handle, dataPtr)) {
255 return false;
256 }
257 }
258 // if we get here, we've found a file/dir
259 if (name) {
260 const uint16_t* utf16name = (const uint16_t*)dataPtr->cFileName;
261 const uint16_t* ptr = utf16name;
262 while (*ptr != 0) { ++ptr; }
263 *name = SkStringFromUTF16(utf16name, ptr - utf16name);
264 }
265 return true;
266}
267
268bool SkOSFile::Iter::next(SkString* name, bool getDir) {
269 SkOSFileIterData& self = *reinterpret_cast<SkOSFileIterData*>(fSelf);
270 WIN32_FIND_DATAW data;
271 WIN32_FIND_DATAW* dataPtr = nullptr;
272
273 if (self.fHandle == 0) { // our first time
274 if (self.fPath16 == nullptr || *self.fPath16 == 0) { // check for no path
275 return false;
276 }
277
278 self.fHandle = ::FindFirstFileW((LPCWSTR)self.fPath16, &data);
279 if (self.fHandle != 0 && self.fHandle != (HANDLE)~0) {
280 dataPtr = &data;
281 }
282 }
283 return self.fHandle != (HANDLE)~0 && get_the_file(self.fHandle, name, dataPtr, getDir);
284}
285
286#endif//defined(SK_BUILD_FOR_WIN)
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
Definition DM.cpp:213
m reset()
int count
#define SkASSERT(cond)
Definition SkAssert.h:116
SK_API void sk_free(void *)
static void * sk_malloc_throw(size_t size)
Definition SkMalloc.h:67
int sk_fileno(FILE *f)
size_t sk_qread(FILE *, void *buffer, size_t count, size_t offset)
void sk_fmunmap(const void *addr, size_t length)
bool sk_exists(const char *path, SkFILE_Flags=(SkFILE_Flags) 0)
SkFILE_Flags
Definition SkOSFile.h:19
@ kRead_SkFILE_Flag
Definition SkOSFile.h:20
@ kWrite_SkFILE_Flag
Definition SkOSFile.h:21
bool sk_fidentical(FILE *a, FILE *b)
void * sk_fdmmap(int fd, size_t *length)
void sk_fsync(FILE *)
void * sk_fmmap(FILE *f, size_t *length)
static bool sk_ino(FILE *a, SkFILEID *id)
SkString SkStringFromUTF16(const uint16_t *src, size_t count)
static constexpr bool SkToBool(const T &x)
Definition SkTo.h:35
SK_SPI void reset(const char path[], const char suffix[]=nullptr)
SK_SPI bool next(SkString *name, bool getDir=false)
static const size_t kStorageSize
Definition SkOSFile.h:95
static bool b
struct MyStruct a[10]
FlutterSemanticsFlag flags
static const uint8_t buffer[]
const char * name
Definition fuchsia.cc:50
size_t length
void ReadFile(uint8_t **data, intptr_t *file_len, void *stream)
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir path
Definition switches.h:57
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot data
Definition switches.h:41
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir Path to the cache directory This is different from the persistent_cache_path in embedder which is used for Skia shader cache icu native lib Path to the library file that exports the ICU data vm service The hostname IP address on which the Dart VM Service should be served If not defaults to or::depending on whether ipv6 is specified vm service A custom Dart VM Service port The default is to pick a randomly available open port disable vm Disable the Dart VM Service The Dart VM Service is never available in release mode disable vm service Disable mDNS Dart VM Service publication Bind to the IPv6 localhost address for the Dart VM Service Ignored if vm service host is set endless trace Enable an endless trace buffer The default is a ring buffer This is useful when very old events need to viewed For during application launch Memory usage will continue to grow indefinitely however Start app with an specific route defined on the framework flutter assets dir
Definition switches.h:145
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive mode
Definition switches.h:228
dst
Definition cp.py:12
Point offset
#define INVALID_HANDLE_VALUE
WINBASEAPI _Check_return_ _Post_equals_last_error_ DWORD WINAPI GetLastError(VOID)
void * HANDLE
struct _OVERLAPPED OVERLAPPED
unsigned __int64 ULONGLONG
unsigned long DWORD