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

Side by Side Diff: chrome/browser/sync/util/path_helpers.cc

Issue 194065: Initial commit of sync engine code to browser/sync.... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Fixes to gtest include path, reverted syncapi. Created 11 years, 3 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
Property Changes:
Added: svn:eol-style
+ LF
OLDNEW
(Empty)
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/browser/sync/util/path_helpers.h"
6
7 #include <Shlwapi.h>
8 #include <stdlib.h>
9
10 #include "base/logging.h"
11 #include "base/port.h"
12 #include "chrome/browser/sync/syncable/syncable.h"
13
14 #ifndef OS_WINDOWS
15 #error Compile this file on Windows only.
16 #endif
17
18 using std::string;
19
20 #if OS_WINDOWS
21 const char PATH_SEPARATOR = '\\';
22 #else
23 const char PATH_SEPARATOR = '/';
24 #endif // OS_WINDOWS
25
26
27 static PathString RemoveTrailingSlashes16(PathString str) {
28 while ((str.length() > 0) && (str.at(str.length() - 1) == kPathSeparator[0]))
29 str.resize(str.length() - 1);
30 return str;
31 }
32
33 static string RemoveTrailingSlashes(string str) {
34 while ((str.length() > 0) && (str.at(str.length() - 1) == PATH_SEPARATOR))
35 str.resize(str.length() - 1);
36 return str;
37 }
38
39 PathString LastPathSegment(const PathString& path) {
40 return RemoveTrailingSlashes16(PathFindFileNameW(path.c_str()));
41 }
42
43 string LastPathSegment(const string& path) {
44 return RemoveTrailingSlashes(PathFindFileNameA(path.c_str()));
45 }
46
47 PathString GetFullPath(const PathString& path) {
48 PathChar buffer[MAX_PATH];
49 PathChar* file_part;
50 DWORD const size = GetFullPathName(path.c_str(), ARRAYSIZE(buffer), buffer,
51 &file_part);
52 return PathString(buffer, size);
53 }
54
55 PathString AppendSlash(const PathString& path) {
56 PathString result(path);
57 if (!result.empty()) {
58 if (*result.rbegin() == '/')
59 *result.rbegin() = '\\';
60 else if (*result.rbegin() != '\\')
61 result.push_back('\\');
62 }
63 return result;
64 }
65
66 PathString ExpandTilde(const PathString& path) {
67 // Do nothing on windows.
68 return path;
69 }
70
71 // Returns a string with length or fewer elements, careful to
72 // not truncate a string mid-surrogate pair.
73 PathString TruncatePathString(const PathString& original, int length) {
74 if (original.size() <= length)
75 return original;
76 if (length <= 0)
77 return original;
78 PathString ret(original.begin(), original.begin() + length);
79 COMPILE_ASSERT(sizeof(PathChar) == sizeof(uint16), PathStringNotUTF16);
80 PathChar last_char = *ret.rbegin();
81
82 // Values taken from
83 // http://en.wikipedia.org/w/index.php?title=UTF-16/UCS-2&oldid=248072840
84 if (last_char >= 0xD800 && last_char <= 0xDBFF)
85 ret.resize(ret.size() - 1);
86 return ret;
87 }
88
89 namespace {
90 const PathString kWindowsIllegalBaseFilenames[] = {
91 L"CON", L"PRN", L"AUX", L"NUL", L"COM1", L"COM2",
92 L"COM3", L"COM4", L"COM5", L"COM6", L"COM7",
93 L"COM8", L"COM9", L"LPT1", L"LPT2", L"LPT3",
94 L"LPT4", L"LPT5", L"LPT6", L"LPT7", L"LPT8",
95 L"LPT9" };
96 }
97
98 // See: http://msdn.microsoft.com/library/default.asp?url=/library/
99 // en-us/fileio/fs/naming_a_file.asp
100 // note that * and ? are not listed on the page as illegal characters,
101 // but they are.
102 PathString MakePathComponentOSLegal(const PathString& component) {
103 CHECK(!component.empty());
104 PathString mutable_component = component;
105
106 // Remove illegal characters.
107 for (PathString::iterator i = mutable_component.begin();
108 i != mutable_component.end();) {
109 if ((PathString::npos != PathString(L"<>:\"/\\|*?").find(*i)) ||
110 ((static_cast<unsigned short>(*i) >= 0) &&
111 (static_cast<unsigned short>(*i) <= 31))) {
112 mutable_component.erase(i);
113 } else {
114 ++i;
115 }
116 }
117
118 // Remove trailing spaces or periods.
119 while (mutable_component.size() &&
120 ((mutable_component.at(mutable_component.size() - 1) == L' ') ||
121 (mutable_component.at(mutable_component.size() - 1) == L'.')))
122 mutable_component.resize(mutable_component.size() - 1, L' ');
123
124 // Remove a bunch of forbidden names. windows only seems to mind if
125 // a forbidden name matches our name exactly (e.g. "prn") or if the
126 // name is the forbidden name, followed by a dot, followed by anything
127 // (e.g., "prn.anything.foo.bar")
128
129 // From this point out, we break mutable_component into two strings, and
130 // use them this way: we save anything after and including the first dot
131 // (usually the extension) and only mess with stuff before the first dot.
132 PathString::size_type first_dot = mutable_component.find_first_of(L'.');
133 if (PathString::npos == first_dot)
134 first_dot = mutable_component.size();
135 PathString sub = mutable_component.substr(0, first_dot);
136 PathString postsub = mutable_component.substr(first_dot);
137 CHECK(sub + postsub == mutable_component);
138 for (int i = 0; i < ARRAYSIZE(kWindowsIllegalBaseFilenames); i++) {
139 // ComparePathNames(a, b) == 0 -> same
140 if (syncable::ComparePathNames(kWindowsIllegalBaseFilenames[i], sub) == 0) {
141 sub.append(L"~1");
142 break;
143 }
144 }
145 if ((L"" == sub) && (L"" == postsub)) {
146 sub = L"~1";
147 }
148
149 // Return the new name, only if it differs from the original.
150 if ((sub + postsub) == component)
151 return L"";
152 return (sub + postsub);
153 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698