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