Annotation of parser3/src/main/pa_dir.C, revision 1.39
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.28 moko 11: #include "pa_request.h"
12: #include "pa_convert_utf.h"
1.1 paf 13:
1.39 ! moko 14: volatile const char * IDENT_PA_DIR_C="$Id: pa_dir.C,v 1.38 2026/09/27 17:21:42 moko Exp $" IDENT_PA_DIR_H;
1.21 moko 15:
1.24 moko 16: #ifdef _MSC_VER
1.1 paf 17:
1.28 moko 18: const UTF16* pa_utf16_encode(const char* in, Charset& source_charset);
19: const char* pa_utf16_decode(const UTF16* in, Charset& asked_charset);
20:
1.22 moko 21: #define TICKS_PER_SECOND 10000000ULL
22: #define EPOCH_DIFFERENCE 11644473600ULL
1.28 moko 23:
1.22 moko 24: time_t filetime_to_timet(FILETIME const& ft){
25: ULARGE_INTEGER ull;
26: ull.LowPart = ft.dwLowDateTime;
27: ull.HighPart = ft.dwHighDateTime;
28: long long secs=(ull.QuadPart / TICKS_PER_SECOND - EPOCH_DIFFERENCE);
29: time_t t =(time_t)secs;
30: return (secs == (long long)t) ? t : 0;
31: }
32:
1.16 paf 33: bool findfirst(const char* _pathname, struct ffblk *_ffblk, int /*_attrib*/) {
1.1 paf 34: char mask[MAXPATH];
35: snprintf(mask, MAXPATH, "%s/*.*", _pathname);
36:
1.28 moko 37: const UTF16* utf16mask=pa_utf16_encode(mask, pa_thread_request().charsets.source());
38:
39: _ffblk->handle=FindFirstFileW((const wchar_t *)utf16mask, &_ffblk->stat);
1.1 paf 40: return _ffblk->handle==INVALID_HANDLE_VALUE;
41: }
42:
43: bool findnext(struct ffblk *_ffblk) {
1.28 moko 44: return !FindNextFileW(_ffblk->handle, &_ffblk->stat);
1.22 moko 45: }
1.1 paf 46:
47: void findclose(struct ffblk *_ffblk) {
48: FindClose(_ffblk->handle);
49: }
50:
1.28 moko 51: const char *ffblk::name() {
52: return pa_utf16_decode((const UTF16*)stat.cFileName, pa_thread_request().charsets.source());
53: }
54:
1.25 moko 55: bool ffblk::is_dir(bool) {
1.28 moko 56: return (stat.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0;
1.22 moko 57: }
58:
59: double ffblk::size() {
60: ULARGE_INTEGER ull;
1.28 moko 61: ull.LowPart = stat.nFileSizeLow;
62: ull.HighPart = stat.nFileSizeHigh;
1.22 moko 63: return (double)ull.QuadPart;
64: }
65:
66: time_t ffblk::c_timestamp() {
1.28 moko 67: return filetime_to_timet(stat.ftCreationTime);
1.22 moko 68: }
69:
70: time_t ffblk::m_timestamp() {
1.28 moko 71: return filetime_to_timet(stat.ftLastWriteTime);
1.22 moko 72: }
73:
74: time_t ffblk::a_timestamp() {
1.28 moko 75: return filetime_to_timet(stat.ftLastAccessTime);
1.22 moko 76: }
77:
1.1 paf 78: #else
79:
1.18 paf 80: bool findfirst(const char* _pathname, struct ffblk *_ffblk, int /*_attrib*/) {
1.23 moko 81: _ffblk->filePath=_pathname;
1.1 paf 82: if(!(_ffblk->dir=opendir(_ffblk->filePath)))
1.28 moko 83: return true;
1.1 paf 84:
85: return findnext(_ffblk);
86: }
87:
88: bool findnext(struct ffblk *_ffblk) {
1.28 moko 89: while(true) {
90: struct dirent *entry=readdir(_ffblk->dir);
91: if(!entry)
92: return true;
1.1 paf 93:
1.31 moko 94: pa_strncpy(_ffblk->ff_name, entry->d_name, sizeof(_ffblk->ff_name));
95:
1.22 moko 96: #ifdef HAVE_STRUCT_DIRENT_D_TYPE
97: // http://www.gnu.org/software/libc/manual/html_node/Directory-Entries.html
98: _ffblk->_d_type=entry->d_type;
99: #endif
1.1 paf 100: return false;
101: }
102: }
103:
104: void findclose(struct ffblk *_ffblk) {
105: closedir(_ffblk->dir);
106: }
107:
1.22 moko 108: void ffblk::stat_file() {
109: char fileSpec[MAXPATH];
110: snprintf(fileSpec, MAXPATH, "%s/%s", filePath, ff_name);
111:
1.27 moko 112: if(pa_stat(fileSpec, &_st) != 0) {
1.22 moko 113: memset(&_st,0,sizeof(_st));
114: }
115: }
116:
1.25 moko 117: bool ffblk::is_dir(bool stat) {
1.22 moko 118: #ifdef HAVE_STRUCT_DIRENT_D_TYPE
1.25 moko 119: if(!stat && _d_type != DT_UNKNOWN)
120: return _d_type == DT_DIR;
121: #endif
122: stat_file();
1.22 moko 123: return S_ISDIR(_st.st_mode) != 0;
124: }
125:
126: double ffblk::size() {
127: return (double)_st.st_size;
128: }
129:
130: time_t ffblk::c_timestamp() {
131: return _st.st_ctime;
132: }
133:
134: time_t ffblk::m_timestamp() {
135: return _st.st_mtime;
136: }
137:
138: time_t ffblk::a_timestamp() {
139: return _st.st_atime;
140: }
141:
1.1 paf 142: #endif
E-mail: