| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578 |
- // File: crn_file_utils.cpp
- // See Copyright Notice and license at the end of inc/crnlib.h
- #include "crn_core.h"
- #include "crn_file_utils.h"
- #include "crn_strutils.h"
- #if CRNLIB_USE_WIN32_API
- #include "crn_winhdr.h"
- #endif
- #ifdef WIN32
- #include <direct.h>
- #endif
- #ifdef __GNUC__
- #include <sys/stat.h>
- #include <sys/stat.h>
- #include <libgen.h>
- #endif
- namespace crnlib
- {
- #if CRNLIB_USE_WIN32_API
- bool file_utils::is_read_only(const char* pFilename)
- {
- uint32 dst_file_attribs = GetFileAttributesA(pFilename);
- if (dst_file_attribs == INVALID_FILE_ATTRIBUTES)
- return false;
- if (dst_file_attribs & FILE_ATTRIBUTE_READONLY)
- return true;
- return false;
- }
- bool file_utils::disable_read_only(const char* pFilename)
- {
- uint32 dst_file_attribs = GetFileAttributesA(pFilename);
- if (dst_file_attribs == INVALID_FILE_ATTRIBUTES)
- return false;
- if (dst_file_attribs & FILE_ATTRIBUTE_READONLY)
- {
- dst_file_attribs &= ~FILE_ATTRIBUTE_READONLY;
- if (SetFileAttributesA(pFilename, dst_file_attribs))
- return true;
- }
- return false;
- }
- bool file_utils::is_older_than(const char* pSrcFilename, const char* pDstFilename)
- {
- WIN32_FILE_ATTRIBUTE_DATA src_file_attribs;
- const BOOL src_file_exists = GetFileAttributesExA(pSrcFilename, GetFileExInfoStandard, &src_file_attribs);
- WIN32_FILE_ATTRIBUTE_DATA dst_file_attribs;
- const BOOL dest_file_exists = GetFileAttributesExA(pDstFilename, GetFileExInfoStandard, &dst_file_attribs);
- if ((dest_file_exists) && (src_file_exists))
- {
- LONG timeComp = CompareFileTime(&src_file_attribs.ftLastWriteTime, &dst_file_attribs.ftLastWriteTime);
- if (timeComp < 0)
- return true;
- }
- return false;
- }
- bool file_utils::does_file_exist(const char* pFilename)
- {
- const DWORD fullAttributes = GetFileAttributesA(pFilename);
- if (fullAttributes == INVALID_FILE_ATTRIBUTES)
- return false;
- if (fullAttributes & FILE_ATTRIBUTE_DIRECTORY)
- return false;
- return true;
- }
- bool file_utils::does_dir_exist(const char* pDir)
- {
- //-- Get the file attributes.
- DWORD fullAttributes = GetFileAttributesA(pDir);
- if (fullAttributes == INVALID_FILE_ATTRIBUTES)
- return false;
- if (fullAttributes & FILE_ATTRIBUTE_DIRECTORY)
- return true;
- return false;
- }
- bool file_utils::get_file_size(const char* pFilename, uint64& file_size)
- {
- file_size = 0;
- WIN32_FILE_ATTRIBUTE_DATA attr;
- if (0 == GetFileAttributesExA(pFilename, GetFileExInfoStandard, &attr))
- return false;
- if (attr.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
- return false;
- file_size = static_cast<uint64>(attr.nFileSizeLow) | (static_cast<uint64>(attr.nFileSizeHigh) << 32U);
- return true;
- }
- #elif defined( __GNUC__ )
- bool file_utils::is_read_only(const char* pFilename)
- {
- pFilename;
- // TODO
- return false;
- }
- bool file_utils::disable_read_only(const char* pFilename)
- {
- pFilename;
- // TODO
- return false;
- }
- bool file_utils::is_older_than(const char *pSrcFilename, const char* pDstFilename)
- {
- pSrcFilename, pDstFilename;
- // TODO
- return false;
- }
- bool file_utils::does_file_exist(const char* pFilename)
- {
- struct stat stat_buf;
- int result = stat(pFilename, &stat_buf);
- if (result)
- return false;
- if (S_ISREG(stat_buf.st_mode))
- return true;
- return false;
- }
- bool file_utils::does_dir_exist(const char* pDir)
- {
- struct stat stat_buf;
- int result = stat(pDir, &stat_buf);
- if (result)
- return false;
- if (S_ISDIR(stat_buf.st_mode) || S_ISLNK(stat_buf.st_mode))
- return true;
- return false;
- }
- bool file_utils::get_file_size(const char* pFilename, uint64& file_size)
- {
- file_size = 0;
- struct stat stat_buf;
- int result = stat(pFilename, &stat_buf);
- if (result)
- return false;
- if (!S_ISREG(stat_buf.st_mode))
- return false;
- file_size = stat_buf.st_size;
- return true;
- }
- #else
- bool file_utils::is_read_only(const char* pFilename)
- {
- return false;
- }
- bool file_utils::disable_read_only(const char* pFilename)
- {
- pFilename;
- // TODO
- return false;
- }
- bool file_utils::is_older_than(const char *pSrcFilename, const char* pDstFilename)
- {
- return false;
- }
- bool file_utils::does_file_exist(const char* pFilename)
- {
- FILE* pFile;
- crn_fopen(&pFile, pFilename, "rb");
- if (!pFile)
- return false;
- fclose(pFile);
- return true;
- }
- bool file_utils::does_dir_exist(const char* pDir)
- {
- return false;
- }
- bool file_utils::get_file_size(const char* pFilename, uint64& file_size)
- {
- FILE* pFile;
- crn_fopen(&pFile, pFilename, "rb");
- if (!pFile)
- return false;
- crn_fseek(pFile, 0, SEEK_END);
- file_size = crn_ftell(pFile);
- fclose(pFile);
- return true;
- }
- #endif
- bool file_utils::get_file_size(const char* pFilename, uint32& file_size)
- {
- uint64 file_size64;
- if (!get_file_size(pFilename, file_size64))
- {
- file_size = 0;
- return false;
- }
- if (file_size64 > cUINT32_MAX)
- file_size64 = cUINT32_MAX;
- file_size = static_cast<uint32>(file_size64);
- return true;
- }
- bool file_utils::is_path_separator(char c)
- {
- #ifdef WIN32
- return (c == '/') || (c == '\\');
- #else
- return (c == '/');
- #endif
- }
- bool file_utils::is_path_or_drive_separator(char c)
- {
- #ifdef WIN32
- return (c == '/') || (c == '\\') || (c == ':');
- #else
- return (c == '/');
- #endif
- }
- bool file_utils::is_drive_separator(char c)
- {
- #ifdef WIN32
- return (c == ':');
- #else
- c;
- return false;
- #endif
- }
- bool file_utils::split_path(const char* p, dynamic_string* pDrive, dynamic_string* pDir, dynamic_string* pFilename, dynamic_string* pExt)
- {
- CRNLIB_ASSERT(p);
- #ifdef WIN32
- char drive_buf[_MAX_DRIVE];
- char dir_buf[_MAX_DIR];
- char fname_buf[_MAX_FNAME];
- char ext_buf[_MAX_EXT];
- #ifdef _MSC_VER
- // Compiling with MSVC
- errno_t error = _splitpath_s(p,
- pDrive ? drive_buf : NULL, pDrive ? _MAX_DRIVE : 0,
- pDir ? dir_buf : NULL, pDir ? _MAX_DIR : 0,
- pFilename ? fname_buf : NULL, pFilename ? _MAX_FNAME : 0,
- pExt ? ext_buf : NULL, pExt ? _MAX_EXT : 0);
- if (error != 0)
- return false;
- #else
- // Compiling with MinGW
- _splitpath(p,
- pDrive ? drive_buf : NULL,
- pDir ? dir_buf : NULL,
- pFilename ? fname_buf : NULL,
- pExt ? ext_buf : NULL);
- #endif
- if (pDrive) *pDrive = drive_buf;
- if (pDir) *pDir = dir_buf;
- if (pFilename) *pFilename = fname_buf;
- if (pExt) *pExt = ext_buf;
- #else
- char dirtmp[1024];
- char nametmp[1024];
- strcpy_safe(dirtmp, sizeof(dirtmp), p);
- strcpy_safe(nametmp, sizeof(nametmp), p);
- if (pDrive) pDrive->clear();
- const char *pDirName = dirname(dirtmp);
- if (!pDirName)
- return false;
- if (pDir)
- {
- pDir->set(pDirName);
- if ((!pDir->is_empty()) && (pDir->back() != '/'))
- pDir->append_char('/');
- }
- const char *pBaseName = basename(nametmp);
- if (!pBaseName)
- return false;
- if (pFilename)
- {
- pFilename->set(pBaseName);
- remove_extension(*pFilename);
- }
- if (pExt)
- {
- pExt->set(pBaseName);
- get_extension(*pExt);
- *pExt = "." + *pExt;
- }
- #endif // #ifdef WIN32
- return true;
- }
- bool file_utils::split_path(const char* p, dynamic_string& path, dynamic_string& filename)
- {
- dynamic_string temp_drive, temp_path, temp_ext;
- if (!split_path(p, &temp_drive, &temp_path, &filename, &temp_ext))
- return false;
- filename += temp_ext;
- combine_path(path, temp_drive.get_ptr(), temp_path.get_ptr());
- return true;
- }
- bool file_utils::get_pathname(const char* p, dynamic_string& path)
- {
- dynamic_string temp_drive, temp_path;
- if (!split_path(p, &temp_drive, &temp_path, NULL, NULL))
- return false;
- combine_path(path, temp_drive.get_ptr(), temp_path.get_ptr());
- return true;
- }
- bool file_utils::get_filename(const char* p, dynamic_string& filename)
- {
- dynamic_string temp_ext;
- if (!split_path(p, NULL, NULL, &filename, &temp_ext))
- return false;
- filename += temp_ext;
- return true;
- }
- void file_utils::combine_path(dynamic_string& dst, const char* pA, const char* pB)
- {
- dynamic_string temp(pA);
- if ((!temp.is_empty()) && (!is_path_separator(pB[0])))
- {
- char c = temp[temp.get_len() - 1];
- if (!is_path_separator(c))
- temp.append_char(CRNLIB_PATH_SEPERATOR_CHAR);
- }
- temp += pB;
- dst.swap(temp);
- }
- void file_utils::combine_path(dynamic_string& dst, const char* pA, const char* pB, const char* pC)
- {
- combine_path(dst, pA, pB);
- combine_path(dst, dst.get_ptr(), pC);
- }
- bool file_utils::full_path(dynamic_string& path)
- {
- #ifdef WIN32
- char buf[1024];
- char* p = _fullpath(buf, path.get_ptr(), sizeof(buf));
- if (!p)
- return false;
- #else
- char buf[PATH_MAX];
- char* p;
- dynamic_string pn, fn;
- split_path(path.get_ptr(), pn, fn);
- if ((fn == ".") || (fn == ".."))
- {
- p = realpath(path.get_ptr(), buf);
- if (!p)
- return false;
- path.set(buf);
- }
- else
- {
- if (pn.is_empty())
- pn = "./";
- p = realpath(pn.get_ptr(), buf);
- if (!p)
- return false;
- combine_path(path, buf, fn.get_ptr());
- }
- #endif
- return true;
- }
- bool file_utils::get_extension(dynamic_string& filename)
- {
- int sep = -1;
- #ifdef WIN32
- sep = filename.find_right('\\');
- #endif
- if (sep < 0)
- sep = filename.find_right('/');
- int dot = filename.find_right('.');
- if (dot < sep)
- {
- filename.clear();
- return false;
- }
- filename.right(dot + 1);
- return true;
- }
- bool file_utils::remove_extension(dynamic_string& filename)
- {
- int sep = -1;
- #ifdef WIN32
- sep = filename.find_right('\\');
- #endif
- if (sep < 0)
- sep = filename.find_right('/');
- int dot = filename.find_right('.');
- if (dot < sep)
- return false;
- filename.left(dot);
- return true;
- }
- bool file_utils::create_path(const dynamic_string& fullpath)
- {
- bool got_unc = false; got_unc;
- dynamic_string cur_path;
- const int l = fullpath.get_len();
- int n = 0;
- while (n < l)
- {
- const char c = fullpath.get_ptr()[n];
- const bool sep = is_path_separator(c);
- const bool back_sep = is_path_separator(cur_path.back());
- const bool is_last_char = (n == (l - 1));
- if ( ((sep) && (!back_sep)) || (is_last_char) )
- {
- if ((is_last_char) && (!sep))
- cur_path.append_char(c);
- bool valid = !cur_path.is_empty();
- #ifdef WIN32
- // reject obvious stuff (drives, beginning of UNC paths):
- // c:\b\cool
- // \\machine\blah
- // \cool\blah
- if ((cur_path.get_len() == 2) && (cur_path[1] == ':'))
- valid = false;
- else if ((cur_path.get_len() >= 2) && (cur_path[0] == '\\') && (cur_path[1] == '\\'))
- {
- if (!got_unc)
- valid = false;
- got_unc = true;
- }
- else if (cur_path == "\\")
- valid = false;
- #endif
- if (cur_path == "/")
- valid = false;
- if ((valid) && (cur_path.get_len()))
- {
- #ifdef WIN32
- _mkdir(cur_path.get_ptr());
- #else
- mkdir(cur_path.get_ptr(), S_IRWXU | S_IRWXG | S_IRWXO );
- #endif
- }
- }
- cur_path.append_char(c);
- n++;
- }
- return true;
- }
- void file_utils::trim_trailing_seperator(dynamic_string& path)
- {
- if ((path.get_len()) && (is_path_separator(path.back())))
- path.truncate(path.get_len() - 1);
- }
- // See http://www.codeproject.com/KB/string/wildcmp.aspx
- int file_utils::wildcmp(const char* pWild, const char* pString)
- {
- const char* cp = NULL, *mp = NULL;
- while ((*pString) && (*pWild != '*'))
- {
- if ((*pWild != *pString) && (*pWild != '?'))
- return 0;
- pWild++;
- pString++;
- }
- // Either *pString=='\0' or *pWild='*' here.
- while (*pString)
- {
- if (*pWild == '*')
- {
- if (!*++pWild)
- return 1;
- mp = pWild;
- cp = pString+1;
- }
- else if ((*pWild == *pString) || (*pWild == '?'))
- {
- pWild++;
- pString++;
- }
- else
- {
- pWild = mp;
- pString = cp++;
- }
- }
- while (*pWild == '*')
- pWild++;
- return !*pWild;
- }
- bool file_utils::write_buf_to_file(const char* pPath, const void* pData, size_t data_size)
- {
- FILE *pFile = NULL;
- #ifdef _MSC_VER
- // Compiling with MSVC
- if (fopen_s(&pFile, pPath, "wb"))
- return false;
- #else
- pFile = fopen(pPath, "wb");
- #endif
- if (!pFile)
- return false;
- bool success = fwrite(pData, 1, data_size, pFile) == data_size;
- fclose(pFile);
- return success;
- }
- } // namespace crnlib
|