annotate C++/modules/Directory/Directory.cpp @ 468:becd06089e8f

Get rid of Flags, update README
author David Demelier <markand@malikania.fr>
date Wed, 04 Nov 2015 21:21:30 +0100
parents d5ec1174b707
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
198
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
1 /*
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
2 * Directory.cpp -- open and read directories
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
3 *
403
d5ec1174b707 Massive cleanup
David Demelier <markand@malikania.fr>
parents: 355
diff changeset
4 * Copyright (c) 2013-2015 David Demelier <markand@malikania.fr>
198
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
5 *
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
6 * Permission to use, copy, modify, and/or distribute this software for any
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
7 * purpose with or without fee is hereby granted, provided that the above
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
8 * copyright notice and this permission notice appear in all copies.
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
9 *
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
199
08eb7b00b950 Directory: support for Linux and BSD complete
David Demelier <markand@malikania.fr>
parents: 198
diff changeset
17 */
08eb7b00b950 Directory: support for Linux and BSD complete
David Demelier <markand@malikania.fr>
parents: 198
diff changeset
18
08eb7b00b950 Directory: support for Linux and BSD complete
David Demelier <markand@malikania.fr>
parents: 198
diff changeset
19 #include <sstream>
248
d157f4747676 Directory: fix _WIN32
David Demelier <markand@malikania.fr>
parents: 204
diff changeset
20 #include <stdexcept>
199
08eb7b00b950 Directory: support for Linux and BSD complete
David Demelier <markand@malikania.fr>
parents: 198
diff changeset
21
08eb7b00b950 Directory: support for Linux and BSD complete
David Demelier <markand@malikania.fr>
parents: 198
diff changeset
22 #include "Directory.h"
08eb7b00b950 Directory: support for Linux and BSD complete
David Demelier <markand@malikania.fr>
parents: 198
diff changeset
23
248
d157f4747676 Directory: fix _WIN32
David Demelier <markand@malikania.fr>
parents: 204
diff changeset
24 #if defined(_WIN32)
199
08eb7b00b950 Directory: support for Linux and BSD complete
David Demelier <markand@malikania.fr>
parents: 198
diff changeset
25 # include <Windows.h>
08eb7b00b950 Directory: support for Linux and BSD complete
David Demelier <markand@malikania.fr>
parents: 198
diff changeset
26 #else
08eb7b00b950 Directory: support for Linux and BSD complete
David Demelier <markand@malikania.fr>
parents: 198
diff changeset
27 # include <cstring>
08eb7b00b950 Directory: support for Linux and BSD complete
David Demelier <markand@malikania.fr>
parents: 198
diff changeset
28 # include <cerrno>
08eb7b00b950 Directory: support for Linux and BSD complete
David Demelier <markand@malikania.fr>
parents: 198
diff changeset
29
08eb7b00b950 Directory: support for Linux and BSD complete
David Demelier <markand@malikania.fr>
parents: 198
diff changeset
30 # include <sys/types.h>
08eb7b00b950 Directory: support for Linux and BSD complete
David Demelier <markand@malikania.fr>
parents: 198
diff changeset
31 # include <dirent.h>
08eb7b00b950 Directory: support for Linux and BSD complete
David Demelier <markand@malikania.fr>
parents: 198
diff changeset
32 #endif
08eb7b00b950 Directory: support for Linux and BSD complete
David Demelier <markand@malikania.fr>
parents: 198
diff changeset
33
248
d157f4747676 Directory: fix _WIN32
David Demelier <markand@malikania.fr>
parents: 204
diff changeset
34 #if defined(_WIN32)
199
08eb7b00b950 Directory: support for Linux and BSD complete
David Demelier <markand@malikania.fr>
parents: 198
diff changeset
35
08eb7b00b950 Directory: support for Linux and BSD complete
David Demelier <markand@malikania.fr>
parents: 198
diff changeset
36 namespace {
08eb7b00b950 Directory: support for Linux and BSD complete
David Demelier <markand@malikania.fr>
parents: 198
diff changeset
37
198
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
38 std::string systemError()
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
39 {
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
40 LPSTR error = nullptr;
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
41 std::string errmsg = "Unknown error";
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
42
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
43 FormatMessageA(
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
44 FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
45 NULL,
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
46 GetLastError(),
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
47 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
48 (LPSTR)&error, 0, NULL);
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
49
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
50 if (error) {
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
51 errmsg = std::string(error);
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
52 LocalFree(error);
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
53 }
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
54
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
55 return errmsg;
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
56 }
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
57
355
9f1e9c69c223 Directory:
David Demelier <markand@malikania.fr>
parents: 343
diff changeset
58 } // !namespace
198
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
59
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
60 void Directory::systemLoad(const std::string &path, int flags)
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
61 {
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
62 std::ostringstream oss;
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
63 HANDLE handle;
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
64 WIN32_FIND_DATA fdata;
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
65
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
66 oss << path << "\\*";
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
67 handle = FindFirstFile(oss.str().c_str(), &fdata);
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
68
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
69 if (handle == nullptr)
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
70 throw std::runtime_error(systemError());
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
71
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
72 do {
341
83ef77841ff1 Directory: dots are not listed by default
David Demelier <markand@malikania.fr>
parents: 334
diff changeset
73 DirectoryEntry entry;
198
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
74
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
75 entry.name = fdata.cFileName;
341
83ef77841ff1 Directory: dots are not listed by default
David Demelier <markand@malikania.fr>
parents: 334
diff changeset
76 if (entry.name == "." && !(flags & Directory::Dot))
198
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
77 continue;
341
83ef77841ff1 Directory: dots are not listed by default
David Demelier <markand@malikania.fr>
parents: 334
diff changeset
78 if (entry.name == ".." && !(flags & Directory::DotDot))
198
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
79 continue;
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
80
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
81 switch (fdata.dwFileAttributes) {
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
82 case FILE_ATTRIBUTE_DIRECTORY:
341
83ef77841ff1 Directory: dots are not listed by default
David Demelier <markand@malikania.fr>
parents: 334
diff changeset
83 entry.type = DirectoryEntry::Dir;
198
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
84 break;
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
85 case FILE_ATTRIBUTE_NORMAL:
341
83ef77841ff1 Directory: dots are not listed by default
David Demelier <markand@malikania.fr>
parents: 334
diff changeset
86 entry.type = DirectoryEntry::File;
198
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
87 break;
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
88 case FILE_ATTRIBUTE_REPARSE_POINT:
341
83ef77841ff1 Directory: dots are not listed by default
David Demelier <markand@malikania.fr>
parents: 334
diff changeset
89 entry.type = DirectoryEntry::Link;
198
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
90 break;
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
91 default:
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
92 break;
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
93 }
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
94
355
9f1e9c69c223 Directory:
David Demelier <markand@malikania.fr>
parents: 343
diff changeset
95 push_back(entry);
198
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
96 } while (FindNextFile(handle, &fdata) != 0);
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
97
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
98 FindClose(handle);
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
99 }
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
100
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
101 #else
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
102
199
08eb7b00b950 Directory: support for Linux and BSD complete
David Demelier <markand@malikania.fr>
parents: 198
diff changeset
103 void Directory::systemLoad(const std::string &path, int flags)
08eb7b00b950 Directory: support for Linux and BSD complete
David Demelier <markand@malikania.fr>
parents: 198
diff changeset
104 {
08eb7b00b950 Directory: support for Linux and BSD complete
David Demelier <markand@malikania.fr>
parents: 198
diff changeset
105 DIR *dp;
08eb7b00b950 Directory: support for Linux and BSD complete
David Demelier <markand@malikania.fr>
parents: 198
diff changeset
106 struct dirent *ent;
08eb7b00b950 Directory: support for Linux and BSD complete
David Demelier <markand@malikania.fr>
parents: 198
diff changeset
107
08eb7b00b950 Directory: support for Linux and BSD complete
David Demelier <markand@malikania.fr>
parents: 198
diff changeset
108 if ((dp = opendir(path.c_str())) == nullptr)
08eb7b00b950 Directory: support for Linux and BSD complete
David Demelier <markand@malikania.fr>
parents: 198
diff changeset
109 throw std::runtime_error(strerror(errno));
08eb7b00b950 Directory: support for Linux and BSD complete
David Demelier <markand@malikania.fr>
parents: 198
diff changeset
110
08eb7b00b950 Directory: support for Linux and BSD complete
David Demelier <markand@malikania.fr>
parents: 198
diff changeset
111 while ((ent = readdir(dp)) != nullptr) {
343
8846b46fc435 Directory: fix for Unix
David Demelier <markand@malikania.fr>
parents: 341
diff changeset
112 DirectoryEntry entry;
199
08eb7b00b950 Directory: support for Linux and BSD complete
David Demelier <markand@malikania.fr>
parents: 198
diff changeset
113
08eb7b00b950 Directory: support for Linux and BSD complete
David Demelier <markand@malikania.fr>
parents: 198
diff changeset
114 entry.name = ent->d_name;
341
83ef77841ff1 Directory: dots are not listed by default
David Demelier <markand@malikania.fr>
parents: 334
diff changeset
115 if (entry.name == "." && !(flags & Directory::Dot))
199
08eb7b00b950 Directory: support for Linux and BSD complete
David Demelier <markand@malikania.fr>
parents: 198
diff changeset
116 continue;
341
83ef77841ff1 Directory: dots are not listed by default
David Demelier <markand@malikania.fr>
parents: 334
diff changeset
117 if (entry.name == ".." && !(flags & Directory::DotDot))
199
08eb7b00b950 Directory: support for Linux and BSD complete
David Demelier <markand@malikania.fr>
parents: 198
diff changeset
118 continue;
08eb7b00b950 Directory: support for Linux and BSD complete
David Demelier <markand@malikania.fr>
parents: 198
diff changeset
119
08eb7b00b950 Directory: support for Linux and BSD complete
David Demelier <markand@malikania.fr>
parents: 198
diff changeset
120 switch (ent->d_type) {
08eb7b00b950 Directory: support for Linux and BSD complete
David Demelier <markand@malikania.fr>
parents: 198
diff changeset
121 case DT_DIR:
341
83ef77841ff1 Directory: dots are not listed by default
David Demelier <markand@malikania.fr>
parents: 334
diff changeset
122 entry.type = DirectoryEntry::Dir;
199
08eb7b00b950 Directory: support for Linux and BSD complete
David Demelier <markand@malikania.fr>
parents: 198
diff changeset
123 break;
08eb7b00b950 Directory: support for Linux and BSD complete
David Demelier <markand@malikania.fr>
parents: 198
diff changeset
124 case DT_REG:
341
83ef77841ff1 Directory: dots are not listed by default
David Demelier <markand@malikania.fr>
parents: 334
diff changeset
125 entry.type = DirectoryEntry::File;
199
08eb7b00b950 Directory: support for Linux and BSD complete
David Demelier <markand@malikania.fr>
parents: 198
diff changeset
126 break;
08eb7b00b950 Directory: support for Linux and BSD complete
David Demelier <markand@malikania.fr>
parents: 198
diff changeset
127 case DT_LNK:
341
83ef77841ff1 Directory: dots are not listed by default
David Demelier <markand@malikania.fr>
parents: 334
diff changeset
128 entry.type = DirectoryEntry::Link;
199
08eb7b00b950 Directory: support for Linux and BSD complete
David Demelier <markand@malikania.fr>
parents: 198
diff changeset
129 break;
08eb7b00b950 Directory: support for Linux and BSD complete
David Demelier <markand@malikania.fr>
parents: 198
diff changeset
130 default:
08eb7b00b950 Directory: support for Linux and BSD complete
David Demelier <markand@malikania.fr>
parents: 198
diff changeset
131 break;
08eb7b00b950 Directory: support for Linux and BSD complete
David Demelier <markand@malikania.fr>
parents: 198
diff changeset
132 }
08eb7b00b950 Directory: support for Linux and BSD complete
David Demelier <markand@malikania.fr>
parents: 198
diff changeset
133
355
9f1e9c69c223 Directory:
David Demelier <markand@malikania.fr>
parents: 343
diff changeset
134 push_back(entry);
199
08eb7b00b950 Directory: support for Linux and BSD complete
David Demelier <markand@malikania.fr>
parents: 198
diff changeset
135 }
08eb7b00b950 Directory: support for Linux and BSD complete
David Demelier <markand@malikania.fr>
parents: 198
diff changeset
136
08eb7b00b950 Directory: support for Linux and BSD complete
David Demelier <markand@malikania.fr>
parents: 198
diff changeset
137 closedir(dp);
08eb7b00b950 Directory: support for Linux and BSD complete
David Demelier <markand@malikania.fr>
parents: 198
diff changeset
138 }
198
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
139
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
140 #endif
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
141
341
83ef77841ff1 Directory: dots are not listed by default
David Demelier <markand@malikania.fr>
parents: 334
diff changeset
142 bool operator==(const DirectoryEntry &e1, const DirectoryEntry &e2)
204
7086e93bc4ea Directory: add count() operator== and STL compat
David Demelier <markand@malikania.fr>
parents: 199
diff changeset
143 {
7086e93bc4ea Directory: add count() operator== and STL compat
David Demelier <markand@malikania.fr>
parents: 199
diff changeset
144 return e1.name == e2.name && e1.type == e2.type;
7086e93bc4ea Directory: add count() operator== and STL compat
David Demelier <markand@malikania.fr>
parents: 199
diff changeset
145 }
7086e93bc4ea Directory: add count() operator== and STL compat
David Demelier <markand@malikania.fr>
parents: 199
diff changeset
146
199
08eb7b00b950 Directory: support for Linux and BSD complete
David Demelier <markand@malikania.fr>
parents: 198
diff changeset
147 Directory::Directory()
08eb7b00b950 Directory: support for Linux and BSD complete
David Demelier <markand@malikania.fr>
parents: 198
diff changeset
148 {
08eb7b00b950 Directory: support for Linux and BSD complete
David Demelier <markand@malikania.fr>
parents: 198
diff changeset
149 }
08eb7b00b950 Directory: support for Linux and BSD complete
David Demelier <markand@malikania.fr>
parents: 198
diff changeset
150
08eb7b00b950 Directory: support for Linux and BSD complete
David Demelier <markand@malikania.fr>
parents: 198
diff changeset
151 Directory::Directory(const std::string &path, int flags)
08eb7b00b950 Directory: support for Linux and BSD complete
David Demelier <markand@malikania.fr>
parents: 198
diff changeset
152 {
08eb7b00b950 Directory: support for Linux and BSD complete
David Demelier <markand@malikania.fr>
parents: 198
diff changeset
153 systemLoad(path, flags);
198
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
154 }
199
08eb7b00b950 Directory: support for Linux and BSD complete
David Demelier <markand@malikania.fr>
parents: 198
diff changeset
155
204
7086e93bc4ea Directory: add count() operator== and STL compat
David Demelier <markand@malikania.fr>
parents: 199
diff changeset
156 int Directory::count() const
7086e93bc4ea Directory: add count() operator== and STL compat
David Demelier <markand@malikania.fr>
parents: 199
diff changeset
157 {
355
9f1e9c69c223 Directory:
David Demelier <markand@malikania.fr>
parents: 343
diff changeset
158 return size();
204
7086e93bc4ea Directory: add count() operator== and STL compat
David Demelier <markand@malikania.fr>
parents: 199
diff changeset
159 }