%% options copyright owner = Dirk Krause copyright year = 2015-xxxx license = bsd %% header /** @file Open a stream to write 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 write 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 write. @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_writer(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 "dk4strmw.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 dk4strmw_co_su[] = { $!string-table macro=dkT .gz .svgz .bz2 $!end }; /** File mode for binary writing. */ static const char dk4strmw_c8_mode[] = { "wb" }; /** File mode for binary writing. */ static const dkChar dk4strmw_dk_mode[] = { dkT("wb") }; dk4_stream_t * dk4stream_open_file_writer(const dkChar *filename, dk4_er_t *erp) { dk4_stream_t *back = NULL; /* Function result */ dkChar *p1 = NULL; /* File name suffix */ #if DK4_HAVE_ZLIB_H && (!(DK4_ON_WINDOWS && DK4_WIN_DENY_CRT)) gzFile gzf = NULL; /* gzip compressed output file */ #endif #if DK4_HAVE_BZLIB_H && (!(DK4_ON_WINDOWS && DK4_WIN_DENY_CRT)) BZFILE *bzf = NULL; /* bzip2 compressed output file */ #endif FILE *fipo = NULL; /* Output 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_writer \"%!ds\"", TR_STR(filename) if (NULL != filename) { p1 = dk4path_get_suffix(filename, erp); if (NULL != p1) { $? ". suffix \"%!ds\"", p1 coi = dk4str_array_index( dk4strmw_co_su, p1, DK4_HAVE_CASE_INSENSITIVE_PATHNAMES ); if (0 > coi) { coi = -1; } } #if TRACE_DEBUG else { $? ". no suffix" } #endif if (0 != dk4fopen_check(filename, 1, DK4_FOPEN_SC_IS_REGULAR, erp)) { switch (coi) { case 0: case 1: { $? ". gzip" #if DK4_HAVE_ZLIB_H && (!(DK4_ON_WINDOWS && DK4_WIN_DENY_CRT)) #if DK4_CHAR_SIZE > 1 /* +++++ gzip, wchar_t */ $? ". gzip mit wchar_t" fd = dk4fd_wc_open( filename, (DK4_O_WRONLY | DK4_O_BINARY | DK4_O_TRUNC | DK4_O_CREAT), erp ); if (-1 < fd) { gzf = gzdopen(fd, dk4strmw_c8_mode); if (NULL != gzf) { back = dk4stream_open_for_gzfile_with_close( gzf, DK4_STREAM_WRITE, 1024, 4096, erp ); if (NULL == back) { $? "! failed to open stream" gzclose(gzf); } #if TRACE_DEBUG else { $? ". stream opened" } #endif } else { $? "! failed to open gzf" dk4error_set_simple_error_code(erp, DK4_E_OPEN_WRITE_FAILED); (void)dk4fd_close(fd, NULL); } } #if TRACE_DEBUG else { $? "! failed to open fd" } #endif /* ----- gzip, wchar_t */ #else /* +++++ gzip, char */ $? ". gzip char" gzf = gzopen(filename, dk4strmw_c8_mode); if (NULL != gzf) { back = dk4stream_open_for_gzfile_with_close( gzf, DK4_STREAM_WRITE, 1024, 4096, erp ); if (NULL == back) { $? "! failed to open stream" gzclose(gzf); } #if TRACE_DEBUG else { $? ". stream opened" } #endif } else { $? "! failed to open gzf" dk4error_set_simple_error_code(erp, DK4_E_OPEN_WRITE_FAILED); } /* ----- gzip, char */ #endif #else dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED); #endif } break; case 2: { $? ". bzip" #if DK4_HAVE_BZLIB_H && (!(DK4_ON_WINDOWS && DK4_WIN_DENY_CRT)) #if DK4_CHAR_SIZE > 1 /* +++++ bzip2, wchar_t */ $? ". bzip2 wchar_t" fd = dk4fd_wc_open( filename, (DK4_O_WRONLY | DK4_O_BINARY | DK4_O_TRUNC | DK4_O_CREAT), erp ); if (-1 < fd) { bzf = BZ2_bzdopen(fd, dk4strmw_c8_mode); if (NULL != bzf) { back = dk4stream_open_for_bzfile_with_close( bzf, DK4_STREAM_WRITE, 1024, 4096, erp ); if (NULL == back) { $? "! failed to open stream" BZ2_bzclose(bzf); } #if TRACE_DEBUG else { $? ". stream opened" } #endif } else { $? "! failed to open bzf" dk4error_set_simple_error_code(erp, DK4_E_OPEN_WRITE_FAILED); (void)dk4fd_close(fd, NULL); } } else { $? "! failed to open fd" dk4error_set_simple_error_code(erp, DK4_E_OPEN_WRITE_FAILED); } /* ----- bzip2, wchar_t */ #else /* +++++ bzip2, char */ $? ". bzip2 char" bzf = BZ2_bzopen(filename, dk4strmw_c8_mode); if (NULL != bzf) { back = dk4stream_open_for_bzfile_with_close( bzf, DK4_STREAM_WRITE, 1024, 4096, erp ); if (NULL == back) { $? "! failed to open stream" BZ2_bzclose(bzf); } #if TRACE_DEBUG else { $? ". stream opened" } #endif } else { $? "! failed to open bzf" dk4error_set_simple_error_code(erp, DK4_E_OPEN_WRITE_FAILED); } /* ----- bzip2, char */ #endif #else dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED); #endif } break; default: { $? ". plain file" #if DK4_ON_WINDOWS && DK4_WIN_DENY_CRT $? ". Windows without CRT" dwattr = FILE_ATTRIBUTE_NORMAL; dwattr |= FILE_FLAG_BACKUP_SEMANTICS; dwattr |= FILE_FLAG_SEQUENTIAL_SCAN; #if DK4_CHAR_SIZE > 1 fha = CreateFileW( filename, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, dwattr, NULL ); #else fha = CreateFileA( filename, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, dwattr, NULL ); #endif if (INVALID_HANDLE_VALUE != fha) { back = dk4stream_open_for_windows_handle_with_close( fha, DK4_STREAM_WRITE, 1024, 4096, erp ); if (NULL == back) { $? "! failed to open stream" (void)CloseHandle(fha); } #if TRACE_DEBUG else { $? ". stream opened" } #endif } else { $? "! CreataeFile failed" dk4error_set_simple_error_code(erp, DK4_E_OPEN_WRITE_FAILED); } #else $? ". Windows with CRT allowed" fipo = dk4fopen( filename, dk4strmw_dk_mode, DK4_FOPEN_SC_IS_REGULAR, erp ); if (NULL != fipo) { back = dk4stream_open_for_file_with_close( fipo, DK4_STREAM_WRITE, 1024, 4096, erp ); if (NULL == back) { $? "! failed to open stream" (void)fclose(fipo); } #if TRACE_DEBUG else { $? ". stream opened" } #endif } else { $? "! fipo" } #endif } break; } } else { $? "! file check failed" } } else { $? "! no filename" dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); } $? "- dk4stream_open_file_writer %d", TR_IPTR(back) return back; }