-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathGlob.cpp
More file actions
135 lines (105 loc) · 2.45 KB
/
Glob.cpp
File metadata and controls
135 lines (105 loc) · 2.45 KB
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
#include "../classes/GlobIterator.h"
#include <Windows.h>
#include <cstring>
#include <string>
#include <iostream>
namespace fs {
class GlobImpl {
HANDLE handle;
public:
DWORD lastError;
WIN32_FIND_DATAW data;
GlobImpl(wchar_t const pathUTF16[]):
lastError(0)
{
handle = FindFirstFileW(pathUTF16,&data);
if( invalid() ) {
lastError = GetLastError();
}
}
~GlobImpl() { FindClose(handle); }
bool invalid() const { return handle == INVALID_HANDLE_VALUE; }
bool noMoreFiles() const { return lastError == ERROR_NO_MORE_FILES; }
bool hasError() const { return invalid() || lastError != 0; }
bool findNext() {
auto res = FindNextFileW(handle,&data);
if( ! res ) {
lastError = GetLastError();
}
return res;
}
};
// File
GlobFile::GlobFile(GlobImpl * impl):
impl(impl)
{}
GlobFile::GlobFile()
{}
GlobFile::~GlobFile()
{}
GlobFile::GlobFile(GlobFile && other):
impl(std::move(other.impl))
{}
GlobFile & GlobFile::operator=(GlobFile && other)
{
impl = std::move(other.impl);
return *this;
}
Filename GlobFile::filename() const
{
return impl->data.cFileName;
}
size_t GlobFile::filesize() const
{
return (impl->data.nFileSizeHigh * (MAXDWORD+1)) + impl->data.nFileSizeLow;
}
bool GlobFile::isDirectory() const
{
return impl->data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
}
bool GlobFile::isSpecialDirectory() const
{
return wcscmp(impl->data.cFileName,L".") == 0 ||
wcscmp(impl->data.cFileName,L"..") == 0;
}
// Iterator
GlobIterator::GlobIterator(Filename const & path):
file(new GlobImpl(path.wstr.c_str()))
{}
GlobFile & GlobIterator::operator*()
{
return file;
}
GlobFile const & GlobIterator::operator*() const
{
return file;
}
GlobFile * GlobIterator::operator->()
{
return &file;
}
GlobFile const * GlobIterator::operator->() const
{
return &file;
}
GlobIterator & GlobIterator::operator++()
{
file.impl->findNext();
return *this;
}
bool GlobIterator::operator==(GlobIterator const & it) const
{
// they are equal only at the sentinel value
return (! file.impl || file.impl->hasError() ) && ! it.file.impl;
}
bool GlobIterator::operator!=(GlobIterator const & it) const
{
return ! operator==(it);
}
Status GlobIterator::getStatus()
{
if( file.impl->invalid() ) return failed;
if( file.impl->noMoreFiles() ) return ignored;
return ok;
}
}