Annotation of parser3/src/main/pa_dir.C, revision 1.42

1.1       paf         1: /** @file
                      2:        Parser: directory scanning for different OS-es.
                      3: 
1.34      moko        4:        Copyright (c) 2000-2026 Art. Lebedev Studio (https://www.artlebedev.com)
1.32      moko        5:        Authors: Konstantin Morshnev <moko@design.ru>, Alexandr Petrosian <paf@design.ru>
1.12      paf         6: */
1.1       paf         7: 
1.9       paf         8: #include "pa_common.h"
1.38      moko        9: #include "pa_file.h"
1.39      moko       10: #include "pa_dir.h"
1.40      moko       11: #include "pa_os.h"
1.28      moko       12: #include "pa_request.h"
                     13: #include "pa_convert_utf.h"
1.1       paf        14: 
1.42    ! moko       15: volatile const char * IDENT_PA_DIR_C="$Id: pa_dir.C,v 1.41 2026/10/11 17:06:44 moko Exp $" IDENT_PA_DIR_H;
1.21      moko       16: 
1.24      moko       17: #ifdef _MSC_VER
1.1       paf        18: 
1.28      moko       19: const UTF16* pa_utf16_encode(const char* in, Charset& source_charset);
                     20: const char* pa_utf16_decode(const UTF16* in, Charset& asked_charset);
                     21: 
1.22      moko       22: #define TICKS_PER_SECOND 10000000ULL
                     23: #define EPOCH_DIFFERENCE 11644473600ULL
1.28      moko       24: 
1.22      moko       25: time_t filetime_to_timet(FILETIME const& ft){
                     26:        ULARGE_INTEGER ull;
                     27:        ull.LowPart = ft.dwLowDateTime;
                     28:        ull.HighPart = ft.dwHighDateTime;
                     29:        long long secs=(ull.QuadPart / TICKS_PER_SECOND - EPOCH_DIFFERENCE);
                     30:        time_t t =(time_t)secs;
                     31:        return (secs == (long long)t) ? t : 0;
                     32: }
                     33: 
1.16      paf        34: bool findfirst(const char* _pathname, struct ffblk *_ffblk, int /*_attrib*/) {
1.1       paf        35:        char mask[MAXPATH];
1.42    ! moko       36:        pa_snprintf(mask, MAXPATH, "%s/*.*", _pathname);
1.1       paf        37: 
1.28      moko       38:        const UTF16* utf16mask=pa_utf16_encode(mask, pa_thread_request().charsets.source());
1.41      moko       39:        if(!utf16mask) { // not UTF-8, there can't be such a directory
                     40:                errno=ENOENT;
                     41:                return false;
                     42:        }
1.28      moko       43: 
                     44:        _ffblk->handle=FindFirstFileW((const wchar_t *)utf16mask, &_ffblk->stat);
1.40      moko       45:        return !pa_set_errno(_ffblk->handle!=INVALID_HANDLE_VALUE); // errno as opendir sets it
1.1       paf        46: }
                     47: 
                     48: bool findnext(struct ffblk *_ffblk) {
1.28      moko       49:        return !FindNextFileW(_ffblk->handle, &_ffblk->stat);
1.22      moko       50: }
1.1       paf        51: 
                     52: void findclose(struct ffblk *_ffblk) {
                     53:        FindClose(_ffblk->handle);
                     54: }
                     55: 
1.28      moko       56: const char *ffblk::name() {
                     57:        return pa_utf16_decode((const UTF16*)stat.cFileName, pa_thread_request().charsets.source());
                     58: }
                     59: 
1.25      moko       60: bool ffblk::is_dir(bool) {
1.28      moko       61:        return (stat.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0;
1.22      moko       62: }
                     63: 
                     64: double ffblk::size() {
                     65:        ULARGE_INTEGER ull;
1.28      moko       66:        ull.LowPart = stat.nFileSizeLow;
                     67:        ull.HighPart = stat.nFileSizeHigh;
1.22      moko       68:        return (double)ull.QuadPart;
                     69: }
                     70: 
                     71: time_t ffblk::c_timestamp() {
1.28      moko       72:        return filetime_to_timet(stat.ftCreationTime);
1.22      moko       73: }
                     74: 
                     75: time_t ffblk::m_timestamp() {
1.28      moko       76:        return filetime_to_timet(stat.ftLastWriteTime);
1.22      moko       77: }
                     78: 
                     79: time_t ffblk::a_timestamp() {
1.28      moko       80:        return filetime_to_timet(stat.ftLastAccessTime);
1.22      moko       81: }
                     82: 
1.1       paf        83: #else
                     84: 
1.18      paf        85: bool findfirst(const char* _pathname, struct ffblk *_ffblk, int /*_attrib*/) {
1.23      moko       86:        _ffblk->filePath=_pathname;
1.1       paf        87:        if(!(_ffblk->dir=opendir(_ffblk->filePath)))
1.28      moko       88:                return true;
1.1       paf        89: 
                     90:        return findnext(_ffblk);
                     91: }
                     92: 
                     93: bool findnext(struct ffblk *_ffblk) {
1.28      moko       94:        while(true) {
                     95:                struct dirent *entry=readdir(_ffblk->dir);
                     96:                if(!entry)
                     97:                        return true;
1.1       paf        98: 
1.31      moko       99:                pa_strncpy(_ffblk->ff_name, entry->d_name, sizeof(_ffblk->ff_name));
                    100: 
1.22      moko      101: #ifdef HAVE_STRUCT_DIRENT_D_TYPE
                    102:                // http://www.gnu.org/software/libc/manual/html_node/Directory-Entries.html
                    103:                _ffblk->_d_type=entry->d_type;
                    104: #endif
1.1       paf       105:                return false;
                    106:     }
                    107: }
                    108: 
                    109: void findclose(struct ffblk *_ffblk) {
                    110:        closedir(_ffblk->dir);
                    111: }
                    112: 
1.22      moko      113: void ffblk::stat_file() {
                    114:        char fileSpec[MAXPATH];
1.42    ! moko      115:        pa_snprintf(fileSpec, MAXPATH, "%s/%s", filePath, ff_name);
1.22      moko      116:        
1.27      moko      117:        if(pa_stat(fileSpec, &_st) != 0) {
1.22      moko      118:                memset(&_st,0,sizeof(_st));
                    119:        }
                    120: }
                    121: 
1.25      moko      122: bool ffblk::is_dir(bool stat) {
1.22      moko      123: #ifdef HAVE_STRUCT_DIRENT_D_TYPE
1.25      moko      124:        if(!stat && _d_type != DT_UNKNOWN)
                    125:                return _d_type == DT_DIR;
                    126: #endif
                    127:        stat_file();
1.22      moko      128:        return S_ISDIR(_st.st_mode) != 0;
                    129: }
                    130: 
                    131: double ffblk::size() {
                    132:        return (double)_st.st_size;
                    133: }
                    134: 
                    135: time_t ffblk::c_timestamp() {
                    136:        return _st.st_ctime;
                    137: }
                    138: 
                    139: time_t ffblk::m_timestamp() {
                    140:        return _st.st_mtime;
                    141: }
                    142: 
                    143: time_t ffblk::a_timestamp() {
                    144:        return _st.st_atime;
                    145: }
                    146: 
1.1       paf       147: #endif

E-mail: