OLD | NEW |
1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #include "bin/directory.h" | 5 #include "bin/directory.h" |
6 | 6 |
7 static void HandleDir(char* dir_name, | 7 // Forward declaration. |
| 8 static bool ListRecursively(const char* dir_name, |
| 9 bool recursive, |
| 10 Dart_Port dir_port, |
| 11 Dart_Port file_port, |
| 12 Dart_Port done_port, |
| 13 Dart_Port error_port); |
| 14 |
| 15 |
| 16 static bool HandleDir(char* dir_name, |
8 char* path, | 17 char* path, |
9 int path_length, | 18 int path_length, |
10 Dart_Port dir_port) { | 19 bool recursive, |
11 if (dir_port != 0 && | 20 Dart_Port dir_port, |
12 strcmp(dir_name, ".") != 0 && | 21 Dart_Port file_port, |
| 22 Dart_Port done_port, |
| 23 Dart_Port error_port) { |
| 24 if (strcmp(dir_name, ".") != 0 && |
13 strcmp(dir_name, "..") != 0) { | 25 strcmp(dir_name, "..") != 0) { |
14 size_t written = snprintf(path + path_length, | 26 size_t written = snprintf(path + path_length, |
15 MAX_PATH - path_length, | 27 MAX_PATH - path_length, |
16 "%s", | 28 "%s", |
17 dir_name); | 29 dir_name); |
18 ASSERT(written == strlen(dir_name)); | 30 ASSERT(written == strlen(dir_name)); |
19 Dart_Handle name = Dart_NewString(path); | 31 if (dir_port != 0) { |
20 Dart_Post(dir_port, name); | 32 Dart_Handle name = Dart_NewString(path); |
| 33 Dart_Post(dir_port, name); |
| 34 } |
| 35 if (recursive) { |
| 36 return ListRecursively(path, |
| 37 recursive, |
| 38 dir_port, |
| 39 file_port, |
| 40 done_port, |
| 41 error_port); |
| 42 } |
21 } | 43 } |
| 44 return true; |
22 } | 45 } |
23 | 46 |
24 | 47 |
25 static void HandleFile(char* file_name, | 48 static void HandleFile(char* file_name, |
26 char* path, | 49 char* path, |
27 int path_length, | 50 int path_length, |
28 Dart_Port file_port) { | 51 Dart_Port file_port) { |
29 if (file_port != 0) { | 52 if (file_port != 0) { |
30 size_t written = snprintf(path + path_length, | 53 size_t written = snprintf(path + path_length, |
31 MAX_PATH - path_length, | 54 MAX_PATH - path_length, |
32 "%s", | 55 "%s", |
33 file_name); | 56 file_name); |
34 ASSERT(written == strlen(file_name)); | 57 ASSERT(written == strlen(file_name)); |
35 Dart_Handle name = Dart_NewString(path); | 58 Dart_Handle name = Dart_NewString(path); |
36 Dart_Post(file_port, name); | 59 Dart_Post(file_port, name); |
37 } | 60 } |
38 } | 61 } |
39 | 62 |
40 | 63 |
41 static void HandleEntry(LPWIN32_FIND_DATA find_file_data, | 64 static bool HandleEntry(LPWIN32_FIND_DATA find_file_data, |
42 char* path, | 65 char* path, |
43 int path_length, | 66 int path_length, |
| 67 bool recursive, |
| 68 Dart_Port dir_port, |
44 Dart_Port file_port, | 69 Dart_Port file_port, |
45 Dart_Port dir_port) { | 70 Dart_Port done_port, |
| 71 Dart_Port error_port) { |
46 DWORD attributes = find_file_data->dwFileAttributes; | 72 DWORD attributes = find_file_data->dwFileAttributes; |
47 if ((attributes & FILE_ATTRIBUTE_DIRECTORY) != 0) { | 73 if ((attributes & FILE_ATTRIBUTE_DIRECTORY) != 0) { |
48 HandleDir(find_file_data->cFileName, path, path_length, dir_port); | 74 return HandleDir(find_file_data->cFileName, |
| 75 path, |
| 76 path_length, |
| 77 recursive, |
| 78 dir_port, |
| 79 file_port, |
| 80 done_port, |
| 81 error_port); |
49 } else { | 82 } else { |
50 HandleFile(find_file_data->cFileName, path, path_length, file_port); | 83 HandleFile(find_file_data->cFileName, path, path_length, file_port); |
| 84 return true; |
51 } | 85 } |
52 } | 86 } |
53 | 87 |
54 | 88 |
55 static void ComputeFullSearchPath(const char* dir_name, | 89 static void ComputeFullSearchPath(const char* dir_name, |
56 char* path, | 90 char* path, |
57 int* path_length) { | 91 int* path_length) { |
58 // GetFullPathName only works in a multi-threaded environment if | 92 // GetFullPathName only works in a multi-threaded environment if |
59 // SetCurrentDirectory is not used. We currently have no plan for | 93 // SetCurrentDirectory is not used. We currently have no plan for |
60 // exposing SetCurrentDirectory. | 94 // exposing SetCurrentDirectory. |
61 int written = | 95 int written = |
62 GetFullPathName(dir_name, MAX_PATH - *path_length, path, NULL); | 96 GetFullPathName(dir_name, MAX_PATH - *path_length, path, NULL); |
63 *path_length += written; | 97 *path_length += written; |
64 written = snprintf(path + *path_length, | 98 written = snprintf(path + *path_length, |
65 MAX_PATH - *path_length, | 99 MAX_PATH - *path_length, |
66 "%s", | 100 "%s", |
67 "\\*"); | 101 "\\*"); |
68 ASSERT(written == 2); | 102 ASSERT(written == 2); |
69 *path_length += written; | 103 *path_length += written; |
70 } | 104 } |
71 | 105 |
72 | 106 static bool ListRecursively(const char* dir_name, |
73 void Directory::List(const char* dir_name, | 107 bool recursive, |
74 bool recursive, | 108 Dart_Port dir_port, |
75 Dart_Port dir_port, | 109 Dart_Port file_port, |
76 Dart_Port file_port, | 110 Dart_Port done_port, |
77 Dart_Port done_port, | 111 Dart_Port error_port) { |
78 Dart_Port error_port) { | 112 char* path = static_cast<char*>(malloc(MAX_PATH)); |
79 // TODO(ager): Handle recursive listing. | |
80 char path[MAX_PATH]; | |
81 int path_length = 0; | 113 int path_length = 0; |
82 ComputeFullSearchPath(dir_name, path, &path_length); | 114 ComputeFullSearchPath(dir_name, path, &path_length); |
83 | 115 |
84 WIN32_FIND_DATA find_file_data; | 116 WIN32_FIND_DATA find_file_data; |
85 HANDLE find_handle = FindFirstFile(path, &find_file_data); | 117 HANDLE find_handle = FindFirstFile(path, &find_file_data); |
86 | 118 |
87 // Adjust the path by removing the '*' used for the search. | 119 // Adjust the path by removing the '*' used for the search. |
88 path_length -= 1; | 120 path_length -= 1; |
89 path[path_length] = '\0'; | 121 path[path_length] = '\0'; |
90 | 122 |
91 if (find_handle == INVALID_HANDLE_VALUE) { | 123 if (find_handle == INVALID_HANDLE_VALUE) { |
92 // TODO(ager): Post on error port. | 124 // TODO(ager): Post on error port. |
93 Dart_Handle value = Dart_NewBoolean(false); | 125 free(path); |
94 Dart_Post(done_port, value); | 126 return false; |
95 return; | |
96 } | 127 } |
97 | 128 |
98 HandleEntry(&find_file_data, path, path_length, file_port, dir_port); | 129 bool completed = HandleEntry(&find_file_data, |
| 130 path, |
| 131 path_length, |
| 132 recursive, |
| 133 dir_port, |
| 134 file_port, |
| 135 done_port, |
| 136 error_port); |
| 137 |
99 while (FindNextFile(find_handle, &find_file_data) != 0) { | 138 while (FindNextFile(find_handle, &find_file_data) != 0) { |
100 HandleEntry(&find_file_data, path, path_length, file_port, dir_port); | 139 completed = completed && HandleEntry(&find_file_data, |
| 140 path, |
| 141 path_length, |
| 142 recursive, |
| 143 dir_port, |
| 144 file_port, |
| 145 done_port, |
| 146 error_port); |
101 } | 147 } |
102 | 148 |
103 bool result = GetLastError() == ERROR_NO_MORE_FILES; | 149 completed = completed && (GetLastError() == ERROR_NO_MORE_FILES); |
104 Dart_Handle value = Dart_NewBoolean(result); | |
105 Dart_Post(done_port, value); | |
106 | 150 |
107 // TODO(ager): Post on error port. | 151 // TODO(ager): Post on error port if close fails. |
108 FindClose(find_handle); | 152 FindClose(find_handle); |
| 153 free(path); |
| 154 |
| 155 return completed; |
109 } | 156 } |
| 157 |
| 158 void Directory::List(const char* dir_name, |
| 159 bool recursive, |
| 160 Dart_Port dir_port, |
| 161 Dart_Port file_port, |
| 162 Dart_Port done_port, |
| 163 Dart_Port error_port) { |
| 164 bool result = ListRecursively(dir_name, |
| 165 recursive, |
| 166 dir_port, |
| 167 file_port, |
| 168 done_port, |
| 169 error_port); |
| 170 if (done_port != 0) { |
| 171 Dart_Handle value = Dart_NewBoolean(result); |
| 172 Dart_Post(done_port, value); |
| 173 } |
| 174 } |
OLD | NEW |