static inline String::CPtr trimSeps(String::CPtr str) { assert(str); Size len = str->length(); if (!len) return str; Size i = len - 1; while (1) { if (!isSep(str->charAt(i))) { return str->substring(0, i + 1); } if (i) { i--; } else { break; } } return str->substring(0, 1); }
String::CPtr dirname(String::CPtr path) { LIBJ_STATIC_SYMBOL_DEF(symCurrent, "."); if (!path) return symCurrent; path = trimSeps(path); String::CPtr base = basename(path); Size baseLen = base->length(); Size pathLen = path->length(); if (baseLen == pathLen) { return symCurrent; } else { Size sepPos = pathLen - baseLen - 1; assert(isSep(path->charAt(sepPos))); if (sepPos) { return path->substring(0, sepPos); } else { return path->substring(0, 1); } } }
String::CPtr extname(String::CPtr path) { if (!path) return String::create(); String::CPtr base = basename(path); if (base->charAt(0) == '.') return String::create(); Size lastIndex = base->lastIndexOf('.'); if (lastIndex == NO_POS) { return String::create(); } else { return base->substring(lastIndex); } }
String::CPtr basename(String::CPtr path) { LIBJ_STATIC_SYMBOL_DEF(symNull, "null"); if (path) { path = trimSeps(path); } else { return symNull; } Size lastIndex = lastIndexOfSep(path); if (lastIndex == NO_POS) { return path; } else { return path->substring(lastIndex + 1); } }
String::CPtr normalize(String::CPtr path) { LIBJ_STATIC_SYMBOL_DEF(symCurrent, "."); LIBJ_STATIC_SYMBOL_DEF(symParent, ".."); LIBJ_STATIC_SYMBOL_DEF(symNull, "null"); if (!path) return symNull; Boolean absolute = false; Boolean endsWithSep = false; typedef TypedJsArray<String::CPtr> StringArray; StringArray::Ptr dirs = StringArray::create(); Size len = path->length(); for (Size i = 0; i < len;) { Size idx = indexOfSep(path, i); if (idx == 0) { absolute = true; } else if (idx != i) { String::CPtr dir; if (idx == NO_POS) { dir = path->substring(i); } else { dir = path->substring(i, idx); } if (dir->equals(symParent)) { Size numDirs = dirs->size(); if (numDirs > 0 && !dirs->getTyped(numDirs - 1)->equals(symParent)) { dirs->removeTyped(numDirs - 1); } else { dirs->addTyped(dir); } } else if (!dir->equals(symCurrent)) { dirs->addTyped(dir); } } if (idx == NO_POS) { endsWithSep = false; i = len; } else { endsWithSep = true; i = idx + 1; } } StringBuilder::Ptr normal = StringBuilder::create(); if (absolute) normal->appendChar(SEP); Size numDirs = dirs->size(); for (Size i = 0; i < numDirs; i++) { if (i) normal->appendChar(SEP); normal->appendStr(dirs->getTyped(i)); } if (numDirs > 0 && endsWithSep) normal->appendChar(SEP); if (normal->length() == 0) { return symCurrent; } else { return normal->toString(); } }