--- parser3/src/main/pa_dir.C 2004/02/11 15:33:15 1.19 +++ parser3/src/main/pa_dir.C 2017/02/07 22:00:42 1.29 @@ -1,60 +1,102 @@ /** @file Parser: directory scanning for different OS-es. - Copyright (c) 2000,2001-2004 ArtLebedev Group (http://www.artlebedev.com) + Copyright (c) 2000-2017 Art. Lebedev Studio (http://www.artlebedev.com) Author: Alexandr Petrosian (http://paf.design.ru) */ -static const char * const IDENT_DIR_C="$Date: 2004/02/11 15:33:15 $"; - #include "pa_common.h" #include "pa_dir.h" +#include "pa_request.h" +#include "pa_convert_utf.h" + +volatile const char * IDENT_PA_DIR_C="$Id: pa_dir.C,v 1.29 2017/02/07 22:00:42 moko Exp $" IDENT_PA_DIR_H; -#ifdef WIN32 +#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-1); _ffblk->filePath[MAXPATH-1]=0; + _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; + 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-1); _ffblk->ff_name[maxsize]=0; - - char fileSpec[MAXPATH]; - snprintf(fileSpec, MAXPATH, "%s/%s", - _ffblk->filePath, - _ffblk->ff_name); - - struct stat st; + strncpy(_ffblk->ff_name, entry->d_name, sizeof(_ffblk->ff_name)-1); + _ffblk->ff_name[sizeof(_ffblk->ff_name)-1]=0; - _ffblk->ff_attrib = - stat(fileSpec, &st) < 0 ? 0/*would fail later*/ : st.st_mode; +#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; } } @@ -63,4 +105,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