8 #ifndef INCL_evo_filepath_h 9 #define INCL_evo_filepath_h 51 static bool reserved_filename(
const char* name,
StrSizeT size) {
52 if (size > 4 && name[4] ==
'.')
54 else if (size > 3 && name[3] ==
'.')
62 if ( (buf[0] ==
'c' && buf[1] ==
'o' && buf[2] ==
'n') ||
63 (buf[0] ==
'p' && buf[1] ==
'r' && buf[2] ==
'n') ||
64 (buf[0] ==
'a' && buf[1] ==
'u' && buf[2] ==
'x') ||
65 (buf[0] ==
'n' && buf[1] ==
'u' && buf[2] ==
'l') )
72 if ( ( (buf[0] ==
'c' && buf[1] ==
'o' && buf[2] ==
'm') ||
73 (buf[0] ==
'l' && buf[1] ==
'p' && buf[2] ==
't') ) &&
74 name[3] >=
'1' && name[3] <=
'9' )
84 static bool valid_filename(
const char* name,
StrSizeT size,
bool strict) {
85 const char lastch = name[size - 1];
86 if (lastch ==
' ' || (size > 1 && lastch ==
'.' && (size > 2 || *name !=
'.')))
88 return (!strict || !reserved_filename(name, size));
115 if (path.
starts(PATH_DELIM) || path.
starts(PATH_DELIM_POSIX))
118 return (path.
size() >= 3 && path[1] ==
':' && (path[2] == PATH_DELIM || path[2] ==
PATH_DELIM_POSIX));
119 return (path.
size() >= 2 && path[1] ==
':');
121 return path.
starts(PATH_DELIM);
134 return (path.
starts(
"\\\\", 2) || path.
starts(
"//", 2) || (path.
size() >= 2 && path[1] ==
':'));
161 const char* p = path.
data();
162 const char* end = p + path.
size();
167 const char* CHARMAP =
168 "0000000000000000000000000000000011011111110111101111111111010100" 169 "1111111111111111111111111111111111111111111111111111111111110111" 170 "1111111111111111111111111111111111111111111111111111111111111111" 171 "1111111111111111111111111111111111111111111111111111111111111111";
173 const char* name = NULL;
174 if (path.
size() >= 2 && p[1] ==
':') {
175 if (CHARMAP[(uchar)*p] ==
'0' || (path.
size() > 2 && p[2] !=
PATH_DELIM))
181 for (; p < end; ++p) {
182 if (*p == PATH_DELIM) {
183 if (name != NULL && name < p && !valid_filename(name, (
StrSizeT)(p - name), strict))
186 }
else if (CHARMAP[(uchar)*p] ==
'0')
189 if (name != NULL && name < p && !valid_filename(name, (
StrSizeT)(p - name), strict))
227 const char* p = filename.
data();
228 const char* end = p + filename.
size();
233 const char* CHARMAP =
234 "0000000000000000000000000000000011011111110111101111111111010100" 235 "1111111111111111111111111111011111111111111111111111111111110111" 236 "1111111111111111111111111111111111111111111111111111111111111111" 237 "1111111111111111111111111111111111111111111111111111111111111111";
240 if (CHARMAP[(uchar)*p] ==
'0')
242 if (!valid_filename(filename.
data(), filename.
size(), strict))
252 if (*p == 0 || *p == PATH_DELIM)
274 bool network_path =
false;
280 if (path.
starts(PATH_DELIM))
281 output.
add(PATH_DELIM);
284 while (input.token(value, PATH_DELIM)) {
285 if (value == PARENT_DIR) {
291 else if (output.
size() >= 2 && output[1] ==
':')
296 if (output[0] == PATH_DELIM)
302 }
else if (i == 2 && output[1] ==
':')
311 }
else if (value.
size() > 0 && value != CUR_DIR) {
312 if (output.
size() > 0 && !output.
ends(PATH_DELIM))
313 output.
add(PATH_DELIM);
319 if (output.
size() == 2 && output[1] ==
':')
320 output.
add(PATH_DELIM);
340 const char* p = path.
data();
342 for (
const char* end = p + path.
size(); p < end; ++p) {
343 if (*p == PATH_DELIM_POSIX)
385 }
else if (path.
size() >= 2 && path[1] ==
':')
412 else if (path[0] == path[1])
416 }
else if (i == 2 && path[1] ==
':')
447 name.
set(path, i + 1,
ALL);
468 if (i ==
NONE || (i == 0 && path[i] ==
'.'))
470 else if (path[i] !=
'.')
471 name.
set(path, i + 1,
ALL);
472 else if (i > 0 && ((ch=path[i-1]) == PATH_DELIM || ch == PATH_DELIM_POSIX || ch ==
':'))
476 name.
set2(path, (j ==
NONE ? 0 : j + 1), i);
481 if (i ==
NONE || (i == 0 && path[i] ==
'.'))
483 else if (path[i] !=
'.')
484 name.
set(path, i + 1,
ALL);
485 else if (i > 0 && path[i-1] == PATH_DELIM)
489 name.
set2(path, (j ==
NONE ? 0 : j + 1), i);
512 if (i == 0 && path[0] ==
'.')
514 else if (i !=
NONE && path[i] ==
'.') {
517 if (i == 2 && path[1] ==
':')
519 else if (i > 0 && ((ch=path[i-1]) == PATH_DELIM || ch == PATH_DELIM_POSIX))
521 if (i > 0 && path[i-1] == PATH_DELIM)
525 name.
set(path, i + 1,
ALL);
553 if (path.
starts(PATH_DELIM) || path.
starts(PATH_DELIM_POSIX))
555 }
else if (b.
starts(PATH_DELIM) || b.
starts(PATH_DELIM_POSIX)) {
575 if (path.
starts(PATH_DELIM)) {
580 while (remain.
token(val, PATH_DELIM))
610 outpath.
set(path, i,
ALL);
612 }
else if (path.
size() >= 2 && path[1] ==
':') {
614 outpath.
set(path, 2,
ALL);
643 outfilename.
set(path, 1,
ALL);
645 if (path[i] ==
':') {
647 outfilename.
set(path, 2,
ALL);
648 }
else if (path[0] == path[1]) {
650 outfilename.
set(path, 2,
ALL);
653 outfilename.
set(path, i + 1,
ALL);
655 }
else if (i == 2 && path[1] ==
':') {
657 outfilename.
set(path, i + 1,
ALL);
663 outfilename.
set(path, 1,
ALL);
666 else if (i !=
NONE) {
668 outfilename.
set(path, i + 1,
ALL);
669 }
else if (!path.
null())
688 if (i ==
NONE || i == 0) {
692 name.
set(filename, 0, i);
693 ext.
set(filename, i + 1,
ALL);
741 if (addpath.
size() >= 2 && addpath[1] ==
':')
745 if (addpath.
starts(PATH_DELIM)) {
747 }
else if (addpath.
size() > 0) {
748 basepath.
addsep(PATH_DELIM);
749 basepath.
add(addpath);
763 const typename T::Size sz = list.
size();
768 typename T::Size i = 1;
769 if (sz > 1 && (first.
ends(PATH_DELIM_POSIX) || first.
ends(
':')))
772 for (; i < sz; ++i) {
774 if (!out.
ends(PATH_DELIM_POSIX))
806 else if (filename.
empty())
809 else if (dirpath.
size() == 2 && dirpath[1] ==
':') {
819 if (!out.
ends(PATH_DELIM_POSIX))
836 if (basename.
empty()) {
839 }
else if (ext.
empty())
863 else if (dirpath.
empty() && drive.
ends(
':')) {
874 if (!out.
ends(PATH_DELIM_POSIX))
896 if (ext.
size() > 0) {
901 }
else if (dirpath.
empty() && drive.
ends(
':')) {
905 if (ext.
size() > 0) {
915 if (!out.
ends(PATH_DELIM_POSIX))
919 if (ext.
size() > 0) {
bool splitat(Key index, T1 &left, T2 &right) const
Split into left/right sublists at index.
bool empty() const
Get whether empty.
char ascii_tolower(char ch)
Convert ASCII character to lowercase.
Definition: str.h:119
static String & join_list(String &out, const T &list)
Join list of path components.
Definition: filepath.h:762
Size size() const
Get size.
Definition: list.h:759
SubString & triml(Size size)
Trim left (beginning) items.
Definition: substring.h:1307
bool token(StringT &value, char delim)
Extract next token from string.
Definition: substring.h:383
static bool validate_filename(const SubString &filename, bool strict=true)
Validate whether filename is valid.
Definition: filepath.h:226
static String & join(String &basepath, const SubString &addpath)
Join two paths together.
Definition: filepath.h:739
static bool hasdrive(const SubString &path)
Check whether given path has a drive component.
Definition: filepath.h:132
T first(T val1, T val2)
Definition: alg.h:85
static void split_all(SubString &drive, SubString &dirpath, SubString &basename, SubString &ext, const SubString &path)
Split input path into drive, dirpath, file basename, and file extension components.
Definition: filepath.h:720
static SubString filename_base(const SubString &path)
Get base filename from path, which is the filename without the extension.
Definition: filepath.h:461
Key findany(const char *chars, Size count, Key start=0, Key end=END) const
Find first occurrence of any given characters with forward search.
Definition: substring.h:828
static SubString dirpath(const SubString &path)
Get directory path from path.
Definition: filepath.h:402
static SubString split_filename(SubString &ext, const SubString &filename)
Split filename into base name and extension.
Definition: filepath.h:685
Size size() const
Get size.
static T & split_list(T &list, const SubString &path)
Split path into list of components.
Definition: filepath.h:543
bool starts(const char *str) const
Check if starts with given terminated string.
Definition: substring.h:658
static const char PATH_DELIM_WIN32
Path delimiter char for Windows systems.
Definition: filepath.h:93
uint32 StrSizeT
Default Evo string size type.
Definition: sys.h:734
static bool abs(const SubString &path, bool strict=true)
Check whether path is an absolute path.
Definition: filepath.h:113
String container.
Definition: string.h:674
static const char PATH_DELIM_POSIX
Path delimiter char for Linux/Unix systems.
Definition: filepath.h:94
static SubString filename_ext(const SubString &path)
Get file extension from filename in path.
Definition: filepath.h:504
static String & join_filename(String &out, const SubString &basename, const SubString &ext)
Join file base name and extension components and write to output string.
Definition: filepath.h:835
static const EndT END
Special integer value for indicating end of items or no item.
Definition: type.h:1846
static const EndT ALL
Special integer value for indicating all items or all remaining items.
Definition: type.h:1839
static String & join_dirpath(String &out, const SubString &dirpath, const SubString &filename)
Join dirpath and filename and write to output string.
Definition: filepath.h:803
String & setempty()
Set as empty but not null.
Definition: string.h:982
static String & join_all(String &out, const SubString &drive, const SubString &dirpath, const SubString &filename)
Join drive, dirpath, and filename components and write to output string.
Definition: filepath.h:859
static const char PATH_DELIM
Path delimiter char for current OS.
Definition: filepath.h:99
static SubString split_drive(SubString &outpath, const SubString &path)
Get Windows drive and remaining path from path.
Definition: filepath.h:597
bool ends(char ch) const
Check if this ends with given character.
Definition: string.h:1694
Evo C++ Library namespace.
Definition: alg.h:11
static const EndT NONE
Special integer value for indicating no item or unknown item.
Definition: type.h:1832
SubString & set2(const StringBase &data, Key index1, Key index2)
Set as reference to subset of source data using start/end positions.
Definition: substring.h:1299
static SubString filename(const SubString &path)
Get filename from path.
Definition: filepath.h:436
String & addsep(char delim=',')
Append separator/delimiter if needed (modifier).
Definition: string.h:2799
static String & normalize_case(String &outpath, const SubString &path)
Normalize path case.
Definition: filepath.h:335
SubString & setempty()
Set as empty but not null.
Definition: substring.h:1303
static String & normalize(String &outpath, const SubString &path)
Normalize path and remove redundant components.
Definition: filepath.h:267
String & add(char ch)
Append character (modifier).
Definition: string.h:2741
static String & join_all(String &out, const SubString &drive, const SubString &dirpath, const SubString &basename, const SubString &ext)
Join drive, dirpath, and filename components and write to output string.
Definition: filepath.h:892
File and directory path helpers.
Definition: filepath.h:47
T * advBuffer(Size size)
Advanced: Resize and get buffer pointer (modifier).
Definition: list.h:2728
bool null() const
Get whether null.
static String & join_drive(String &out, const SubString &drive, const SubString &dirpath)
Join drive and dirpath and write to output string.
Definition: filepath.h:791
String & truncate(Size size=0)
Truncate to given size.
Definition: string.h:4987
Key findr(char ch) const
Find last occurrence of character with reverse search.
Definition: string.h:1879
static SubString drive(const SubString &path)
Get Windows drive from path.
Definition: filepath.h:373
static void split_all(SubString &drive, SubString &dirpath, SubString &filename, const SubString &path)
Split input path into drive, dirpath, and filename components.
Definition: filepath.h:706
Key findr(char ch) const
Find last occurrence of character with reverse search.
Definition: substring.h:747
static SubString split_dirpath(SubString &outfilename, const SubString &path)
Get directory path from path.
Definition: filepath.h:636
static bool validate(const SubString &path, bool strict=true)
Validate whether path is valid.
Definition: filepath.h:160
SubString & set(const char *data)
Set as reference to terminated string.
Definition: substring.h:353
Reference and access existing string data.
Definition: substring.h:229
bool ends(const char *str) const
Check if ends with given terminated string.
Definition: substring.h:671
Key findanyr(const char *chars, Size count, Key start=0, Key end=END) const
Find last occurrence of any given characters with reverse search.
Definition: substring.h:853
const char * data() const
Get data pointer.
String & reserve(Size size, bool prefer_realloc=false)
Reserve capacity for additional items (modifier).
Definition: string.h:5027