comparison C++/modules/Directory/Directory.cpp @ 334:0b576ee64d45

* Create brand new hierarchy * Rename DynLib to Dynlib * Remove some warnings
author David Demelier <markand@malikania.fr>
date Sun, 08 Mar 2015 14:26:33 +0100
parents C++/Directory.cpp@24085fae3162
children 83ef77841ff1
comparison
equal deleted inserted replaced
333:412ca7a5e1ea 334:0b576ee64d45
1 /*
2 * Directory.cpp -- open and read directories
3 *
4 * Copyright (c) 2013, 2014 David Demelier <markand@malikania.fr>
5 *
6 * Permission to use, copy, modify, and/or distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18
19 #include <sstream>
20 #include <stdexcept>
21
22 #include "Directory.h"
23
24 #if defined(_WIN32)
25 # include <Windows.h>
26 #else
27 # include <cstring>
28 # include <cerrno>
29
30 # include <sys/types.h>
31 # include <dirent.h>
32 #endif
33
34 #if defined(_WIN32)
35
36 namespace {
37
38 std::string systemError()
39 {
40 LPSTR error = nullptr;
41 std::string errmsg = "Unknown error";
42
43 FormatMessageA(
44 FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
45 NULL,
46 GetLastError(),
47 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
48 (LPSTR)&error, 0, NULL);
49
50 if (error) {
51 errmsg = std::string(error);
52 LocalFree(error);
53 }
54
55 return errmsg;
56 }
57
58 }
59
60 void Directory::systemLoad(const std::string &path, int flags)
61 {
62 std::ostringstream oss;
63 HANDLE handle;
64 WIN32_FIND_DATA fdata;
65
66 oss << path << "\\*";
67 handle = FindFirstFile(oss.str().c_str(), &fdata);
68
69 if (handle == nullptr)
70 throw std::runtime_error(systemError());
71
72 do {
73 Entry entry;
74
75 entry.name = fdata.cFileName;
76 if ((flags & Directory::NotDot) && entry.name == ".")
77 continue;
78 if ((flags & Directory::NotDotDot) && entry.name == "..")
79 continue;
80
81 switch (fdata.dwFileAttributes) {
82 case FILE_ATTRIBUTE_DIRECTORY:
83 entry.type = Dir;
84 break;
85 case FILE_ATTRIBUTE_NORMAL:
86 entry.type = File;
87 break;
88 case FILE_ATTRIBUTE_REPARSE_POINT:
89 entry.type = Link;
90 break;
91 default:
92 break;
93 }
94
95 m_list.push_back(entry);
96 } while (FindNextFile(handle, &fdata) != 0);
97
98 FindClose(handle);
99 }
100
101 #else
102
103 void Directory::systemLoad(const std::string &path, int flags)
104 {
105 DIR *dp;
106 struct dirent *ent;
107
108 if ((dp = opendir(path.c_str())) == nullptr)
109 throw std::runtime_error(strerror(errno));
110
111 while ((ent = readdir(dp)) != nullptr) {
112 Entry entry;
113
114 entry.name = ent->d_name;
115 if ((flags & Directory::NotDot) && entry.name == ".")
116 continue;
117 if ((flags & Directory::NotDotDot) && entry.name == "..")
118 continue;
119
120 switch (ent->d_type) {
121 case DT_DIR:
122 entry.type = Dir;
123 break;
124 case DT_REG:
125 entry.type = File;
126 break;
127 case DT_LNK:
128 entry.type = Link;
129 break;
130 default:
131 break;
132 }
133
134 m_list.push_back(entry);
135 }
136
137 closedir(dp);
138 }
139
140 #endif
141
142 Directory::Entry::Entry()
143 : type(Unknown)
144 {
145 }
146
147 bool operator==(const Directory::Entry &e1, const Directory::Entry &e2)
148 {
149 return e1.name == e2.name && e1.type == e2.type;
150 }
151
152 Directory::Directory()
153 {
154 }
155
156 Directory::Directory(const std::string &path, int flags)
157 {
158 systemLoad(path, flags);
159 }
160
161 Directory::List::iterator Directory::begin()
162 {
163 return m_list.begin();
164 }
165
166 Directory::List::const_iterator Directory::cbegin() const
167 {
168 return m_list.cbegin();
169 }
170
171 Directory::List::iterator Directory::end()
172 {
173 return m_list.end();
174 }
175
176 Directory::List::const_iterator Directory::cend() const
177 {
178 return m_list.cend();
179 }
180
181 int Directory::count() const
182 {
183 return m_list.size();
184 }
185
186 bool operator==(const Directory &d1, const Directory &d2)
187 {
188 return d1.m_list == d2.m_list;
189 }