plugin  0.1.0
w_dirent.hpp
1 // Copyright (C) 2018-2024 Intel Corporation
2 // SPDX-License-Identifier: Apache-2.0
3 //
4 
5 #pragma once
6 
7 #if defined(_WIN32)
8 
9 #ifndef NOMINMAX
10 # define NOMINMAX
11 #endif
12 
13 #include <WinSock2.h>
14 #include <Windows.h>
15 #include <stdlib.h>
16 
17 #else
18 
19 #include <unistd.h>
20 #include <cstdlib>
21 #include <string.h>
22 
23 #endif
24 
25 #include <string>
26 
27 #include <sys/stat.h>
28 
29 #if defined(WIN32)
30  // Copied from linux libc sys/stat.h:
31  #define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
32  #define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
33 #endif
34 
35 struct dirent {
36  char *d_name;
37 
38  explicit dirent(const wchar_t *wsFilePath) {
39  size_t i;
40  auto slen = wcslen(wsFilePath);
41  d_name = static_cast<char*>(malloc(slen + 1));
42  wcstombs_s(&i, d_name, slen + 1, wsFilePath, slen);
43  }
44 
45  ~dirent() {
46  free(d_name);
47  }
48 };
49 
50 class DIR {
51  WIN32_FIND_DATAA FindFileData;
52  HANDLE hFind;
53  dirent *next;
54 
55  static inline bool endsWith(const std::string &src, const char *with) {
56  int wl = static_cast<int>(strlen(with));
57  int so = static_cast<int>(src.length()) - wl;
58  if (so < 0) return false;
59  return 0 == strncmp(with, &src[so], wl);
60  }
61 
62 public:
63  explicit DIR(const char *dirPath) : next(nullptr) {
64  std::string ws = dirPath;
65  if (endsWith(ws, "\\"))
66  ws += "*";
67  else
68  ws += "\\*";
69  hFind = FindFirstFileA(ws.c_str(), &FindFileData);
70  FindFileData.dwReserved0 = hFind != INVALID_HANDLE_VALUE;
71  }
72 
73  ~DIR() {
74  if (!next) delete next;
75  FindClose(hFind);
76  }
77 
78  bool isValid() const {
79  return (hFind != INVALID_HANDLE_VALUE && FindFileData.dwReserved0);
80  }
81 
82  dirent* nextEnt() {
83  if (next != nullptr) delete next;
84  next = nullptr;
85 
86  if (!FindFileData.dwReserved0) return nullptr;
87 
88  wchar_t wbuf[4096];
89 
90  size_t outSize;
91  mbstowcs_s(&outSize, wbuf, 4094, FindFileData.cFileName, 4094);
92  next = new dirent(wbuf);
93  FindFileData.dwReserved0 = FindNextFileA(hFind, &FindFileData);
94  return next;
95  }
96 };
97 
98 
99 static DIR *opendir(const char* dirPath) {
100  auto dp = new DIR(dirPath);
101  if (!dp->isValid()) {
102  delete dp;
103  return nullptr;
104  }
105  return dp;
106 }
107 
108 static struct dirent *readdir(DIR *dp) {
109  return dp->nextEnt();
110 }
111 
112 static void closedir(DIR *dp) {
113  delete dp;
114 }
Definition: w_dirent.hpp:50
Definition: w_dirent.hpp:35