OLD | NEW |
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <sys/types.h> | 5 #include "chrome/browser/sync/util/path_helpers.h" |
6 | 6 |
7 #include <algorithm> | 7 #include "build/build_config.h" |
8 #include <pwd.h> | |
9 #include <string.h> | |
10 | |
11 #include "base/logging.h" | |
12 #include "base/port.h" | |
13 #include "chrome/browser/sync/util/character_set_converters.h" | |
14 #include "chrome/browser/sync/util/path_helpers.h" | |
15 | 8 |
16 #if ((!defined(OS_LINUX)) && (!defined(OS_MACOSX))) | 9 #if ((!defined(OS_LINUX)) && (!defined(OS_MACOSX))) |
17 #error Compile this file on Mac OS X or Linux only. | 10 #error Compile this file on Mac OS X or Linux only. |
18 #endif | 11 #endif |
19 | 12 |
20 PathString ExpandTilde(const PathString& path) { | |
21 if (path.empty()) | |
22 return path; | |
23 if ('~' != path[0]) | |
24 return path; | |
25 PathString ret; | |
26 // TODO(sync): Consider using getpwuid_r. | |
27 ret.insert(0, getpwuid(getuid())->pw_dir); | |
28 ret.append(++path.begin(), path.end()); | |
29 return ret; | |
30 } | |
31 | |
32 namespace { | |
33 // TODO(sync): We really should use char[]. | |
34 std::string cache_dir_; | |
35 } | |
36 | |
37 void set_cache_dir(std::string cache_dir) { | |
38 CHECK(cache_dir_.empty()); | |
39 cache_dir_ = cache_dir; | |
40 } | |
41 | |
42 std::string get_cache_dir() { | |
43 CHECK(!cache_dir_.empty()); | |
44 return cache_dir_; | |
45 } | |
46 | |
47 // On Posix, PathStrings are UTF-8, not UTF-16 as they are on Windows. Thus, | |
48 // this function is different from the Windows version. | |
49 PathString TruncatePathString(const PathString& original, int length) { | |
50 if (original.size() <= static_cast<size_t>(length)) | |
51 return original; | |
52 if (length <= 0) | |
53 return original; | |
54 PathString ret(original.begin(), original.begin() + length); | |
55 COMPILE_ASSERT(sizeof(PathChar) == sizeof(uint8), PathStringNotUTF8); | |
56 PathString::reverse_iterator last_char = ret.rbegin(); | |
57 | |
58 // Values taken from | |
59 // http://en.wikipedia.org/w/index.php?title=UTF-8&oldid=252875566 | |
60 if (0 == (*last_char & 0x80)) | |
61 return ret; | |
62 | |
63 for (; last_char != ret.rend(); ++last_char) { | |
64 if (0 == (*last_char & 0x80)) { | |
65 // Got malformed UTF-8; bail. | |
66 return ret; | |
67 } | |
68 if (0 == (*last_char & 0x40)) { | |
69 // Got another trailing byte. | |
70 continue; | |
71 } | |
72 break; | |
73 } | |
74 | |
75 if (ret.rend() == last_char) { | |
76 // We hit the beginning of the string. bail. | |
77 return ret; | |
78 } | |
79 | |
80 int last_codepoint_len = last_char - ret.rbegin() + 1; | |
81 | |
82 if (((0xC0 == (*last_char & 0xE0)) && (2 == last_codepoint_len)) || | |
83 ((0xE0 == (*last_char & 0xF0)) && (3 == last_codepoint_len)) || | |
84 ((0xF0 == (*last_char & 0xF8)) && (4 == last_codepoint_len))) { | |
85 // Valid utf-8. | |
86 return ret; | |
87 } | |
88 | |
89 // Invalid utf-8. chop off last "codepoint" and return. | |
90 ret.resize(ret.size() - last_codepoint_len); | |
91 return ret; | |
92 } | |
93 | |
94 // Convert /s to :s. | 13 // Convert /s to :s. |
95 PathString MakePathComponentOSLegal(const PathString& component) { | 14 PathString MakePathComponentOSLegal(const PathString& component) { |
96 if (PathString::npos == component.find("/")) | 15 if (PathString::npos == component.find("/")) |
97 return PSTR(""); | 16 return PSTR(""); |
98 PathString new_name(component); | 17 PathString new_name(component); |
99 std::replace(new_name.begin(), new_name.end(), '/', ':'); | 18 std::replace(new_name.begin(), new_name.end(), '/', ':'); |
100 return new_name; | 19 return new_name; |
101 } | 20 } |
102 | |
103 string LastPathSegment(const string& path) { | |
104 string str(path); | |
105 string::size_type final_slash = str.find_last_of('/'); | |
106 if (string::npos != final_slash && final_slash == str.length() - 1 | |
107 && str.length() > 1) { | |
108 str.erase(final_slash); | |
109 final_slash = str.find_last_of('/'); | |
110 } | |
111 if (string::npos == final_slash) | |
112 return str; | |
113 str.erase(0, final_slash + 1); | |
114 return str; | |
115 } | |
116 | |
117 PathString AppendSlash(const PathString& path) { | |
118 if ((!path.empty()) && (*path.rbegin() != '/')) { | |
119 return path + '/'; | |
120 } | |
121 return path; | |
122 } | |
123 | |
OLD | NEW |