| |
| |
|
|
| |
| |
| |
| |
| const char slash = '\\'; |
| const char auxslash = '/'; |
| |
| const char slash = '/'; |
| const char auxslash = '\\'; |
| |
| |
| |
| |
| |
| string TFrameId::expand(FrameFormat format) const |
| { |
| if (m_frame == EMPTY_FRAME) |
| return ""; |
| else if (m_frame == NO_FRAME) |
| return "-"; |
| char buffer[80]; |
| ostrstream o_buff(buffer, sizeof(buffer)); |
| if (format == FOUR_ZEROS) { |
| o_buff.fill('0'); |
| o_buff.width(4); |
| o_buff << m_frame; |
| o_buff.width(0); |
| } else { |
| o_buff << m_frame; |
| } |
| if (m_letter != '\0') |
| o_buff << m_letter; |
| int len = o_buff.pcount(); |
| return string(buffer, len); |
| } |
| |
| |
| |
| const TFrameId &TFrameId::operator++() |
| { |
| ++m_frame; |
| m_letter = 0; |
| return *this; |
| } |
| |
| |
| |
| const TFrameId &TFrameId::operator--() |
| { |
| if (m_letter > 0) |
| m_letter = 0; |
| else |
| --m_frame; |
| return *this; |
| } |
| |
| |
| |
| inline bool isSlash(char c) |
| { |
| return c == slash || c == auxslash; |
| } |
| |
| |
| |
| |
| |
| inline int getLastSlash(const string &path) |
| { |
| int i; |
| for (i = path.length() - 1; i >= 0 && !isSlash(path[i]); i--) { |
| } |
| return i; |
| } |
| |
| |
| |
| void TFilePath::setPath(string path) |
| { |
| bool isUncName = false; |
| |
| |
| int length = path.length(); |
| int pos = 0; |
| if (path.length() >= 2 && isalpha(path[0]) && path[1] == ':') { |
| m_path.append(path, 0, 2); |
| pos = 2; |
| if (path.length() == 2 || !isSlash(path[pos])) |
| m_path.append(1, slash); |
| } |
| |
| else |
| if (path.length() >= 3 && path[0] == '\\' && path[1] == '\\' && isalpha(path[2])) { |
| isUncName = true; |
| m_path.append(path, 0, 3); |
| pos = 3; |
| } |
| |
| for (; pos < length; pos++) |
| if (path[pos] == '.') { |
| pos++; |
| if (pos >= length) { |
| if (pos > 1) |
| m_path.append(1, '.'); |
| } else if (!isSlash(path[pos])) |
| m_path.append(path, pos - 1, 2); |
| else { |
| while (pos + 1 < length && isSlash(path[pos + 1])) |
| pos++; |
| } |
| } else if (isSlash(path[pos])) { |
| do |
| pos++; |
| while (pos < length && isSlash(path[pos])); |
| pos--; |
| m_path.append(1, slash); |
| } else { |
| m_path.append(1, path[pos]); |
| } |
| |
| |
| |
| if (!(m_path.length() == 1 && m_path[0] == slash || |
| m_path.length() == 3 && isalpha(m_path[0]) && m_path[1] == ':' && m_path[2] == slash) && |
| m_path.length() > 1 && m_path[m_path.length() - 1] == slash) |
| m_path.erase(m_path.length() - 1, 1); |
| |
| if (isUncName && m_path.find_last_of('\\') == 1) |
| m_path.append(1, slash); |
| } |
| |
| |
| |
| TFilePath::TFilePath(string path) |
| : m_path("") |
| { |
| setPath(path); |
| } |
| |
| |
| |
| TFilePath::TFilePath(const char *path) |
| : m_path("") |
| { |
| setPath(string(path)); |
| } |
| |
| |
| |
| bool TFilePath::operator==(const TFilePath &fp) const |
| { |
| |
| return stricmp(m_path.c_str(), fp.m_path.c_str()) == 0; |
| |
| return m_path == fp.m_path; |
| |
| } |
| |
| |
| |
| bool TFilePath::operator<(const TFilePath &fp) const |
| { |
| string iName = m_path; |
| string jName = fp.m_path; |
| int i1 = 0, j1 = 0; |
| int i2 = m_path.find("\\"); |
| int j2 = fp.m_path.find("\\"); |
| if (i2 == j2 && j2 == -1) |
| |
| return stricmp(m_path.c_str(), fp.m_path.c_str()) < 0; |
| |
| return m_path < fp.m_path; |
| |
| if (!i2) { |
| ++i1; |
| i2 = m_path.find("\\", i1); |
| } |
| if (!j2) { |
| ++j1; |
| j2 = fp.m_path.find("\\", j1); |
| } |
| while (i2 != -1 || j2 != -1) { |
| iName = m_path.substr(i1, i2 - i1); |
| jName = fp.m_path.substr(j1, j2 - j1); |
| |
| |
| |
| char differ; |
| differ = stricmp(iName.c_str(), jName.c_str()); |
| if (differ != 0) |
| return differ < 0 ? true : false; |
| |
| if (TFilePath(iName) != TFilePath(jName)) |
| return TFilePath(iName) < TFilePath(jName); |
| |
| i1 = i2 + 1; |
| j1 = j2 + 1; |
| i2 = m_path.find("\\", i1); |
| j2 = fp.m_path.find("\\", j1); |
| } |
| iName = m_path.substr(i1, m_path.size() - i1); |
| jName = fp.m_path.substr(j1, fp.m_path.size() - j1); |
| |
| return stricmp(iName.c_str(), jName.c_str()) < 0; |
| |
| return TFilePath(iName) < TFilePath(jName); |
| |
| } |
| |
| |
| |
| TFilePath &TFilePath::operator+=(const TFilePath &fp) |
| { |
| assert(!fp.isAbsolute()); |
| if (fp.isEmpty()) |
| return *this; |
| else if (isEmpty()) { |
| *this = fp; |
| return *this; |
| } else if (m_path.length() != 1 || m_path[0] != slash) { |
| *this = TFilePath(m_path + slash + fp.m_path); |
| return *this; |
| } else { |
| *this = TFilePath(m_path + fp.m_path); |
| return *this; |
| } |
| } |
| |
| TFilePath TFilePath::operator+(const TFilePath &fp) const |
| { |
| TFilePath ret(*this); |
| ret += fp; |
| return ret; |
| } |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| bool TFilePath::isAbsolute() const |
| { |
| return m_path.length() >= 1 && m_path[0] == slash || |
| m_path.length() >= 2 && isalpha(m_path[0]) && m_path[1] == ':'; |
| } |
| |
| |
| |
| bool TFilePath::isRoot() const |
| { |
| return m_path.length() == 1 && m_path[0] == slash || |
| m_path.length() == 3 && isalpha(m_path[0]) && m_path[1] == ':' && m_path[2] == slash; |
| } |
| |
| |
| |
| |
| string TFilePath::getDots() const |
| { |
| int i = getLastSlash(m_path); |
| string str = m_path.substr(i + 1); |
| |
| i = str.rfind("."); |
| if (i == string::npos || str == "..") |
| return ""; |
| return str.substr(0, i).rfind(".") == string::npos ? "." : ".."; |
| } |
| |
| |
| |
| string TFilePath::getDottedType() const |
| { |
| int i = getLastSlash(m_path); |
| string str = m_path.substr(i + 1); |
| i = str.rfind("."); |
| if (i == string::npos) |
| return ""; |
| |
| return toLower(str.substr(i)); |
| |
| return str.substr(i); |
| |
| } |
| |
| |
| |
| string TFilePath::getUndottedType() const |
| { |
| size_t i = getLastSlash(m_path); |
| string str = m_path.substr(i + 1); |
| i = str.rfind("."); |
| if (i == string::npos || i == str.length() - 1) |
| return ""; |
| |
| return toLower(str.substr(i + 1)); |
| |
| return str.substr(i + 1); |
| |
| } |
| |
| |
| |
| string TFilePath::getName() const |
| { |
| int i = getLastSlash(m_path); |
| string str = m_path.substr(i + 1); |
| i = str.rfind("."); |
| if (i == string::npos) |
| return str; |
| int j = str.substr(0, i).rfind("."); |
| if (j != string::npos) |
| i = j; |
| return str.substr(0, i); |
| } |
| |
| |
| |
| string TFilePath::getLevelName() const |
| { |
| int i = getLastSlash(m_path); |
| string str = m_path.substr(i + 1); |
| i = str.find("."); |
| if (i == string::npos) |
| return str; |
| int j = str.rfind("."); |
| if (j == i || j - i == 1) |
| return str; |
| else |
| return str.erase(i + 1, j - i - 1); |
| } |
| |
| |
| |
| TFilePath TFilePath::getParentDir() const |
| { |
| int i = getLastSlash(m_path); |
| if (i < 0) { |
| if (m_path.length() >= 2 && ('a' <= m_path[0] && m_path[0] <= 'z' || 'A' <= m_path[0] && m_path[0] <= 'Z') && m_path[1] == ':') |
| return TFilePath(m_path.substr(0, 2)); |
| else |
| return TFilePath(""); |
| } else if (i == 0) |
| return TFilePath("/"); |
| else |
| return TFilePath(m_path.substr(0, i)); |
| } |
| |
| |
| |
| TFrameId TFilePath::getFrame() const |
| { |
| int i = getLastSlash(m_path); |
| string str = m_path.substr(i + 1); |
| i = str.rfind('.'); |
| if (i == string::npos || str == "." || str == "..") |
| return TFrameId(TFrameId::NO_FRAME); |
| int j = str.substr(0, i).rfind('.'); |
| if (j == string::npos) |
| return TFrameId(TFrameId::NO_FRAME); |
| if (i == j + 1) |
| return TFrameId(TFrameId::EMPTY_FRAME); |
| |
| int k, number = 0; |
| for (k = j + 1; k < i && isdigit(str[k]); k++) |
| number = number * 10 + str[k] - '0'; |
| char letter = '\0'; |
| if (isalpha(str[k])) |
| letter = str[k++]; |
| if (number == 0 || k < i) |
| throw TMalformedFrameException(); |
| return TFrameId(number, letter); |
| } |
| |
| |
| |
| TFilePath TFilePath::withType(const string &type) const |
| { |
| const string dotDot = ".."; |
| assert(type.length() < 2 || type.substr(0, 2) != dotDot); |
| int i = getLastSlash(m_path); |
| string str = m_path.substr(i + 1); |
| int j = str.rfind('.'); |
| if (j == string::npos || str == dotDot) |
| |
| { |
| if (type == "") |
| return *this; |
| else if (type[0] == '.') |
| return TFilePath(m_path + type); |
| else |
| return TFilePath(m_path + "." + type); |
| } else |
| |
| { |
| if (type == "") |
| return TFilePath(m_path.substr(0, i + j + 1)); |
| else if (type[0] == '.') |
| return TFilePath(m_path.substr(0, i + j + 1) + type); |
| else |
| return TFilePath(m_path.substr(0, i + j + 2) + type); |
| } |
| } |
| |
| |
| |
| TFilePath TFilePath::withName(const string &name) const |
| { |
| int i = getLastSlash(m_path); |
| string str = m_path.substr(i + 1); |
| int j = str.rfind('.'); |
| if (j == string::npos) |
| return TFilePath(m_path.substr(0, i + 1) + name); |
| int k = str.substr(0, j).rfind("."); |
| if (k == string::npos) |
| k = j; |
| return TFilePath(m_path.substr(0, i + 1) + name + str.substr(k)); |
| } |
| |
| |
| |
| TFilePath TFilePath::withParentDir(const TFilePath &dir) const |
| { |
| int i = getLastSlash(m_path); |
| return dir + TFilePath(m_path.substr(i + 1)); |
| } |
| |
| |
| |
| TFilePath TFilePath::withFrame(const TFrameId &frame, TFrameId::FrameFormat format) const |
| { |
| const string dot = ".", dotDot = ".."; |
| int i = getLastSlash(m_path); |
| string str = m_path.substr(i + 1); |
| assert(str != dot && str != dotDot); |
| int j = str.rfind('.'); |
| if (j == string::npos) { |
| if (frame.isEmptyFrame() || frame.isNoFrame()) |
| return *this; |
| else |
| return TFilePath(m_path + "." + frame.expand(format)); |
| } |
| |
| string frameString; |
| if (frame.isNoFrame()) |
| frameString = ""; |
| else |
| frameString = "." + frame.expand(format); |
| |
| int k = str.substr(0, j).rfind('.'); |
| if (k == string::npos) |
| return TFilePath(m_path.substr(0, j + i + 1) + frameString + str.substr(j)); |
| else |
| return TFilePath(m_path.substr(0, k + i + 1) + frameString + str.substr(j)); |
| } |
| |
| |
| |
| bool TFilePath::isAncestorOf(const TFilePath &fp) const |
| { |
| size_t len = m_path.length(); |
| |
| if (len == 0) { |
| |
| return !fp.isAbsolute(); |
| } |
| |
| return len < fp.m_path.length() |
| && (m_path[len - 1] == slash |
| || fp.m_path[len] == slash) |
| && |
| |
| toLower(m_path) == toLower(fp.m_path.substr(0, len)); |
| |
| m_path == fp.m_path.substr(0, len); |
| |
| } |
| |
| |
| |
| TFilePath TFilePath::operator-(const TFilePath &fp) const |
| { |
| |
| if (toLower(m_path) == toLower(fp.m_path)) |
| return TFilePath(""); |
| |
| if (m_path == fp.m_path) |
| return TFilePath(""); |
| |
| if (!fp.isAncestorOf(*this)) |
| return *this; |
| int len = fp.m_path.length(); |
| if (len == 0 || fp.m_path[len - 1] != slash) |
| len++; |
| |
| return TFilePath(m_path.substr(len)); |
| } |
| |
| |
| |
| bool TFilePath::match(const TFilePath &fp) const |
| { |
| return getParentDir() == fp.getParentDir() && |
| getName() == fp.getName() && |
| getFrame() == fp.getFrame() && |
| getType() == fp.getType(); |
| } |
| |
| |
| |
| TFilePath TFilePath::decode(const std::map<string, string> &dictionary) const |
| { |
| TFilePath parent = getParentDir(); |
| TFilePath filename = withParentDir(""); |
| std::map<string, string>::const_iterator it = dictionary.find(filename.getFullPath()); |
| if (it != dictionary.end()) |
| filename = TFilePath(it->second); |
| if (parent.isEmpty()) |
| return filename; |
| else |
| return parent.decode(dictionary) + filename; |
| } |
| |