Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(346)

Side by Side Diff: runtime/bin/directory_win.cc

Issue 12220034: Use a PathBuffer class in dart:io directory lister. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Refactor to use a PathBuffer class Created 7 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, 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 #include <errno.h> 7 #include <errno.h>
8 #include <sys/stat.h> 8 #include <sys/stat.h>
9 9
10 #include "bin/log.h" 10 #include "bin/log.h"
11 11
12 // Forward declaration. 12 class PathBuffer {
13 public:
14 PathBuffer() : length(0) { }
15
16 wchar_t data[MAX_PATH + 1];
17 int length;
18
19 bool Add(const wchar_t* name) {
20 size_t written = _snprintf(data + length,
21 MAX_PATH - length,
22 L"%s",
23 name);
24 data[MAX_PATH] = L'\0';
25 if (written == wcsnlen(name, MAX_PATH + 1)) {
26 length += written;
27 return true;
28 } else {
29 return false;
30 }
31 }
32
33 void Reset(int new_length) {
34 length = new_length;
35 data[length] = L'\0';
36 }
37 };
38
39
40 // Forward declarations.
13 static bool ListRecursively(const wchar_t* dir_name, 41 static bool ListRecursively(const wchar_t* dir_name,
14 bool recursive, 42 bool recursive,
15 DirectoryListing* listing); 43 DirectoryListing* listing);
16 static bool DeleteRecursively(const wchar_t* dir_name); 44 static bool DeleteRecursively(const wchar_t* dir_name);
17 45
18 46
19 static bool HandleDir(wchar_t* dir_name, 47 static bool HandleDir(wchar_t* dir_name,
20 wchar_t* path, 48 PathBuffer* path,
21 int path_length,
22 bool recursive, 49 bool recursive,
23 DirectoryListing* listing) { 50 DirectoryListing* listing) {
24 if (wcscmp(dir_name, L".") != 0 && 51 if (wcscmp(dir_name, L".") == 0) return true;
25 wcscmp(dir_name, L"..") != 0) { 52 if (wcscmp(dir_name, L"..") == 0) return true;
26 size_t written = _snwprintf(path + path_length, 53 if (!path->Add(dir_name)) return false;
27 MAX_PATH - path_length, 54 char* utf8_path = StringUtils::WideToUtf8(path->data);
28 L"%s", 55 bool ok = listing->HandleDirectory(utf8_path);
29 dir_name); 56 free(utf8_path);
30 if (written != wcslen(dir_name)) { 57 if (!ok) return ok;
31 return false; 58 if (recursive) {
32 } 59 return ListRecursively(path->data, recursive, listing);
33 char* utf8_path = StringUtils::WideToUtf8(path);
34 bool ok = listing->HandleDirectory(utf8_path);
35 free(utf8_path);
36 if (!ok) return ok;
37 if (recursive) {
38 return ListRecursively(path, recursive, listing);
39 }
40 } 60 }
41 return true;
42 } 61 }
43 62
44 63
45 static bool HandleFile(wchar_t* file_name, 64 static bool HandleFile(wchar_t* file_name,
46 wchar_t* path, 65 PathBuffer* path,
47 int path_length,
48 DirectoryListing* listing) { 66 DirectoryListing* listing) {
49 size_t written = _snwprintf(path + path_length, 67 if (!path->Add(file_name)) {
50 MAX_PATH - path_length,
51 L"%s",
52 file_name);
53 if (written != wcslen(file_name)) {
54 return false; 68 return false;
55 }; 69 }
56 char* utf8_path = StringUtils::WideToUtf8(path); 70 char* utf8_path = StringUtils::WideToUtf8(path->data);
57 bool ok = listing->HandleFile(utf8_path); 71 bool ok = listing->HandleFile(utf8_path);
58 free(utf8_path); 72 free(utf8_path);
59 return ok; 73 return ok;
60 } 74 }
61 75
62 76
63 static bool HandleEntry(LPWIN32_FIND_DATAW find_file_data, 77 static bool HandleEntry(LPWIN32_FIND_DATAW find_file_data,
64 wchar_t* path, 78 PathBuffer* path,
65 int path_length,
66 bool recursive, 79 bool recursive,
67 DirectoryListing* listing) { 80 DirectoryListing* listing) {
68 DWORD attributes = find_file_data->dwFileAttributes; 81 DWORD attributes = find_file_data->dwFileAttributes;
69 if ((attributes & FILE_ATTRIBUTE_DIRECTORY) != 0) { 82 if ((attributes & FILE_ATTRIBUTE_DIRECTORY) != 0) {
70 return HandleDir(find_file_data->cFileName, 83 return HandleDir(find_file_data->cFileName,
71 path, 84 path,
72 path_length,
73 recursive, 85 recursive,
74 listing); 86 listing);
75 } else { 87 } else {
76 return HandleFile(find_file_data->cFileName, path, path_length, listing); 88 return HandleFile(find_file_data->cFileName, path, listing);
77 } 89 }
78 } 90 }
79 91
80 92
81 // ComputeFullSearchPath must be called with a path array of size at 93 static PathBuffer* ComputeFullSearchPath(const wchar_t* dir_name) {
82 // least MAX_PATH.
83 static bool ComputeFullSearchPath(const wchar_t* dir_name,
84 wchar_t* path,
85 int* path_length) {
86 // GetFullPathName only works in a multi-threaded environment if 94 // GetFullPathName only works in a multi-threaded environment if
87 // SetCurrentDirectory is not used. We currently have no plan for 95 // SetCurrentDirectory is not used. We currently have no plan for
88 // exposing SetCurrentDirectory. 96 // exposing SetCurrentDirectory.
89 size_t written = GetFullPathNameW(dir_name, MAX_PATH, path, NULL); 97 PathBuffer* path = new PathBuffer();
98
99 size_t written = GetFullPathNameW(dir_name, MAX_PATH + 1, path->data, NULL);
90 // GetFullPathName only accepts input strings of size less than 100 // GetFullPathName only accepts input strings of size less than
91 // MAX_PATH and returns 0 to indicate failure for paths longer than 101 // MAX_PATH and returns 0 to indicate failure for paths longer than
92 // that. Therefore the path buffer is always big enough. 102 // that. Therefore the path buffer is always big enough.
93 if (written == 0 || written > MAX_PATH) { 103 if (written == 0 || written > MAX_PATH) {
94 return false; 104 delete path;
105 return NULL;
95 } 106 }
96 *path_length = written; 107 path->length = written;
97 written = _snwprintf(path + *path_length, 108 if (path->Add(L"\\*")) {
98 MAX_PATH - *path_length, 109 return path;
99 L"%s", 110 } else {
100 L"\\*"); 111 delete path;
101 if (written != 2) { 112 return NULL;
102 return false;
103 } 113 }
104 *path_length += written;
105 return true;
106 } 114 }
107 115
108 static void PostError(DirectoryListing* listing, 116 static void PostError(DirectoryListing* listing,
109 const wchar_t* dir_name) { 117 const wchar_t* dir_name) {
110 const char* utf8_path = StringUtils::WideToUtf8(dir_name); 118 const char* utf8_path = StringUtils::WideToUtf8(dir_name);
111 listing->HandleError(utf8_path); 119 listing->HandleError(utf8_path);
112 free(const_cast<char*>(utf8_path)); 120 free(const_cast<char*>(utf8_path));
113 } 121 }
114 122
115 123
116 static bool ListRecursively(const wchar_t* dir_name, 124 static bool ListRecursively(const wchar_t* dir_name,
117 bool recursive, 125 bool recursive,
118 DirectoryListing* listing) { 126 DirectoryListing* listing) {
119 // Compute full path for the directory currently being listed. The 127 // Compute full path for the directory currently being listed. The
120 // path buffer will be used to construct the current path in the 128 // path buffer will be used to construct the current path in the
121 // recursive traversal. path_length does not always equal 129 // recursive traversal. path_length does not always equal
122 // strlen(path) but indicates the current prefix of path that is the 130 // strlen(path) but indicates the current prefix of path that is the
123 // path of the current directory in the traversal. 131 // path of the current directory in the traversal.
124 wchar_t* path = static_cast<wchar_t*>(malloc(MAX_PATH * sizeof(wchar_t))); 132 PathBuffer* path = ComputeFullSearchPath(dir_name, path, &path_length);
125 int path_length = 0; 133 if (path == NULL) {
126 bool valid = ComputeFullSearchPath(dir_name, path, &path_length);
127 if (!valid) {
128 PostError(listing, dir_name); 134 PostError(listing, dir_name);
129 free(path); 135 delete path;
130 return false; 136 return false;
131 } 137 }
132 138
133 WIN32_FIND_DATAW find_file_data; 139 WIN32_FIND_DATAW find_file_data;
134 HANDLE find_handle = FindFirstFileW(path, &find_file_data); 140 HANDLE find_handle = FindFirstFileW(path, &find_file_data);
135 141
136 // Adjust the path by removing the '*' used for the search. 142 // Adjust the path by removing the '*' used for the search.
137 path_length -= 1; 143 path->Reset(path->length - 1);
138 path[path_length] = '\0';
139 144
140 if (find_handle == INVALID_HANDLE_VALUE) { 145 if (find_handle == INVALID_HANDLE_VALUE) {
141 PostError(listing, path); 146 PostError(listing, path);
142 free(path); 147 delete path;
143 return false; 148 return false;
144 } 149 }
145 150
151 int path_length = path->length;
146 bool success = HandleEntry(&find_file_data, 152 bool success = HandleEntry(&find_file_data,
147 path, 153 path,
148 path_length,
149 recursive, 154 recursive,
150 listing); 155 listing);
151 156
152 while ((FindNextFileW(find_handle, &find_file_data) != 0)) { 157 while ((FindNextFileW(find_handle, &find_file_data) != 0)) {
158 path->Reset(path_length); // HandleEntry adds the entry name to path.
153 success = HandleEntry(&find_file_data, 159 success = HandleEntry(&find_file_data,
154 path, 160 path,
155 path_length,
156 recursive, 161 recursive,
157 listing) && success; 162 listing) && success;
158 } 163 }
159 164
160 if (GetLastError() != ERROR_NO_MORE_FILES) { 165 if (GetLastError() != ERROR_NO_MORE_FILES) {
161 success = false; 166 success = false;
162 PostError(listing, dir_name); 167 PostError(listing, dir_name);
163 } 168 }
164 169
165 if (FindClose(find_handle) == 0) { 170 if (FindClose(find_handle) == 0) {
166 success = false; 171 success = false;
167 PostError(listing, dir_name); 172 PostError(listing, dir_name);
168 } 173 }
169 free(path); 174 delete path;
170 175
171 return success; 176 return success;
172 } 177 }
173 178
174 179 // TODO(whesse): Finish adding PathBuffer, starting here.
175 static bool DeleteFile(wchar_t* file_name, 180 static bool DeleteFile(wchar_t* file_name,
176 wchar_t* path, 181 wchar_t* path,
177 int path_length) { 182 int path_length) {
178 size_t written = _snwprintf(path + path_length, 183 size_t written = _snwprintf(path + path_length,
179 MAX_PATH - path_length, 184 MAX_PATH - path_length,
180 L"%s", 185 L"%s",
181 file_name); 186 file_name);
182 if (written != wcslen(file_name)) { 187 if (written != wcslen(file_name)) {
183 return false; 188 return false;
184 } 189 }
(...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after
438 bool success = DeleteRecursively(system_new_path); 443 bool success = DeleteRecursively(system_new_path);
439 if (!success) return false; 444 if (!success) return false;
440 } 445 }
441 DWORD flags = MOVEFILE_WRITE_THROUGH; 446 DWORD flags = MOVEFILE_WRITE_THROUGH;
442 int move_status = 447 int move_status =
443 MoveFileExW(system_path, system_new_path, flags); 448 MoveFileExW(system_path, system_new_path, flags);
444 free(const_cast<wchar_t*>(system_path)); 449 free(const_cast<wchar_t*>(system_path));
445 free(const_cast<wchar_t*>(system_new_path)); 450 free(const_cast<wchar_t*>(system_new_path));
446 return (move_status != 0); 451 return (move_status != 0);
447 } 452 }
OLDNEW
« runtime/bin/directory_linux.cc ('K') | « runtime/bin/directory_macos.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698