--- parser3/src/main/pa_dir.C 2001/06/28 07:44:17 1.5 +++ parser3/src/main/pa_dir.C 2026/04/25 13:38:46 1.34 @@ -1,61 +1,101 @@ /** @file Parser: directory scanning for different OS-es. - Copyright (c) 2000,2001 ArtLebedev Group (http://www.artlebedev.com) - - Author: Alexander Petrosyan (http://design.ru/paf) + Copyright (c) 2000-2026 Art. Lebedev Studio (https://www.artlebedev.com) + Authors: Konstantin Morshnev , Alexandr Petrosian */ -static const char *RCSId="$Id: pa_dir.C,v 1.5 2001/06/28 07:44:17 parser Exp $"; -#include "pa_dir.h" #include "pa_common.h" +#include "pa_dir.h" +#include "pa_request.h" +#include "pa_convert_utf.h" -#ifdef WIN32 +volatile const char * IDENT_PA_DIR_C="$Id: pa_dir.C,v 1.34 2026/04/25 13:38:46 moko Exp $" IDENT_PA_DIR_H; -bool findfirst(const char *_pathname, struct ffblk *_ffblk, int _attrib) { +#ifdef _MSC_VER + +const UTF16* pa_utf16_encode(const char* in, Charset& source_charset); +const char* pa_utf16_decode(const UTF16* in, Charset& asked_charset); + +#define TICKS_PER_SECOND 10000000ULL +#define EPOCH_DIFFERENCE 11644473600ULL + +time_t filetime_to_timet(FILETIME const& ft){ + ULARGE_INTEGER ull; + ull.LowPart = ft.dwLowDateTime; + ull.HighPart = ft.dwHighDateTime; + long long secs=(ull.QuadPart / TICKS_PER_SECOND - EPOCH_DIFFERENCE); + time_t t =(time_t)secs; + return (secs == (long long)t) ? t : 0; +} + +bool findfirst(const char* _pathname, struct ffblk *_ffblk, int /*_attrib*/) { char mask[MAXPATH]; snprintf(mask, MAXPATH, "%s/*.*", _pathname); - _ffblk->handle=FindFirstFile(mask, (_WIN32_FIND_DATAA *)_ffblk); + const UTF16* utf16mask=pa_utf16_encode(mask, pa_thread_request().charsets.source()); + + _ffblk->handle=FindFirstFileW((const wchar_t *)utf16mask, &_ffblk->stat); return _ffblk->handle==INVALID_HANDLE_VALUE; } bool findnext(struct ffblk *_ffblk) { - return !FindNextFile(_ffblk->handle, (_WIN32_FIND_DATAA *)_ffblk);} + return !FindNextFileW(_ffblk->handle, &_ffblk->stat); +} void findclose(struct ffblk *_ffblk) { FindClose(_ffblk->handle); } +const char *ffblk::name() { + return pa_utf16_decode((const UTF16*)stat.cFileName, pa_thread_request().charsets.source()); +} + +bool ffblk::is_dir(bool) { + return (stat.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0; +} + +double ffblk::size() { + ULARGE_INTEGER ull; + ull.LowPart = stat.nFileSizeLow; + ull.HighPart = stat.nFileSizeHigh; + return (double)ull.QuadPart; +} + +time_t ffblk::c_timestamp() { + return filetime_to_timet(stat.ftCreationTime); +} + +time_t ffblk::m_timestamp() { + return filetime_to_timet(stat.ftLastWriteTime); +} + +time_t ffblk::a_timestamp() { + return filetime_to_timet(stat.ftLastAccessTime); +} + #else -bool findfirst(const char *_pathname, struct ffblk *_ffblk, int _attrib) { - strncpy(_ffblk->filePath, _pathname, MAXPATH); +bool findfirst(const char* _pathname, struct ffblk *_ffblk, int /*_attrib*/) { + _ffblk->filePath=_pathname; if(!(_ffblk->dir=opendir(_ffblk->filePath))) - return true; + return true; return findnext(_ffblk); } bool findnext(struct ffblk *_ffblk) { - while(true) { - struct dirent *entry=readdir(_ffblk->dir); - if(!entry) - return true; - - int maxsize=sizeof(_ffblk->ff_name)-1; - strncpy(_ffblk->ff_name, entry->d_name, maxsize); - _ffblk->ff_name[maxsize]=0; - - char fileSpec[MAXPATH]; - snprintf(fileSpec, MAXPATH, "%s/%s", - _ffblk->filePath, - _ffblk->ff_name); - - struct stat st; - - _ffblk->ff_attrib = - stat(fileSpec, &st) < 0 ? 0/*would fail later*/ : st.st_mode; + while(true) { + struct dirent *entry=readdir(_ffblk->dir); + if(!entry) + return true; + + pa_strncpy(_ffblk->ff_name, entry->d_name, sizeof(_ffblk->ff_name)); + +#ifdef HAVE_STRUCT_DIRENT_D_TYPE + // http://www.gnu.org/software/libc/manual/html_node/Directory-Entries.html + _ffblk->_d_type=entry->d_type; +#endif return false; } } @@ -64,4 +104,38 @@ void findclose(struct ffblk *_ffblk) { closedir(_ffblk->dir); } +void ffblk::stat_file() { + char fileSpec[MAXPATH]; + snprintf(fileSpec, MAXPATH, "%s/%s", filePath, ff_name); + + if(pa_stat(fileSpec, &_st) != 0) { + memset(&_st,0,sizeof(_st)); + } +} + +bool ffblk::is_dir(bool stat) { +#ifdef HAVE_STRUCT_DIRENT_D_TYPE + if(!stat && _d_type != DT_UNKNOWN) + return _d_type == DT_DIR; +#endif + stat_file(); + return S_ISDIR(_st.st_mode) != 0; +} + +double ffblk::size() { + return (double)_st.st_size; +} + +time_t ffblk::c_timestamp() { + return _st.st_ctime; +} + +time_t ffblk::m_timestamp() { + return _st.st_mtime; +} + +time_t ffblk::a_timestamp() { + return _st.st_atime; +} + #endif