DCL 3.7.4
Loading...
Searching...
No Matches
Dir.cpp
Go to the documentation of this file.
1#include <dcl/Config.h>
2
3#ifdef __WINNT__
4#include <windows.h> // dcl/Dir.h
5#else
6#include <errno.h>
7#if defined(_AIX) || defined(__sun__)
8#include <alloca.h>
9#endif
10#include <stdlib.h> // alloca
11#include <string.h> // memset
12#include <dcl/_string.h>
13#include <dcl/_stat.h>
14#endif
15
16#include <dcl/Charset.h>
17#include <dcl/Dir.h>
18
19#include "__strumbs.h"
20
21#if __DCL_HAVE_ALLOC_DEBUG
22#undef __DCL_ALLOC_LEVEL
23#define __DCL_ALLOC_LEVEL __DCL_ALLOC_INTERNAL
24#endif
25
26#if __DCL_HAVE_THIS_FILE__
27#undef __THIS_FILE__
28static const char_t __THIS_FILE__[] = __T("dcl/Dir.cpp");
29#endif
30
31__DCL_BEGIN_NAMESPACE
32
33#ifndef INVALID_HANDLE_VALUE
34#define INVALID_HANDLE_VALUE ((DIR*)-1)
35#endif
36
38
39Dir::Entry::Entry()
40{
41 memset(&__dirent, 0, sizeof(__dirent));
42}
43
44String Dir::Entry::name() const
45__DCL_THROWS1(CharsetConvertException*)
46{
47#ifdef __WINNT__
48 return String(__dirent.cFileName);
49#elif defined(__sun__)
50 return __name;
51#else
52 return __mbstostr(__dirent.d_name);
53#endif
54}
55
56#ifdef __WINNT__
57bool Dir::Entry::isDir() const
58{
59 return (__dirent.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0;
60}
61
62bool Dir::Entry::isLink() const
63{
64 return (__dirent.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) != 0;
65}
66#else
67bool Dir::Entry::isDir() const
68{
69#if defined(_AIX) || defined(__sun__)
70 String path = __path + name();
71 struct stat st;
72 if (__lstat(path, &st) != 0) {
73 throw new IOException(path, errno);
74 }
75 return S_ISDIR(st.st_mode);
76#else
77 return __dirent.d_type == DT_DIR;
78#endif
79}
80
81bool Dir::Entry::isLink() const
82{
83#if defined(_AIX) || defined(__sun__)
84 String path = __path + name();
85 struct stat st;
86 if (__lstat(path, &st) != 0) {
87 throw new IOException(path, errno);
88 }
89 return S_ISLNK(st.st_mode);
90#else
91 return __dirent.d_type == DT_LNK;
92#endif
93}
94#endif
95
96String Dir::Entry::toString() const
97__DCL_THROWS1(CharsetConvertException*)
98{
99 StringBuilder r = name();
100 if (isDir() || isLink()) {
101 r += __T(" [");
102 if (isDir())
103 r += __T("directory");
104 if (isLink()) {
105 if (isDir())
106 r += __T(", ");
107 r += __T("symbolic link");
108 }
109 r += __T(']');
110 }
111 return r;
112}
113
114Dir::~Dir()
115{
117 try {
118 close();
119 }
120 catch (Exception* e) {
121 __DCL_TRACE1(__T("Dir::close Error! %ls\n"), e->toString().data());
122 e->destroy();
123 }
124 }
125}
126
127Dir::Dir(const String& _path) __DCL_THROWS1(IOException*)
128{
129 __DCL_ASSERT(!_path.isEmpty());
130
131 // 모든 OS에서 경로 구분자는 '/'를 사용한다.
132 String path = _path.replace(__T('\\'), __T('/'));
133 if (!path.endsWith(__T('/')))
134 path = path + __T("/");
135
136#ifdef __WINNT__
137 WIN32_FIND_DATAW findData;
138 HANDLE h = FindFirstFileW(path + __T('*'), &findData);
139 if (h == INVALID_HANDLE_VALUE)
140 throw new IOException(_path, GetLastError());
141 FindClose(h);
142 if (!(findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
143 throw new IOException(_path, ERROR_DIRECTORY);
144#else
145 struct stat st;
146 if (__stat(path, &st) != 0) {
147 throw new IOException(path, errno);
148 }
149
150 if (!S_ISDIR(st.st_mode)) {
151 throw new IOException(path, ENOTDIR);
152 }
153#endif
154
156 __path = path;
157 rewind();
158}
159
160void Dir::close() __DCL_THROWS1(IOException*)
161{
163 HandleType handle = __handle;
165
166#ifdef __WINNT__
167 if (!FindClose(handle))
168 throw new IOException(__path, GetLastError());
169#else
170 if (closedir(handle))
171 throw new IOException(__path, errno);
172#endif
173}
174
175void Dir::rewind() __DCL_THROWS1(IOException*)
176{
177#ifdef __WINNT__
179 close();
180#else
182 rewinddir(__handle);
183 return;
184 }
185
186 STRTOMBS(__path, path)
187 else {
188 throw new IOException(__path, EILSEQ);
189 }
190
191 DIR* handle = opendir(path);
192 if (handle == NULL) {
193 throw new IOException(__path, errno);
194 }
195 __handle = handle;
196#endif
197}
198
199bool Dir::read(Dir::Entry& _entry) __DCL_THROWS1(IOException*)
200{
201#ifdef __WINNT__
203 HANDLE h = FindFirstFileW(__path + __T('*'), &_entry.__dirent);
204 if (h == INVALID_HANDLE_VALUE)
205 throw new IOException(__path, GetLastError());
206 __handle = h;
207 }
208 else {
209 if (!FindNextFileW(__handle, &_entry.__dirent)) {
210 if (GetLastError() == ERROR_NO_MORE_FILES)
211 return false;
212 else
213 throw new IOException(__path, GetLastError());
214 }
215 }
216 return true;
217#else
219 errno = 0;
220 struct dirent* ent = readdir(__handle);
221 if (ent != NULL) {
222 memcpy((void*)&_entry.__dirent, ent, sizeof(_entry.__dirent));
223#if defined(_AIX)
224 _entry.__path = __path;
225#elif defined(__sun__)
226 _entry.__path = __path;
227 _entry.__name = __mbstostr(ent->d_name);
228 _entry.__dirent.d_name[0] = '\0';
229#endif
230 }
231 else if (errno != 0) {
232 throw new IOException(__path, errno);
233 }
234 return ent != NULL; // EOF
235#endif
236}
237
238__DCL_END_NAMESPACE
__DCL_BEGIN_NAMESPACE String __mbstostr(const char *_mbs, size_t _nmbs) __DCL_THROWS1(CharsetConvertException *)
Definition __strumbs.cpp:18
#define STRTOMBS(str, mbs)
Definition __strumbs.h:25
DCLCAPI int __lstat(const String &_path, struct stat *_buf)
Definition _stat.cpp:30
DCLCAPI int __stat(const String &_path, struct stat *_buf)
Definition _stat.cpp:24
#define __THIS_FILE__
Definition _trace.h:14
#define NULL
Definition Config.h:312
wchar_t char_t
Definition Config.h:247
#define __DCL_THROWS1(e)
Definition Config.h:152
#define INVALID_HANDLE_VALUE
Definition Dir.cpp:34
IOException *size_t r
Definition MediaInfo.cpp:82
#define __DCL_TRACE1(fmt, arg1)
Definition Object.h:399
#define __DCL_ASSERT(expr)
Definition Object.h:394
#define IMPLEMENT_CLASSINFO(class_name, base_class_name)
Definition Object.h:245
#define __T(str)
Definition Object.h:60
Definition Dir.h:41
String __path
Definition Dir.h:152
HandleType __handle
Definition Dir.h:151
virtual String toString() const
Definition Exception.cpp:40
virtual void destroy()
Definition Exception.cpp:74