ozone: evdev: Sync caps lock LED state to evdev
[chromium-blink-merge.git] / native_client_sdk / src / libraries / nacl_io / path.cc
blobc524bfa35ed9b1040d433f0f17b2c6a5a9af46fe
1 // Copyright (c) 2012 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.
5 #include "nacl_io/path.h"
7 #include <stdio.h>
8 #include <string.h>
9 #include <string>
11 #include "sdk_util/string_util.h"
13 namespace nacl_io {
15 Path::Path(const Path& path) {
16 paths_ = path.paths_;
19 Path::Path(const std::string& path) {
20 Set(path);
23 bool Path::IsAbsolute() const {
24 return !paths_.empty() && paths_[0] == "/";
27 const std::string& Path::Part(size_t index) const {
28 return paths_[index];
31 size_t Path::Size() const {
32 return paths_.size();
35 bool Path::IsRoot() const {
36 return paths_.empty() || (paths_.size() == 1 && paths_[0] == "/");
39 Path& Path::MakeRelative() {
40 if (IsAbsolute()) {
41 paths_.erase(paths_.begin());
43 return *this;
46 Path& Path::Append(const Path& path) {
47 // Appending an absolute path effectivly sets the path, ignoring
48 // the current contents.
49 if (path.IsAbsolute()) {
50 paths_ = path.paths_;
51 } else {
52 for (size_t index = 0; index < path.paths_.size(); index++) {
53 paths_.push_back(path.paths_[index]);
57 paths_ = Normalize(paths_);
58 return *this;
61 Path& Path::Append(const std::string& path) {
62 return Append(Path(path));
65 Path& Path::Set(const StringArray_t path) {
66 paths_ = Normalize(path);
67 return *this;
70 Path& Path::Set(const std::string& path) {
71 return Set(Split(path));
74 Path Path::Parent() const {
75 Path out;
76 out.paths_ = paths_;
77 if (out.paths_.size())
78 out.paths_.pop_back();
79 return out;
82 std::string Path::Basename() const {
83 if (paths_.size())
84 return paths_.back();
85 return std::string();
88 std::string Path::Join() const {
89 return Range(paths_, 0, paths_.size());
92 std::string Path::Range(size_t start, size_t end) const {
93 return Range(paths_, start, end);
96 StringArray_t Path::Split() const {
97 return paths_;
100 // static
101 StringArray_t Path::Normalize(const StringArray_t& paths) {
102 StringArray_t path_out;
104 for (size_t index = 0; index < paths.size(); index++) {
105 const std::string& curr = paths[index];
107 // Check if '/' was used excessively in the path.
108 // For example, in cd Desktop/////
109 if (curr == "/" && index != 0)
110 continue;
112 // Check for '.' in the path and remove it
113 if (curr == ".")
114 continue;
116 // Check for '..'
117 if (curr == "..") {
118 // If the path is empty, or "..", then add ".."
119 if (path_out.empty() || path_out.back() == "..") {
120 path_out.push_back(curr);
121 continue;
124 // If the path is at root, "/.." = "/"
125 if (path_out.back() == "/") {
126 continue;
129 // if we are already at root, then stay there (root/.. -> root)
130 if (path_out.back() == "/") {
131 continue;
134 // otherwise, pop off the top path component
135 path_out.pop_back();
136 continue;
139 // By now, we should have handled end cases so just append.
140 path_out.push_back(curr);
143 // If the path was valid, but now it's empty, return self
144 if (path_out.empty())
145 path_out.push_back(".");
147 return path_out;
150 // static
151 std::string Path::Join(const StringArray_t& paths) {
152 return Range(paths, 0, paths.size());
155 // static
156 std::string Path::Range(const StringArray_t& paths, size_t start, size_t end) {
157 std::string out_path;
158 size_t index = start;
160 if (end > paths.size())
161 end = paths.size();
163 // If this is an absolute path, paths[0] == "/". In this case, we don't want
164 // to add an additional / separator.
165 if (start == 0 && end > 0 && paths[0] == "/") {
166 out_path += "/";
167 index++;
170 for (; index < end; index++) {
171 out_path += paths[index];
172 if (index < end - 1)
173 out_path += "/";
176 return out_path;
179 // static
180 StringArray_t Path::Split(const std::string& path) {
181 StringArray_t path_split;
182 StringArray_t components;
184 sdk_util::SplitString(path, '/', &path_split);
186 if (path[0] == '/')
187 components.push_back("/");
189 // Copy path_split to components, removing empty path segments.
190 for (StringArray_t::const_iterator it = path_split.begin();
191 it != path_split.end();
192 ++it) {
193 if (!it->empty())
194 components.push_back(*it);
196 return components;
199 Path& Path::operator=(const Path& p) {
200 paths_ = p.paths_;
201 return *this;
204 Path& Path::operator=(const std::string& p) {
205 return Set(p);
208 } // namespace nacl_io