aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/ports
diff options
context:
space:
mode:
authorGravatar bungeman <bungeman@google.com>2015-02-12 07:18:27 -0800
committerGravatar Commit bot <commit-bot@chromium.org>2015-02-12 07:18:27 -0800
commite998b7ff3a398eaa2f359d4af1a1898ea2824938 (patch)
treeac240aab26dd045252557522470d95f437a67e88 /src/ports
parent72942b8eb56f17e9303380d4e8492f66e9330578 (diff)
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
Diffstat (limited to 'src/ports')
-rw-r--r--src/ports/SkOSFile_none.cpp30
-rw-r--r--src/ports/SkOSFile_posix.cpp89
-rw-r--r--src/ports/SkOSFile_win.cpp122
3 files changed, 211 insertions, 30 deletions
diff --git a/src/ports/SkOSFile_none.cpp b/src/ports/SkOSFile_none.cpp
deleted file mode 100644
index 11723c24f3..0000000000
--- 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 b5dc4ac09b..cea688b86f 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 @@ void* sk_fmmap(SkFILE* f, size_t* size) {
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 ded58586b0..a544168c84 100644
--- a/src/ports/SkOSFile_win.cpp
+++ b/src/ports/SkOSFile_win.cpp
@@ -120,3 +120,125 @@ void* sk_fmmap(SkFILE* f, size_t* length) {
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);
+}