OLD | NEW |
(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 "build/build_config.h" |
| 13 #include "chrome/browser/sync/syncable/syncable.h" |
| 14 |
| 15 #ifndef OS_WIN |
| 16 #error Compile this file on Windows only. |
| 17 #endif |
| 18 |
| 19 using std::string; |
| 20 |
| 21 namespace { |
| 22 const PathString kWindowsIllegalBaseFilenames[] = { |
| 23 "CON", "PRN", "AUX", "NUL", "COM1", "COM2", |
| 24 "COM3", "COM4", "COM5", "COM6", "COM7", |
| 25 "COM8", "COM9", "LPT1", "LPT2", "LPT3", |
| 26 "LPT4", "LPT5", "LPT6", "LPT7", "LPT8", |
| 27 "LPT9" }; |
| 28 } |
| 29 |
| 30 // See: http://msdn.microsoft.com/library/default.asp?url=/library/ |
| 31 // en-us/fileio/fs/naming_a_file.asp |
| 32 // note that * and ? are not listed on the page as illegal characters, |
| 33 // but they are. |
| 34 PathString MakePathComponentOSLegal(const PathString& component) { |
| 35 CHECK(!component.empty()); |
| 36 PathString mutable_component = component; |
| 37 |
| 38 // Remove illegal characters. |
| 39 for (PathString::iterator i = mutable_component.begin(); |
| 40 i != mutable_component.end();) { |
| 41 if ((PathString::npos != PathString("<>:\"/\\|*?").find(*i)) || |
| 42 ((static_cast<unsigned short>(*i) >= 0) && |
| 43 (static_cast<unsigned short>(*i) <= 31))) { |
| 44 mutable_component.erase(i); |
| 45 } else { |
| 46 ++i; |
| 47 } |
| 48 } |
| 49 |
| 50 // Remove trailing spaces or periods. |
| 51 while (mutable_component.size() && |
| 52 ((mutable_component.at(mutable_component.size() - 1) == ' ') || |
| 53 (mutable_component.at(mutable_component.size() - 1) == '.'))) |
| 54 mutable_component.resize(mutable_component.size() - 1, ' '); |
| 55 |
| 56 // Remove a bunch of forbidden names. windows only seems to mind if |
| 57 // a forbidden name matches our name exactly (e.g. "prn") or if the name is |
| 58 // the forbidden name, followed by a dot, followed by anything |
| 59 // (e.g., "prn.anything.foo.bar") |
| 60 |
| 61 // From this point out, we break mutable_component into two strings, and use |
| 62 // them this way: we save anything after and including the first dot (usually |
| 63 // the extension) and only mess with stuff before the first dot. |
| 64 PathString::size_type first_dot = mutable_component.find_first_of('.'); |
| 65 if (PathString::npos == first_dot) |
| 66 first_dot = mutable_component.size(); |
| 67 PathString sub = mutable_component.substr(0, first_dot); |
| 68 PathString postsub = mutable_component.substr(first_dot); |
| 69 CHECK(sub + postsub == mutable_component); |
| 70 for (int i = 0; i < ARRAYSIZE(kWindowsIllegalBaseFilenames); i++) { |
| 71 // ComparePathNames(a, b) == 0 -> same |
| 72 if (syncable::ComparePathNames(kWindowsIllegalBaseFilenames[i], sub) == 0) { |
| 73 sub.append("~1"); |
| 74 break; |
| 75 } |
| 76 } |
| 77 if (("" == sub) && ("" == postsub)) { |
| 78 sub = "~1"; |
| 79 } |
| 80 |
| 81 // Return the new name, only if it differs from the original. |
| 82 if ((sub + postsub) == component) |
| 83 return ""; |
| 84 return (sub + postsub); |
| 85 } |
OLD | NEW |