%% options copyright owner = Dirk Krause copyright year = 2015-xxxx license = bsd %% header /** @file Open stream to read a file. */ #ifndef DK4CONF_H_INCLUDED #include "dk4conf.h" #endif #ifndef DK4TYPES_H_INCLUDED #include "dk4types.h" #endif #ifndef DK4ERROR_H_INCLUDED #include "dk4error.h" #endif #ifndef DK4STRM_H_INCLUDED #include "dk4strm.h" #endif #ifndef DK4STRMF_H_INCLUDED #include "dk4strmf.h" #endif #ifndef DK4STRMG_H_INCLUDED #include "dk4strmg.h" #endif #ifndef DK4STRMB_H_INCLUDED #include "dk4strmb.h" #endif #ifdef __cplusplus extern "C" { #endif /** Open a stream to read a file. CRT on Windows: Optional, disabling CRT reduces functionality by disabling the gzip and bzip2 compression libraries. @param filename File name of file to read. @param erp Error report, may be NULL. @return Pointer to stream on success, NULL on error. DK4_E_INVALID_ARGUMENTS if filename is NULL, DK4_E_MATH_OVERFLOW if ibs or obs is too large, DK4_E_MEMORY_ALLOCATION_FAILED if allocation of input or output buffer failed. */ dk4_stream_t * dk4stream_open_file_reader(const dkChar *filename, dk4_er_t *erp); #ifdef __cplusplus } #endif %% module #include "dk4conf.h" #if DK4_ON_WINDOWS && DK4_WIN_DENY_CRT #ifndef WINDOWS_H_INCLUDED #include #define WINDOWS_H_INCLUDED 1 #endif #ifndef DK4STRMH_H_INCLUDED #include "dk4strmh.h" #endif #endif #include "dk4strmr.h" #ifndef DK4FD_H_INCLUDED #include "dk4fd.h" #endif #ifndef DK4PATH_H_INCLUDED #include "dk4pathd.h" #endif #ifndef DK4STRD_H_INCLUDED #include "dk4strd.h" #endif #ifndef DK4FOPD_H_INCLUDED #include "dk4fopd.h" #endif $!trace-include /** Compression suffixes. */ static const dkChar * const dk4strmr_co_su[] = { $!string-table macro=dkT .gz .bz2 .svgz $!end }; /** File mode for binary reading. */ static const char dk4strmr_c8_mode[] = { "rb" }; /** File mode for binary reading. */ static const dkChar dk4strmr_dk_mode[] = { dkT("rb") }; dk4_stream_t * dk4stream_open_file_reader(const dkChar *filename, dk4_er_t *erp) { dk4_stream_t *back = NULL; /* Function result */ const dkChar *p1 = NULL; /* Suffix pointer */ #if DK4_HAVE_ZLIB_H && (!(DK4_ON_WINDOWS && DK4_WIN_DENY_CRT)) gzFile gzf = NULL; /* gzip compressed input file */ #endif #if DK4_HAVE_BZLIB_H && (!(DK4_ON_WINDOWS && DK4_WIN_DENY_CRT)) BZFILE *bzf = NULL; /* bzip2 compressed input file */ #endif FILE *fipo = NULL; /* Input file */ #if DK4_ON_WINDOWS && DK4_WIN_DENY_CRT HANDLE fha = INVALID_HANDLE_VALUE; DWORD dwattr = (DWORD)0UL; #endif int coi = -1; /* Compression algorithm index */ #if DK4_CHAR_SIZE > 1 int fd = -1; /* File descriptor */ #endif $? "+ dk4stream_open_file_reader \"%!ds\"", filename if (NULL != filename) { p1 = dk4path_get_suffix(filename, erp); if (NULL != p1) { $? ". file name suffix \"%!ds\"", p1 coi = dk4str_array_index( dk4strmr_co_su, p1, DK4_HAVE_CASE_INSENSITIVE_PATHNAMES ); if (0 > coi) coi = -1; $? ". coi = %d", coi } if (0 != dk4fopen_check(filename, 0, DK4_FOPEN_SC_IS_REGULAR, erp)) { $? ". fopen check ok" switch (coi) { case 1: { #if DK4_HAVE_BZLIB_H && (!(DK4_ON_WINDOWS && DK4_WIN_DENY_CRT)) #if DK4_CHAR_SIZE > 1 /* +++++ bzip2, wchar_t */ $? ". bzip2 for wchar_t" fd = dk4fd_wc_open(filename, (DK4_O_RDONLY | DK4_O_BINARY), erp); if (-1 < fd) { bzf = BZ2_bzdopen(fd, dk4strmr_c8_mode); if (NULL != bzf) { back = dk4stream_open_for_bzfile_with_close( bzf, DK4_STREAM_READ, 4096, 1024, erp ); if (NULL == back) { BZ2_bzclose(bzf); } } else { dk4error_set_simple_error_code(erp, DK4_E_OPEN_READ_FAILED); (void)dk4fd_close(fd, NULL); } } else { dk4error_set_simple_error_code(erp, DK4_E_OPEN_READ_FAILED); } /* ----- bzip2, wchar_t */ #else /* +++++ bzip2, char */ $? ". bzip2 for char" bzf = BZ2_bzopen(filename, dk4strmr_c8_mode); if (NULL != bzf) { back = dk4stream_open_for_bzfile_with_close( bzf, DK4_STREAM_READ, 4096, 1024, erp ); if (NULL == back) { BZ2_bzclose(bzf); } } else { dk4error_set_simple_error_code(erp, DK4_E_OPEN_READ_FAILED); } /* ----- bzip2, char */ #endif #else dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED); #endif } break; case 0: case 2: { $? ". gzip" #if DK4_HAVE_ZLIB_H && (!(DK4_ON_WINDOWS && DK4_WIN_DENY_CRT)) #if DK4_CHAR_SIZE > 1 $? ". gzip for wide characters" /* +++++ gzip, wchar_t */ fd = dk4fd_wc_open(filename, (DK4_O_RDONLY | DK4_O_BINARY), erp); if (-1 < fd) { gzf = gzdopen(fd, dk4strmr_c8_mode); if (NULL != gzf) { back = dk4stream_open_for_gzfile_with_close( gzf, DK4_STREAM_READ, 4096, 1024, erp ); if (NULL == back) { gzclose(gzf); } } else { dk4error_set_simple_error_code(erp, DK4_E_OPEN_READ_FAILED); (void)dk4fd_close(fd, NULL); } } /* ----- gzip, wchar_t */ #else $? ". gzip for char" /* +++++ gzip, char */ gzf = gzopen(filename, dk4strmr_c8_mode); if (NULL != gzf) { back = dk4stream_open_for_gzfile_with_close( gzf, DK4_STREAM_READ, 4096, 1024, erp ); if (NULL == back) { gzclose(gzf); } } else { dk4error_set_simple_error_code(erp, DK4_E_OPEN_READ_FAILED); } /* ----- gzip, char */ #endif #else dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED); #endif } break; default: { $? ". simple file" #if DK4_ON_WINDOWS && DK4_WIN_DENY_CRT dwattr = FILE_ATTRIBUTE_NORMAL; dwattr |= FILE_FLAG_BACKUP_SEMANTICS; dwattr |= FILE_FLAG_SEQUENTIAL_SCAN; #if DK4_CHAR_SIZE > 1 fha = CreateFileW( filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, dwattr, NULL ); #else fha = CreateFileA( filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, dwattr, NULL ); #endif if (INVALID_HANDLE_VALUE != fha) { back = dk4stream_open_for_windows_handle_with_close( fha, DK4_STREAM_READ, 4096, 1024, erp ); if (NULL == back) { (void)CloseHandle(fha); } } else { dk4error_set_simple_error_code(erp, DK4_E_OPEN_READ_FAILED); } #else fipo = dk4fopen( filename, dk4strmr_dk_mode, DK4_FOPEN_SC_IS_REGULAR, erp ); if (NULL != fipo) { $? ". fopen ok" back = dk4stream_open_for_file_with_close( fipo, DK4_STREAM_READ, 4096, 1024, erp ); if (NULL == back) { $? "! stream open failed" (void)fclose(fipo); } } else { $? "! fipo" } #endif $? ". simple file ended" } break; } } else { $? "! file check failed" } } else { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); } $? "- dk4stream_open_file_reader PTR=%d", TR_IPTR(back) return back; }