2#include <cgv/utils/dir.h>
3#include <cgv/type/standard_types.h>
18#if (__cplusplus >= 201703L || _MSVC_LANG >= 201703L)
20#define USE_STD_FILESYSTEM
27#pragma warning (disable:4996)
30void* open(
const std::string& file_name,
const std::string& mode,
void* buf,
int length)
32 FILE *file = fopen(file_name.c_str(), mode.c_str());
33 if ( (file != 0) && (setvbuf((FILE*) file, (
char*) buf, _IOFBF, length) == 0) )
40bool exists(
const std::string& file_name)
42#ifdef USE_STD_FILESYSTEM
43 return std::filesystem::exists(file_name);
45 void* handle = find_first(file_name);
46 bool ret = (bool)handle;
52std::string find_recursive(
const std::string& path,
const std::string& file_name)
54#ifdef USE_STD_FILESYSTEM
55 if (!cgv::utils::dir::exists(path))
57 if(cgv::utils::file::exists(path +
'/' + file_name))
58 return path +
'/' + file_name;
60 std::filesystem::path target_file_name = file_name;
62 for(
const std::filesystem::directory_entry& dir_entry : std::filesystem::recursive_directory_iterator(path)) {
63 if(dir_entry.is_regular_file() && !dir_entry.is_symlink()) {
64 if(dir_entry.path().filename() == target_file_name) {
65 if(cgv::utils::file::exists(dir_entry.path().string())) {
66 return dir_entry.path().string();
74 if (cgv::utils::file::exists(path+
'/'+file_name))
75 return path+
'/'+file_name;
76 void* h = find_first(path+
"/*");
78 if (find_directory(h) && find_name(h) !=
"." && find_name(h) !=
"..") {
79 std::string res = find_recursive(path+
'/'+find_name(h), file_name);
92std::string find_in_paths(
const std::string& file_name,
const std::string& path_list,
93 bool recursive,
const std::string& sub_dir)
96 if (cgv::utils::file::exists(file_name))
104 sfn = sub_dir+
'/'+file_name;
105 if (cgv::utils::file::exists(sfn))
112 size_t end_pos = path_list.find_first_of(
';', pos);
114 if (end_pos == std::string::npos) {
115 fn = path_list.substr(pos)+
'/'+sfn;
116 pos = path_list.length();
119 fn = path_list.substr(pos,end_pos-pos)+
'/'+sfn;
122 if (cgv::utils::file::exists(fn))
124 }
while (pos < path_list.length());
129 size_t end_pos = path_list.find_first_of(
';', pos);
131 if (end_pos == std::string::npos) {
132 fn = path_list.substr(pos);
133 pos = path_list.length();
136 fn = path_list.substr(pos, end_pos-pos);
139 fn = find_recursive(fn, sfn);
142 }
while (pos < path_list.length());
146bool remove(
const std::string& file_name)
148 return ::remove(file_name.c_str()) == 0;
151bool rename(
const std::string& before,
const std::string& after)
153 return ::rename(before.c_str(), after.c_str()) == 0;
156bool copy(
const std::string& from,
const std::string& to)
158 bool success =
false;
159 FILE* fp = ::fopen(from.c_str(),
"rb");
160 FILE* gp = ::fopen(to.c_str(),
"wb");
165 size_t count = fread (buffer,
sizeof(
char), 4096, fp);
166 if (count != fwrite(buffer,
sizeof(
char), count, gp) ) {
177Result cmp(
const std::string& what,
const std::string& with)
179 Result result = file::EQUAL;
180 FILE* fp = ::fopen(what.c_str(),
"rb");
181 FILE* gp = ::fopen(with.c_str(),
"rb");
186 size_t countf = fread (bufferf,
sizeof(
char), 4096, fp);
187 size_t countg = fread (bufferg,
sizeof(
char), 4096, gp);
188 if ( (countf != countg) ||
189 (::memcmp(bufferf, bufferg,
sizeof(
char)*countf) != 0) ) {
190 result = file::DIFFERENT;
196 result = file::FILE_ERROR;
202size_t size(
const std::string& file_name,
bool ascii)
204#ifdef USE_STD_FILESYSTEM
206 return std::filesystem::file_size(file_name);
214 void* handle = find_first(file_name);
215 size_t s = (size_t)-1;
217 s = find_size(handle);
222 FILE* fp = fopen(file_name.c_str(), ascii ?
"r" :
"rb");
226 if (fseek(fp, 0, SEEK_END) == 0) {
235 int fh = ::open(file_name.c_str(), O_RDONLY);
238 struct stat fileinfo;
239 fstat(fh, &fileinfo);
241 return fileinfo.st_size;
247bool read(
const std::string& filename,
char* ptr,
size_t size,
bool ascii,
size_t file_offset)
249 FILE* fp = ::fopen(filename.c_str(), ascii ?
"r" :
"rb");
250 if (file_offset != 0) {
257 (fp, file_offset, SEEK_SET) != 0)
260 size_t n = ::fread(ptr, 1, size, fp);
266bool read(
const std::string& file_name, std::string& content,
bool ascii)
268 size_t l = size(file_name, ascii);
269 if (l == (
size_t)-1)
return false;
278 FILE* fp = ::fopen(file_name.c_str(), ascii ?
"r" :
"rb");
279 size_t n = ::fread(&content[0], 1, l, fp);
285char* read(
const std::string& file_name,
bool ascii,
size_t* size_ptr,
size_t add_nr_bytes_to_buffer)
287 size_t l = size(file_name);
288 if (l == (
size_t)-1)
return 0;
289 char* buffer =
new char[l+ add_nr_bytes_to_buffer];
290 FILE* fp = ::fopen(file_name.c_str(), ascii ?
"r" :
"rb");
291 l = ::fread(buffer, 1, l, fp);
293 if (size_ptr) *size_ptr = l;
297bool write(
const std::string& filename,
const std::string& content,
bool ascii)
299 return write(filename, content.c_str(), content.length(), ascii);
302bool write(
const std::string& file_name,
const char* ptr,
size_t size,
bool ascii)
305 FILE* fp = ::fopen(file_name.c_str(), ascii ?
"w" :
"wb");
307 res = ::fwrite(ptr, 1, size, fp) == size;
313bool append(
const std::string& file_name,
const char* ptr,
size_t size,
bool ascii)
316 FILE* fp = ::fopen(file_name.c_str(), ascii ?
"a" :
"ab");
318 res = ::fwrite(ptr, 1, size, fp) == size;
324bool append(
const std::string& file_name_1,
const std::string& file_name_2,
bool ascii)
326 const size_t buffer_size = 10000000;
327 size_t N = cgv::utils::file::size(file_name_2, ascii);
328 std::vector<char> buffer(buffer_size, 0);
334 if (!cgv::utils::file::read(file_name_2, &buffer.front(), n, ascii, off))
336 if (!cgv::utils::file::append(file_name_1, &buffer.front(), n, ascii))
346 _finddata_t fileinfo;
358long long find_last_write_time(
const void* handle)
362 return fi->fileinfo.time_write;
364 struct stat statBuffer;
365 int result =stat(find_name(fi).c_str(),&statBuffer);
368 return statBuffer.st_ctime;
376long long get_last_write_time(
const std::string& file_path)
378 void* handle = find_first(file_path);
381 time = find_last_write_time(handle);
387void* find_first(
const std::string& filter)
389 FileInfo *fi =
new FileInfo;
391 fi->handle = _findfirst(filter.c_str(), &fi->fileinfo);
392 if (fi->handle == -1) {
398 fi->globResults=
new glob_t();
400 if(glob(filter.c_str(),GLOB_NOSORT,NULL,(fi->globResults))!=0)
402 delete fi->globResults;
413void* find_next(
void* handle)
415 FileInfo *fi = (FileInfo*) handle;
417 if (_findnext(fi->handle, &fi->fileinfo) == -1) {
424 if(fi->globResults->gl_pathc > fi->index)
426 delete fi->globResults;
433void find_close(
void* handle) {
436 FileInfo* fi = (FileInfo*)handle;
438 _findclose(fi->handle);
442 delete fi->globResults;
448std::string find_name(
void* handle)
450 FileInfo *fi = (FileInfo*) handle;
452 return std::string(fi->fileinfo.name);
454 if(fi->globResults->gl_pathc > fi->index)
455 return get_file_name(std::string(fi->globResults->gl_pathv[fi->index]));
457 return std::string(
"");
461bool find_read_only(
const void* handle)
464 FileInfo *fi = (FileInfo*) handle;
465 return fi->fileinfo.attrib & _A_RDONLY;
467 std::cerr <<
"Not Implemented" << std::endl;
473bool find_directory(
const void* handle)
475 FileInfo *fi = (FileInfo*) handle;
477 return (fi->fileinfo.attrib & _A_SUBDIR) != 0;
479 if(fi->globResults->gl_pathc > fi->index)
481 struct stat stat_buf;
482 stat(fi->globResults->gl_pathv[fi->index],&stat_buf);
483 return S_ISDIR(stat_buf.st_mode);
489bool find_system(
const void* handle)
492 FileInfo *fi = (FileInfo*) handle;
493 return (fi->fileinfo.attrib & _A_SYSTEM) != 0;
495 std::cerr <<
"Not Implemented" << std::endl;
500bool find_hidden(
const void* handle)
503 FileInfo *fi = (FileInfo*) handle;
504 return (fi->fileinfo.attrib & _A_HIDDEN) != 0;
506 std::cerr <<
"Not Implemented" << std::endl;
511bool find_archive(
const void* handle)
514 FileInfo *fi = (FileInfo*) handle;
515 return (fi->fileinfo.attrib & _A_ARCH) != 0;
517 std::cerr <<
"Not Implemented" << std::endl;
522bool find_normal(
const void* handle)
524 FileInfo *fi = (FileInfo*) handle;
526 return fi->fileinfo.attrib == _A_NORMAL;
528 if(fi->globResults->gl_pathc > fi->index)
530 struct stat stat_buf;
531 stat(fi->globResults->gl_pathv[fi->index],&stat_buf);
532 return S_ISREG(stat_buf.st_mode);
538size_t find_size(
void* handle)
540 FileInfo *fi = (FileInfo*) handle;
542 return fi->fileinfo.size;
544 if(fi->globResults->gl_pathc > fi->index)
546 struct stat stat_buf;
547 stat(fi->globResults->gl_pathv[fi->index],&stat_buf);
548 return stat_buf.st_size;
555std::string get_extension(
const std::string& file_path)
557 size_t pos = file_path.find_last_of(
'.');
558 if (pos == std::string::npos)
559 return std::string();
560 return file_path.substr(pos+1);
564std::string drop_extension(
const std::string& file_path)
568 std::string base_name = get_file_name(file_path);
569 size_t pos = base_name.find_last_of(
'.');
570 if (pos == std::string::npos)
573 return file_path.substr(0,file_path.find_last_of(
'.'));
577std::string get_file_name(
const std::string& file_path)
580 file_path.find_last_of(
'/'),
581 file_path.find_last_of(
'\\'),
582 file_path.find_last_of(
':')
584 size_t p = std::string::npos;
585 for (
unsigned int i=0; i<3; ++i)
586 if (pos[i] != std::string::npos)
587 if (p == std::string::npos || pos[i] > p)
589 if (p == std::string::npos)
591 return file_path.substr(p+1);
595std::string get_path(
const std::string& file_path)
598 file_path.find_last_of(
'/'),
599 file_path.find_last_of(
'\\'),
600 file_path.find_last_of(
':')
602 size_t p = std::string::npos;
603 for (
unsigned int i=0; i<3; ++i)
604 if (pos[i] != std::string::npos)
605 if (p == std::string::npos || pos[i] > p)
607 if (p == std::string::npos)
609 return file_path.substr(0,p);
614 if (c >=
'A' && c <=
'Z')
617 case (
char) 0xD6 :
return (
char) 0xF6;
618 case (
char) 0xC4 :
return (
char) 0xE4;
619 case (
char) 0xDC :
return (
char) 0xFC;
624bool is_letter(
char c)
627 return c >=
'a' && c <=
'z';
630bool is_relative_path(
const std::string& file_path)
632 if (file_path.size() == 0)
634 if (file_path[0] ==
'/')
636 if (file_path[0] ==
'\\')
638 if (file_path.size() == 1)
640 if (file_path[1] ==
':' && is_letter(file_path[0]))
646std::string clean_path(
const std::string& file_path)
648 std::string cleaned_path = file_path;
650 for (i=0; i<cleaned_path.size(); ++i) {
651 char c = cleaned_path[i];
655 else c = to_lower(c);
659 bool last_is_slash =
false;
660 unsigned n = (
unsigned int) cleaned_path.size();
662 for (
unsigned int i=0, j=0; i<n; ++i, ++j) {
664 cleaned_path[j] = cleaned_path[i];
665 if (cleaned_path[i] ==
'/')
671 last_is_slash =
true;
673 last_is_slash =
false;
675 if (cleaned_path[m-1] ==
'/')
677 return cleaned_path.substr(0,m);
681std::string platform_path(
const std::string& file_path)
683 std::string cleaned_path = clean_path(file_path);
685 for (i = 0; i < cleaned_path.size(); ++i) {
686 char c = cleaned_path[i];
700bool shorten_path(std::string& file_path,
const std::string& prefix_path)
702 std::string cleaned_prefix_path = clean_path(prefix_path);
703 std::string cleaned_file_path = clean_path(file_path);
704 if (cleaned_file_path.size() < cleaned_prefix_path.size()) {
705 file_path = cleaned_file_path;
708 if (cleaned_file_path.substr(0,cleaned_prefix_path.size()) != cleaned_prefix_path) {
709 file_path = cleaned_file_path;
712 if (cleaned_file_path.size() == cleaned_prefix_path.size()) {
716 unsigned int o = (
unsigned int) cleaned_prefix_path.size();
717 if (cleaned_file_path[o] ==
'/')
719 file_path = cleaned_file_path.substr(o);
725bool read_string_bin(std::string& s, FILE* fp)
733 return fread(&s[0],
sizeof(
char), length, fp) == length;
736bool write_string_bin(
const std::string& s, FILE* fp)
743 return fwrite(&s[0],
sizeof(
char), length, fp) == length;
complete implementation of method actions that only call one method when entering a node
unsigned short uint16_type
this type provides an 16 bit unsigned integer type