in activemq-cpp/src/main/decaf/net/URI.cpp [594:694]
std::string URI::normalize(const std::string& path) const {
if (path == "") {
return path;
}
// count the number of '/'s, to determine number of segments
std::size_t index = -1;
std::size_t pathlen = path.length();
unsigned int size = 0;
if (pathlen > 0 && path.at(0) != '/') {
size++;
}
while ((index = path.find('/', index + 1)) != string::npos) {
if (index + 1 < pathlen && path.at(index + 1) != '/') {
size++;
}
}
std::vector<string> seglist(size);
std::vector<bool> include(size);
// break the path into segments and store in the list
std::size_t current = 0;
std::size_t index2 = 0;
index = (pathlen > 0 && path.at(0) == '/') ? 1 : 0;
while ((index2 = path.find('/', index + 1)) != string::npos) {
seglist[current++] = path.substr(index, index2 - index);
index = index2 + 1;
}
// if current==size, then the last character was a slash
// and there are no more segments
if (current < size) {
seglist[current] = path.substr(index);
}
// determine which segments get included in the normalized path
for (unsigned int i = 0; i < size; i++) {
include[i] = true;
if (seglist[i] == "..") {
int remove = i - 1;
// search back to find a segment to remove, if possible
while (remove > -1 && !include[remove]) {
remove--;
}
// if we find a segment to remove, remove it and the ".."
// segment
if (remove > -1 && !(seglist[remove] == "..")) {
include[remove] = false;
include[i] = false;
}
} else if (seglist[i] == ".") {
include[i] = false;
}
}
// put the path back together
string newpath;
if (path.at(0) == '/') {
newpath.append("/");
}
for (unsigned int i = 0; i < seglist.size(); i++) {
if (include[i]) {
newpath.append(seglist[i]);
newpath.append("/");
}
}
// if we used at least one segment and the path previously ended with
// a slash and the last segment is still used, then delete the extra
// trailing '/'
if (path.at(path.length() - 1) != '/' && seglist.size() > 0 && include[seglist.size() - 1]) {
newpath.erase(newpath.length() - 1, 1);
}
string result = newpath;
// check for a ':' in the first segment if one exists,
// prepend "./" to normalize
index = result.find(':');
index2 = result.find('/');
if (index != string::npos && (index < index2 || index2 == string::npos)) {
newpath.insert(0, "./");
result = newpath;
}
return result;
}