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: