1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
|
// Copyright (C) 2018-2022 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//
#pragma once
#if defined(_WIN32)
# ifndef WIN32_LEAN_AND_MEAN
# define WIN32_LEAN_AND_MEAN
# define WIN32_LEAN_AND_MEAN_UNDEF
# endif
# ifndef NOMINMAX
# define NOMINMAX
# define NOMINMAX_UNDEF
# endif
# if defined(_M_IX86) && !defined(_X86_) && !defined(_AMD64_)
# define _X86_
# endif
# if defined(_M_X64) && !defined(_X86_) && !defined(_AMD64_)
# define _AMD64_
# endif
# if defined(_M_ARM) && !defined(_ARM_) && !defined(_ARM64_)
# define _ARM_
# endif
# if defined(_M_ARM64) && !defined(_ARM_) && !defined(_ARM64_)
# define _ARM64_
# endif
// clang-format off
#include <string.h>
#include <windef.h>
#include <fileapi.h>
#include <Winbase.h>
#include <sys/stat.h>
// clang-format on
// Copied from linux libc sys/stat.h:
# define S_ISREG(m) (((m)&S_IFMT) == S_IFREG)
# define S_ISDIR(m) (((m)&S_IFMT) == S_IFDIR)
/// @brief structure to store directory names
struct dirent {
char* d_name;
explicit dirent(const wchar_t* wsFilePath) {
size_t i;
auto slen = wcslen(wsFilePath);
d_name = static_cast<char*>(malloc(slen + 1));
wcstombs_s(&i, d_name, slen + 1, wsFilePath, slen);
}
~dirent() {
free(d_name);
}
};
/// @brief class to store directory data (files meta)
class DIR {
WIN32_FIND_DATAA FindFileData;
HANDLE hFind;
dirent* next;
static inline bool endsWith(const std::string& src, const char* with) {
int wl = static_cast<int>(strlen(with));
int so = static_cast<int>(src.length()) - wl;
if (so < 0)
return false;
return 0 == strncmp(with, &src[so], wl);
}
public:
DIR(const DIR& other) = delete;
DIR(DIR&& other) = delete;
DIR& operator=(const DIR& other) = delete;
DIR& operator=(DIR&& other) = delete;
explicit DIR(const char* dirPath) : next(nullptr) {
std::string ws = dirPath;
if (endsWith(ws, "\\"))
ws += "*";
else
ws += "\\*";
hFind = FindFirstFileA(ws.c_str(), &FindFileData);
FindFileData.dwReserved0 = hFind != INVALID_HANDLE_VALUE;
}
~DIR() {
if (!next)
delete next;
next = nullptr;
FindClose(hFind);
}
/**
* @brief Check file handler is valid
* @return status True(success) or False(fail)
*/
bool isValid() const {
return (hFind != INVALID_HANDLE_VALUE && FindFileData.dwReserved0);
}
/**
* @brief Add directory to directory names struct
* @return pointer to directory names struct
*/
dirent* nextEnt() {
if (next != nullptr)
delete next;
next = nullptr;
if (!FindFileData.dwReserved0)
return nullptr;
wchar_t wbuf[4096];
size_t outSize;
mbstowcs_s(&outSize, wbuf, 4094, FindFileData.cFileName, 4094);
next = new dirent(wbuf);
FindFileData.dwReserved0 = FindNextFileA(hFind, &FindFileData);
return next;
}
};
/**
* @brief Create directory data struct element
* @param string directory path
* @return pointer to directory data struct element
*/
static DIR* opendir(const char* dirPath) {
auto dp = new DIR(dirPath);
if (!dp->isValid()) {
delete dp;
return nullptr;
}
return dp;
}
/**
* @brief Walk throw directory data struct
* @param pointer to directory data struct
* @return pointer to directory data struct next element
*/
static struct dirent* readdir(DIR* dp) {
return dp->nextEnt();
}
/**
* @brief Remove directory data struct
* @param pointer to struct directory data
* @return void
*/
static void closedir(DIR* dp) {
delete dp;
}
# ifdef WIN32_LEAN_AND_MEAN_UNDEF
# undef WIN32_LEAN_AND_MEAN
# undef WIN32_LEAN_AND_MEAN_UNDEF
# endif
# ifdef NOMINMAX_UNDEF
# undef NOMINMAX_UNDEF
# undef NOMINMAX
# endif
#else
# include <dirent.h>
# include <sys/types.h>
#endif
|