annotate C++/Directory.cpp @ 198:01294ed877f6

Directory: support of Windows complete
author David Demelier <markand@malikania.fr>
date Sat, 30 Nov 2013 09:41:21 +0100
parents
children 08eb7b00b950
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 *
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
4 * Copyright (c) 2013 David Demelier <markand@malikania.fr>
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.
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
17 */
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
18
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
19 #include <sstream>
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
20
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
21 #include "Directory.h"
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
22
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
23 #if defined(_MSC_VER)
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
24 # include <Windows.h>
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
25 #endif
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
26
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
27 #if defined(_MSC_VER)
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
28
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
29 namespace {
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
30
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
31 std::string systemError()
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
32 {
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
33 LPSTR error = nullptr;
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
34 std::string errmsg = "Unknown error";
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
35
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
36 FormatMessageA(
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
37 FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
38 NULL,
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
39 GetLastError(),
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
40 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
41 (LPSTR)&error, 0, NULL);
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 if (error) {
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
44 errmsg = std::string(error);
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
45 LocalFree(error);
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
46 }
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
47
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
48 return errmsg;
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
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
51 }
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
52
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
53 void Directory::systemLoad(const std::string &path, int flags)
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 std::ostringstream oss;
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
56 HANDLE handle;
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
57 WIN32_FIND_DATA fdata;
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
58
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
59 oss << path << "\\*";
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
60 handle = FindFirstFile(oss.str().c_str(), &fdata);
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 if (handle == nullptr)
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
63 throw std::runtime_error(systemError());
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
64
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
65 do {
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
66 Entry entry;
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
67
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
68 entry.name = fdata.cFileName;
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
69 if ((flags & Directory::NotDot) && entry.name == ".")
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
70 continue;
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
71 if ((flags & Directory::NotDotDot) && entry.name == "..")
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
72 continue;
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
73
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
74 switch (fdata.dwFileAttributes) {
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
75 case FILE_ATTRIBUTE_DIRECTORY:
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
76 entry.type = Dir;
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
77 break;
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
78 case FILE_ATTRIBUTE_NORMAL:
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
79 entry.type = File;
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
80 break;
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
81 case FILE_ATTRIBUTE_REPARSE_POINT:
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
82 entry.type = Link;
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
83 break;
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
84 default:
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
85 break;
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
86 }
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
87
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
88 m_list.push_back(entry);
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
89 } while (FindNextFile(handle, &fdata) != 0);
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
90
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
91 FindClose(handle);
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
92 }
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 #else
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
95
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
96 // UNIX STUFF
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 #endif
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 Directory::Entry::Entry()
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
101 : type(Unknown)
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
102 {
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
103 }
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
104
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
105 Directory::Directory()
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
106 {
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
107 }
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
108
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
109 Directory::Directory(const std::string &path, int flags)
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
110 {
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
111 systemLoad(path, flags);
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
112 }
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
113
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
114 Directory::List::iterator Directory::begin()
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
115 {
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
116 return m_list.begin();
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
117 }
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
118
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
119 Directory::List::const_iterator Directory::cbegin() const
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
120 {
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
121 return m_list.cbegin();
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
122 }
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
123
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
124 Directory::List::iterator Directory::end()
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
125 {
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
126 return m_list.end();
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
127 }
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
128
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
129 Directory::List::const_iterator Directory::cend() const
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
130 {
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
131 return m_list.cend();
01294ed877f6 Directory: support of Windows complete
David Demelier <markand@malikania.fr>
parents:
diff changeset
132 }