Move SkOSFile::Iter impls into ports.
This was one large ifdef in SkOSFile.cpp in utils.
This moves the code to existing ports files.
Review URL: https://codereview.chromium.org/920593002
diff --git a/include/core/SkOSFile.h b/include/core/SkOSFile.h
index 69a74df..3ee3aa4 100644
--- a/include/core/SkOSFile.h
+++ b/include/core/SkOSFile.h
@@ -14,12 +14,6 @@
#include "SkString.h"
-#if defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_UNIX) || defined(SK_BUILD_FOR_ANDROID) || defined(SK_BUILD_FOR_IOS)
- #include <dirent.h>
-#endif
-
-#include <stddef.h> // ptrdiff_t
-
struct SkFILE;
enum SkFILE_Flags {
@@ -109,14 +103,9 @@
*/
bool next(SkString* name, bool getDir = false);
+ static const size_t kStorageSize = 40;
private:
-#ifdef SK_BUILD_FOR_WIN
- HANDLE fHandle;
- uint16_t* fPath16;
-#elif defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_UNIX) || defined(SK_BUILD_FOR_ANDROID) || defined(SK_BUILD_FOR_IOS)
- DIR* fDIR;
- SkString fPath, fSuffix;
-#endif
+ SkAlignedSStorage<kStorageSize> fSelf;
};
};
@@ -154,7 +143,6 @@
* final slash, or the full name if ending in a slash.
*/
static SkString Dirname(const char* fullPath);
-
};
#endif
diff --git a/src/ports/SkOSFile_none.cpp b/src/ports/SkOSFile_none.cpp
deleted file mode 100644
index 11723c2..0000000
--- a/src/ports/SkOSFile_none.cpp
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * 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"
-
-bool sk_exists(const char *path, SkFILE_Flags flags) {
- return false;
-}
-
-bool sk_fidentical(SkFILE* a, SkFILE* b) {
- return false;
-}
-
-int sk_fileno(SkFILE* f) {
- return -1;
-}
-
-void sk_fmunmap(const void* addr, size_t length) { }
-
-void* sk_fdmmap(int fd, size_t* size) {
- return NULL;
-}
-
-void* sk_fmmap(SkFILE* f, size_t* size) {
- return NULL;
-}
diff --git a/src/ports/SkOSFile_posix.cpp b/src/ports/SkOSFile_posix.cpp
index b5dc4ac..cea688b 100644
--- a/src/ports/SkOSFile_posix.cpp
+++ b/src/ports/SkOSFile_posix.cpp
@@ -8,7 +8,9 @@
#include "SkOSFile.h"
#include "SkTFitsIn.h"
+#include "SkTypes.h"
+#include <dirent.h>
#include <stdio.h>
#include <sys/mman.h>
#include <sys/stat.h>
@@ -90,3 +92,90 @@
return sk_fdmmap(fd, size);
}
+
+////////////////////////////////////////////////////////////////////////////
+
+struct SkOSFileIterData {
+ SkOSFileIterData() : fDIR(0) { }
+ DIR* fDIR;
+ SkString fPath, fSuffix;
+};
+SK_COMPILE_ASSERT(sizeof(SkOSFileIterData) <= SkOSFile::Iter::kStorageSize, not_enough_space);
+
+SkOSFile::Iter::Iter() {
+ SkNEW_PLACEMENT(fSelf.get(), SkOSFileIterData);
+}
+
+SkOSFile::Iter::Iter(const char path[], const char suffix[]) {
+ SkNEW_PLACEMENT(fSelf.get(), SkOSFileIterData);
+ this->reset(path, suffix);
+}
+
+SkOSFile::Iter::~Iter() {
+ SkOSFileIterData& self = *static_cast<SkOSFileIterData*>(fSelf.get());
+ if (self.fDIR) {
+ ::closedir(self.fDIR);
+ }
+ self.~SkOSFileIterData();
+}
+
+void SkOSFile::Iter::reset(const char path[], const char suffix[]) {
+ SkOSFileIterData& self = *static_cast<SkOSFileIterData*>(fSelf.get());
+ if (self.fDIR) {
+ ::closedir(self.fDIR);
+ self.fDIR = 0;
+ }
+
+ self.fPath.set(path);
+ if (path) {
+ self.fDIR = ::opendir(path);
+ self.fSuffix.set(suffix);
+ } else {
+ self.fSuffix.reset();
+ }
+}
+
+// returns true if suffix is empty, or if str ends with suffix
+static bool issuffixfor(const SkString& suffix, const char str[]) {
+ size_t suffixLen = suffix.size();
+ size_t strLen = strlen(str);
+
+ return strLen >= suffixLen &&
+ memcmp(suffix.c_str(), str + strLen - suffixLen, suffixLen) == 0;
+}
+
+bool SkOSFile::Iter::next(SkString* name, bool getDir) {
+ SkOSFileIterData& self = *static_cast<SkOSFileIterData*>(fSelf.get());
+ if (self.fDIR) {
+ dirent* entry;
+
+ while ((entry = ::readdir(self.fDIR)) != NULL) {
+ struct stat s;
+ SkString str(self.fPath);
+
+ if (!str.endsWith("/") && !str.endsWith("\\")) {
+ str.append("/");
+ }
+ str.append(entry->d_name);
+
+ if (0 == stat(str.c_str(), &s)) {
+ if (getDir) {
+ if (s.st_mode & S_IFDIR) {
+ break;
+ }
+ } else {
+ if (!(s.st_mode & S_IFDIR) && issuffixfor(self.fSuffix, entry->d_name)) {
+ break;
+ }
+ }
+ }
+ }
+ if (entry) { // we broke out with a file
+ if (name) {
+ name->set(entry->d_name);
+ }
+ return true;
+ }
+ }
+ return false;
+}
diff --git a/src/ports/SkOSFile_win.cpp b/src/ports/SkOSFile_win.cpp
index ded5858..a544168 100644
--- a/src/ports/SkOSFile_win.cpp
+++ b/src/ports/SkOSFile_win.cpp
@@ -120,3 +120,125 @@
return sk_fdmmap(fileno, length);
}
+
+////////////////////////////////////////////////////////////////////////////
+
+struct SkOSFileIterData {
+ SkOSFileIterData() : fHandle(0), fPath16(NULL) { }
+ HANDLE fHandle;
+ uint16_t* fPath16;
+};
+SK_COMPILE_ASSERT(sizeof(SkOSFileIterData) <= SkOSFile::Iter::kStorageSize, not_enough_space);
+
+static uint16_t* concat_to_16(const char src[], const char suffix[]) {
+ size_t i, len = strlen(src);
+ size_t len2 = 3 + (suffix ? strlen(suffix) : 0);
+ uint16_t* dst = (uint16_t*)sk_malloc_throw((len + len2) * sizeof(uint16_t));
+
+ for (i = 0; i < len; i++) {
+ dst[i] = src[i];
+ }
+
+ if (i > 0 && dst[i-1] != '/') {
+ dst[i++] = '/';
+ }
+ dst[i++] = '*';
+
+ if (suffix) {
+ while (*suffix) {
+ dst[i++] = *suffix++;
+ }
+ }
+ dst[i] = 0;
+ SkASSERT(i + 1 <= len + len2);
+
+ return dst;
+}
+
+SkOSFile::Iter::Iter() {
+ SkNEW_PLACEMENT(fSelf.get(), SkOSFileIterData);
+}
+
+SkOSFile::Iter::Iter(const char path[], const char suffix[]) {
+ SkNEW_PLACEMENT(fSelf.get(), SkOSFileIterData);
+ this->reset(path, suffix);
+}
+
+SkOSFile::Iter::~Iter() {
+ SkOSFileIterData& self = *static_cast<SkOSFileIterData*>(fSelf.get());
+ sk_free(self.fPath16);
+ if (self.fHandle) {
+ ::FindClose(self.fHandle);
+ }
+ self.~SkOSFileIterData();
+}
+
+void SkOSFile::Iter::reset(const char path[], const char suffix[]) {
+ SkOSFileIterData& self = *static_cast<SkOSFileIterData*>(fSelf.get());
+ if (self.fHandle) {
+ ::FindClose(self.fHandle);
+ self.fHandle = 0;
+ }
+ if (NULL == path) {
+ path = "";
+ }
+
+ sk_free(self.fPath16);
+ self.fPath16 = concat_to_16(path, suffix);
+}
+
+static bool is_magic_dir(const uint16_t dir[]) {
+ // return true for "." and ".."
+ return dir[0] == '.' && (dir[1] == 0 || (dir[1] == '.' && dir[2] == 0));
+}
+
+static bool get_the_file(HANDLE handle, SkString* name, WIN32_FIND_DATAW* dataPtr, bool getDir) {
+ WIN32_FIND_DATAW data;
+
+ if (NULL == dataPtr) {
+ if (::FindNextFileW(handle, &data))
+ dataPtr = &data;
+ else
+ return false;
+ }
+
+ for (;;) {
+ if (getDir) {
+ if ((dataPtr->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) &&
+ !is_magic_dir((uint16_t*)dataPtr->cFileName))
+ {
+ break;
+ }
+ } else {
+ if (!(dataPtr->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
+ break;
+ }
+ }
+ if (!::FindNextFileW(handle, dataPtr)) {
+ return false;
+ }
+ }
+ // if we get here, we've found a file/dir
+ if (name) {
+ name->setUTF16((uint16_t*)dataPtr->cFileName);
+ }
+ return true;
+}
+
+bool SkOSFile::Iter::next(SkString* name, bool getDir) {
+ SkOSFileIterData& self = *static_cast<SkOSFileIterData*>(fSelf.get());
+ WIN32_FIND_DATAW data;
+ WIN32_FIND_DATAW* dataPtr = NULL;
+
+ if (self.fHandle == 0) { // our first time
+ if (self.fPath16 == NULL || *self.fPath16 == 0) { // check for no path
+ return false;
+ }
+
+ self.fHandle = ::FindFirstFileW((LPCWSTR)self.fPath16, &data);
+ if (self.fHandle != 0 && self.fHandle != (HANDLE)~0) {
+ dataPtr = &data;
+ }
+ }
+ return self.fHandle != (HANDLE)~0 && get_the_file(self.fHandle, name, dataPtr, getDir);
+}
diff --git a/src/utils/SkOSFile.cpp b/src/utils/SkOSFile.cpp
index 04a4fe9..cb12c2b 100644
--- a/src/utils/SkOSFile.cpp
+++ b/src/utils/SkOSFile.cpp
@@ -42,212 +42,3 @@
}
return SkString(fullPath, end - fullPath);
}
-
-#ifdef SK_BUILD_FOR_WIN
-
-static uint16_t* concat_to_16(const char src[], const char suffix[])
-{
- size_t i, len = strlen(src);
- size_t len2 = 3 + (suffix ? strlen(suffix) : 0);
- uint16_t* dst = (uint16_t*)sk_malloc_throw((len + len2) * sizeof(uint16_t));
-
- for (i = 0; i < len; i++)
- dst[i] = src[i];
-
- if (i > 0 && dst[i-1] != '/')
- dst[i++] = '/';
- dst[i++] = '*';
-
- if (suffix)
- {
- while (*suffix)
- dst[i++] = *suffix++;
- }
- dst[i] = 0;
- SkASSERT(i + 1 <= len + len2);
-
- return dst;
-}
-
-////////////////////////////////////////////////////////////////////////////
-
-SkOSFile::Iter::Iter() : fHandle(0), fPath16(NULL)
-{
-}
-
-SkOSFile::Iter::Iter(const char path[], const char suffix[]) : fHandle(0), fPath16(NULL)
-{
- this->reset(path, suffix);
-}
-
-SkOSFile::Iter::~Iter()
-{
- sk_free(fPath16);
- if (fHandle)
- ::FindClose(fHandle);
-}
-
-void SkOSFile::Iter::reset(const char path[], const char suffix[])
-{
- if (fHandle)
- {
- ::FindClose(fHandle);
- fHandle = 0;
- }
- if (NULL == path)
- path = "";
-
- sk_free(fPath16);
- fPath16 = concat_to_16(path, suffix);
-}
-
-static bool is_magic_dir(const uint16_t dir[])
-{
- // return true for "." and ".."
- return dir[0] == '.' && (dir[1] == 0 || dir[1] == '.' && dir[2] == 0);
-}
-
-static bool get_the_file(HANDLE handle, SkString* name, WIN32_FIND_DATAW* dataPtr, bool getDir)
-{
- WIN32_FIND_DATAW data;
-
- if (NULL == dataPtr)
- {
- if (::FindNextFileW(handle, &data))
- dataPtr = &data;
- else
- return false;
- }
-
- for (;;)
- {
- if (getDir)
- {
- if ((dataPtr->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) && !is_magic_dir((uint16_t*)dataPtr->cFileName))
- break;
- }
- else
- {
- if (!(dataPtr->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
- break;
- }
- if (!::FindNextFileW(handle, dataPtr))
- return false;
- }
- // if we get here, we've found a file/dir
- if (name)
- name->setUTF16((uint16_t*)dataPtr->cFileName);
- return true;
-}
-
-bool SkOSFile::Iter::next(SkString* name, bool getDir)
-{
- WIN32_FIND_DATAW data;
- WIN32_FIND_DATAW* dataPtr = NULL;
-
- if (fHandle == 0) // our first time
- {
- if (fPath16 == NULL || *fPath16 == 0) // check for no path
- return false;
-
- fHandle = ::FindFirstFileW((LPCWSTR)fPath16, &data);
- if (fHandle != 0 && fHandle != (HANDLE)~0)
- dataPtr = &data;
- }
- return fHandle != (HANDLE)~0 && get_the_file(fHandle, name, dataPtr, getDir);
-}
-
-#elif defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_UNIX) || defined(SK_BUILD_FOR_ANDROID) || defined(SK_BUILD_FOR_IOS)
-
-#if 0
-OSStatus FSPathMakeRef (
- const UInt8 * path,
- FSRef * ref,
- Boolean * isDirectory
-);
-#endif
-
-SkOSFile::Iter::Iter() : fDIR(0)
-{
-}
-
-SkOSFile::Iter::Iter(const char path[], const char suffix[]) : fDIR(0)
-{
- this->reset(path, suffix);
-}
-
-SkOSFile::Iter::~Iter()
-{
- if (fDIR)
- ::closedir(fDIR);
-}
-
-void SkOSFile::Iter::reset(const char path[], const char suffix[])
-{
- if (fDIR)
- {
- ::closedir(fDIR);
- fDIR = 0;
- }
-
- fPath.set(path);
- if (path)
- {
- fDIR = ::opendir(path);
- fSuffix.set(suffix);
- }
- else
- fSuffix.reset();
-}
-
-// returns true if suffix is empty, or if str ends with suffix
-static bool issuffixfor(const SkString& suffix, const char str[])
-{
- size_t suffixLen = suffix.size();
- size_t strLen = strlen(str);
-
- return strLen >= suffixLen &&
- memcmp(suffix.c_str(), str + strLen - suffixLen, suffixLen) == 0;
-}
-
-#include <sys/stat.h>
-
-bool SkOSFile::Iter::next(SkString* name, bool getDir)
-{
- if (fDIR)
- {
- dirent* entry;
-
- while ((entry = ::readdir(fDIR)) != NULL)
- {
- struct stat s;
- SkString str(fPath);
-
- if (!str.endsWith("/") && !str.endsWith("\\"))
- str.append("/");
- str.append(entry->d_name);
-
- if (0 == stat(str.c_str(), &s))
- {
- if (getDir)
- {
- if (s.st_mode & S_IFDIR)
- break;
- }
- else
- {
- if (!(s.st_mode & S_IFDIR) && issuffixfor(fSuffix, entry->d_name))
- break;
- }
- }
- }
- if (entry) // we broke out with a file
- {
- if (name)
- name->set(entry->d_name);
- return true;
- }
- }
- return false;
-}
-#endif // if one of:SK_BUILD_FOR_MAC, SK_BUILD_FOR_UNIX, SK_BUILD_FOR_ANDROID,SK_BUILD_FOR_IOS