Split folder operations out of fx_stream.h into fx_folder.h

Then implement in platform-specific .cpp files. Avoid dragging some
additional bytes into the numerous files that use streams and not
folders (and vice versa).

-- add some comments about FX_FILEMODE_ in fx_stream while at it.
-- make FX_FILEMODE_ definitions look more like bitmasks.

Change-Id: I46f660f8d03c2593e6783266dd299e6a1c7515b9
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/82972
Commit-Queue: Tom Sepez <tsepez@chromium.org>
Reviewed-by: Lei Zhang <thestig@chromium.org>
diff --git a/core/fxcrt/BUILD.gn b/core/fxcrt/BUILD.gn
index 58e4c80..07beba6 100644
--- a/core/fxcrt/BUILD.gn
+++ b/core/fxcrt/BUILD.gn
@@ -40,6 +40,7 @@
     "fx_coordinates.h",
     "fx_extension.cpp",
     "fx_extension.h",
+    "fx_folder.h",
     "fx_memory.cpp",
     "fx_memory.h",
     "fx_memory_wrappers.h",
@@ -119,12 +120,14 @@
     sources += [
       "cfx_fileaccess_posix.cpp",
       "cfx_fileaccess_posix.h",
+      "fx_folder_posix.cpp",
     ]
   }
   if (is_win) {
     sources += [
       "cfx_fileaccess_windows.cpp",
       "cfx_fileaccess_windows.h",
+      "fx_folder_windows.cpp",
     ]
   }
   if (pdf_enable_xfa) {
diff --git a/core/fxcrt/fx_folder.h b/core/fxcrt/fx_folder.h
new file mode 100644
index 0000000..921fbcd
--- /dev/null
+++ b/core/fxcrt/fx_folder.h
@@ -0,0 +1,25 @@
+// Copyright 2021 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef CORE_FXCRT_FX_FOLDER_H_
+#define CORE_FXCRT_FX_FOLDER_H_
+
+#include "core/fxcrt/fx_string.h"
+
+struct FX_FolderHandle;
+
+FX_FolderHandle* FX_OpenFolder(const char* path);
+bool FX_GetNextFile(FX_FolderHandle* handle,
+                    ByteString* filename,
+                    bool* bFolder);
+void FX_CloseFolder(FX_FolderHandle* handle);
+
+// Used with std::unique_ptr to automatically call FX_CloseFolder().
+struct FxFolderHandleCloser {
+  inline void operator()(FX_FolderHandle* h) const { FX_CloseFolder(h); }
+};
+
+#endif  // CORE_FXCRT_FX_FOLDER_H_
diff --git a/core/fxcrt/fx_folder_posix.cpp b/core/fxcrt/fx_folder_posix.cpp
new file mode 100644
index 0000000..1e4ef9b
--- /dev/null
+++ b/core/fxcrt/fx_folder_posix.cpp
@@ -0,0 +1,64 @@
+// Copyright 2021 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "core/fxcrt/fx_folder.h"
+
+#include <dirent.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include <memory>
+
+#include "build/build_config.h"
+#include "core/fxcrt/unowned_ptr.h"
+
+#if defined(OS_WIN)
+#error "built on wrong platform"
+#endif
+
+struct FX_FolderHandle {
+  ByteString m_Path;
+  UnownedPtr<DIR> m_Dir;
+};
+
+FX_FolderHandle* FX_OpenFolder(const char* path) {
+  auto handle = std::make_unique<FX_FolderHandle>();
+  DIR* dir = opendir(path);
+  if (!dir)
+    return nullptr;
+
+  handle->m_Path = path;
+  handle->m_Dir = dir;
+  return handle.release();
+}
+
+bool FX_GetNextFile(FX_FolderHandle* handle,
+                    ByteString* filename,
+                    bool* bFolder) {
+  if (!handle)
+    return false;
+
+  struct dirent* de = readdir(handle->m_Dir);
+  if (!de)
+    return false;
+
+  ByteString fullpath = handle->m_Path + "/" + de->d_name;
+  struct stat deStat;
+  if (stat(fullpath.c_str(), &deStat) < 0)
+    return false;
+
+  *filename = de->d_name;
+  *bFolder = S_ISDIR(deStat.st_mode);
+  return true;
+}
+
+void FX_CloseFolder(FX_FolderHandle* handle) {
+  if (!handle)
+    return;
+
+  closedir(handle->m_Dir.Release());
+  delete handle;
+}
diff --git a/core/fxcrt/fx_folder_windows.cpp b/core/fxcrt/fx_folder_windows.cpp
new file mode 100644
index 0000000..d7a4a23
--- /dev/null
+++ b/core/fxcrt/fx_folder_windows.cpp
@@ -0,0 +1,60 @@
+// Copyright 2021 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "core/fxcrt/fx_folder.h"
+
+#include <direct.h>
+
+#include <memory>
+
+#include "build/build_config.h"
+
+#if !defined(OS_WIN)
+#error "built on wrong platform"
+#endif
+
+struct FX_FolderHandle {
+  HANDLE m_Handle;
+  bool m_bReachedEnd;
+  WIN32_FIND_DATAA m_FindData;
+};
+
+FX_FolderHandle* FX_OpenFolder(const char* path) {
+  auto handle = std::make_unique<FX_FolderHandle>();
+  handle->m_Handle =
+      FindFirstFileExA((ByteString(path) + "/*.*").c_str(), FindExInfoStandard,
+                       &handle->m_FindData, FindExSearchNameMatch, nullptr, 0);
+  if (handle->m_Handle == INVALID_HANDLE_VALUE)
+    return nullptr;
+
+  handle->m_bReachedEnd = false;
+  return handle.release();
+}
+
+bool FX_GetNextFile(FX_FolderHandle* handle,
+                    ByteString* filename,
+                    bool* bFolder) {
+  if (!handle)
+    return false;
+
+  if (handle->m_bReachedEnd)
+    return false;
+
+  *filename = handle->m_FindData.cFileName;
+  *bFolder =
+      (handle->m_FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0;
+  if (!FindNextFileA(handle->m_Handle, &handle->m_FindData))
+    handle->m_bReachedEnd = true;
+  return true;
+}
+
+void FX_CloseFolder(FX_FolderHandle* handle) {
+  if (!handle)
+    return;
+
+  FindClose(handle->m_Handle);
+  delete handle;
+}
diff --git a/core/fxcrt/fx_stream.cpp b/core/fxcrt/fx_stream.cpp
index 7eadefd..9a65181 100644
--- a/core/fxcrt/fx_stream.cpp
+++ b/core/fxcrt/fx_stream.cpp
@@ -6,33 +6,10 @@
 
 #include "core/fxcrt/fx_stream.h"
 
-#include <algorithm>
 #include <memory>
 #include <utility>
 
-#include "build/build_config.h"
 #include "core/fxcrt/fileaccess_iface.h"
-#include "core/fxcrt/fx_safe_types.h"
-#include "core/fxcrt/unowned_ptr.h"
-
-#if defined(OS_WIN)
-#include <direct.h>
-
-struct FX_FolderHandle {
-  HANDLE m_Handle;
-  bool m_bReachedEnd;
-  WIN32_FIND_DATAA m_FindData;
-};
-#else
-#include <dirent.h>
-#include <sys/stat.h>
-#include <unistd.h>
-
-struct FX_FolderHandle {
-  ByteString m_Path;
-  UnownedPtr<DIR> m_Dir;
-};
-#endif
 
 namespace {
 
@@ -134,67 +111,3 @@
 bool IFX_SeekableStream::WriteBlock(const void* buffer, size_t size) {
   return WriteBlockAtOffset(buffer, GetSize(), size);
 }
-
-FX_FolderHandle* FX_OpenFolder(const char* path) {
-  auto handle = std::make_unique<FX_FolderHandle>();
-#if defined(OS_WIN)
-  handle->m_Handle =
-      FindFirstFileExA((ByteString(path) + "/*.*").c_str(), FindExInfoStandard,
-                       &handle->m_FindData, FindExSearchNameMatch, nullptr, 0);
-  if (handle->m_Handle == INVALID_HANDLE_VALUE)
-    return nullptr;
-
-  handle->m_bReachedEnd = false;
-#else
-  DIR* dir = opendir(path);
-  if (!dir)
-    return nullptr;
-
-  handle->m_Path = path;
-  handle->m_Dir = dir;
-#endif
-  return handle.release();
-}
-
-bool FX_GetNextFile(FX_FolderHandle* handle,
-                    ByteString* filename,
-                    bool* bFolder) {
-  if (!handle)
-    return false;
-
-#if defined(OS_WIN)
-  if (handle->m_bReachedEnd)
-    return false;
-
-  *filename = handle->m_FindData.cFileName;
-  *bFolder =
-      (handle->m_FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0;
-  if (!FindNextFileA(handle->m_Handle, &handle->m_FindData))
-    handle->m_bReachedEnd = true;
-  return true;
-#else
-  struct dirent* de = readdir(handle->m_Dir);
-  if (!de)
-    return false;
-  ByteString fullpath = handle->m_Path + "/" + de->d_name;
-  struct stat deStat;
-  if (stat(fullpath.c_str(), &deStat) < 0)
-    return false;
-
-  *filename = de->d_name;
-  *bFolder = S_ISDIR(deStat.st_mode);
-  return true;
-#endif
-}
-
-void FX_CloseFolder(FX_FolderHandle* handle) {
-  if (!handle)
-    return;
-
-#if defined(OS_WIN)
-  FindClose(handle->m_Handle);
-#else
-  closedir(handle->m_Dir.Release());
-#endif
-  delete handle;
-}
diff --git a/core/fxcrt/fx_stream.h b/core/fxcrt/fx_stream.h
index 1e947b8..3e62890 100644
--- a/core/fxcrt/fx_stream.h
+++ b/core/fxcrt/fx_stream.h
@@ -13,23 +13,9 @@
 #include "core/fxcrt/fx_string.h"
 #include "core/fxcrt/fx_types.h"
 #include "core/fxcrt/retain_ptr.h"
-#include "third_party/base/compiler_specific.h"
 
-struct FX_FolderHandle;
-
-FX_FolderHandle* FX_OpenFolder(const char* path);
-bool FX_GetNextFile(FX_FolderHandle* handle,
-                    ByteString* filename,
-                    bool* bFolder);
-void FX_CloseFolder(FX_FolderHandle* handle);
-
-// Used with std::unique_ptr to automatically call FX_CloseFolder().
-struct FxFolderHandleCloser {
-  inline void operator()(FX_FolderHandle* h) const { FX_CloseFolder(h); }
-};
-
-#define FX_FILEMODE_ReadOnly 1
-#define FX_FILEMODE_Truncate 2
+constexpr uint32_t FX_FILEMODE_ReadOnly = 1 << 0;
+constexpr uint32_t FX_FILEMODE_Truncate = 1 << 1;
 
 class IFX_WriteStream {
  public:
@@ -87,9 +73,11 @@
 class IFX_SeekableStream : public IFX_SeekableReadStream,
                            public IFX_SeekableWriteStream {
  public:
+  // dwModes is a mask of FX_FILEMODE_* from above.
   static RetainPtr<IFX_SeekableStream> CreateFromFilename(const char* filename,
                                                           uint32_t dwModes);
 
+  // dwModes is a mask of FX_FILEMODE_* from above.
   static RetainPtr<IFX_SeekableStream> CreateFromFilename(
       const wchar_t* filename,
       uint32_t dwModes);
diff --git a/core/fxge/android/cfpf_skiafontmgr.cpp b/core/fxge/android/cfpf_skiafontmgr.cpp
index a9c0414..d6f593b 100644
--- a/core/fxge/android/cfpf_skiafontmgr.cpp
+++ b/core/fxge/android/cfpf_skiafontmgr.cpp
@@ -11,7 +11,7 @@
 
 #include "core/fxcrt/fx_codepage.h"
 #include "core/fxcrt/fx_extension.h"
-#include "core/fxcrt/fx_stream.h"
+#include "core/fxcrt/fx_folder.h"
 #include "core/fxcrt/fx_system.h"
 #include "core/fxge/android/cfpf_skiafont.h"
 #include "core/fxge/android/cfpf_skiapathfont.h"
diff --git a/core/fxge/cfx_folderfontinfo.cpp b/core/fxge/cfx_folderfontinfo.cpp
index 657fa1c..a676534 100644
--- a/core/fxge/cfx_folderfontinfo.cpp
+++ b/core/fxge/cfx_folderfontinfo.cpp
@@ -12,9 +12,9 @@
 #include "build/build_config.h"
 #include "core/fxcrt/fx_codepage.h"
 #include "core/fxcrt/fx_extension.h"
+#include "core/fxcrt/fx_folder.h"
 #include "core/fxcrt/fx_memory_wrappers.h"
 #include "core/fxcrt/fx_safe_types.h"
-#include "core/fxcrt/fx_stream.h"
 #include "core/fxge/cfx_fontmapper.h"
 #include "core/fxge/fx_font.h"
 #include "third_party/base/containers/contains.h"