/* -*- tab-width: 4; -*- */ /* vi: set sw=2 ts=4 expandtab: */ /* * Copyright 2010-2020 The Khronos Group Inc. * SPDX-License-Identifier: Apache-2.0 */ /** * @file * @~English * * @brief Implementation of ktxStream for FILE. * * @author Maksim Kolesin, Under Development * @author Georg Kolling, Imagination Technology * @author Mark Callow, HI Corporation */ #include <assert.h> #include <errno.h> #include <inttypes.h> #include <string.h> /* I need these on Linux. Why? */ #define __USE_LARGEFILE … #define __USE_POSIX … #define _POSIX_SOURCE … #include <stdio.h> #include <stdlib.h> #include <sys/types.h> // For stat.h on Windows #define __USE_MISC … #include <sys/stat.h> #include "ktx.h" #include "ktxint.h" #include "filestream.h" // Gotta love Windows :-( #if defined(_MSC_VER) #if defined(_WIN64) #define ftello … #define fseeko … #else #define ftello … #define fseeko … #endif #define fileno … #define fstat … #define stat … #define S_IFIFO … #define S_IFSOCK … typedef unsigned short mode_t; #endif #if defined(__MINGW32__) #define S_IFSOCK … #endif #define KTX_FILE_STREAM_MAX … /** * @~English * @brief Read bytes from a ktxFileStream. * * @param [in] str pointer to the ktxStream from which to read. * @param [out] dst pointer to a block of memory with a size * of at least @p size bytes, converted to a void*. * @param [in,out] count pointer to total count of bytes to be read. * On completion set to number of bytes read. * * @return KTX_SUCCESS on success, other KTX_* enum values on error. * * @exception KTX_INVALID_VALUE @p dst is @c NULL or @p src is @c NULL. * @exception KTX_FILE_READ_ERROR an error occurred while reading the file. * @exception KTX_FILE_UNEXPECTED_EOF not enough data to satisfy the request. */ static KTX_error_code ktxFileStream_read(ktxStream* str, void* dst, const ktx_size_t count) { … } /** * @~English * @brief Skip bytes in a ktxFileStream. * * @param [in] str pointer to a ktxStream object. * @param [in] count number of bytes to be skipped. * * In order to support applications reading from stdin, read characters * rather than using seek functions. * * @return KTX_SUCCESS on success, other KTX_* enum values on error. * * @exception KTX_INVALID_VALUE @p str is @c NULL or @p count is less than zero. * @exception KTX_INVALID_OPERATION skipping @p count bytes would go beyond EOF. * @exception KTX_FILE_READ_ERROR an error occurred while reading the file. * @exception KTX_FILE_UNEXPECTED_EOF not enough data to satisfy the request. * @p count is set to the number of bytes * skipped. */ static KTX_error_code ktxFileStream_skip(ktxStream* str, const ktx_size_t count) { … } /** * @~English * @brief Write bytes to a ktxFileStream. * * @param [in] str pointer to the ktxStream that is the destination of the * write. * @param [in] src pointer to the array of elements to be written, * converted to a const void*. * @param [in] size size in bytes of each element to be written. * @param [in] count number of elements, each one with a @p size of size * bytes. * * @return KTX_SUCCESS on success, other KTX_* enum values on error. * * @exception KTX_INVALID_VALUE @p str is @c NULL or @p src is @c NULL. * @exception KTX_FILE_OVERFLOW the requested write would caused the file to * exceed the maximum supported file size. * @exception KTX_FILE_WRITE_ERROR a system error occurred while writing the * file. */ static KTX_error_code ktxFileStream_write(ktxStream* str, const void *src, const ktx_size_t size, const ktx_size_t count) { … } /** * @~English * @brief Get the current read/write position in a ktxFileStream. * * @param [in] str pointer to the ktxStream to query. * @param [in,out] off pointer to variable to receive the offset value. * * @return KTX_SUCCESS on success, other KTX_* enum values on error. * * @exception KTX_FILE_ISPIPE file descriptor underlying stream is associated * with a pipe or FIFO so does not have a * file-position indicator. * @exception KTX_INVALID_VALUE @p str or @p pos is @c NULL. */ static KTX_error_code ktxFileStream_getpos(ktxStream* str, ktx_off_t* pos) { … } /** * @~English * @brief Set the current read/write position in a ktxFileStream. * * Offset of 0 is the start of the file. This function operates * like Linux > 3.1's @c lseek() when it is passed a @c whence * of @c SEEK_DATA as it returns an error if the seek would * go beyond the end of the file. * * @param [in] str pointer to the ktxStream whose r/w position is to be set. * @param [in] off pointer to the offset value to set. * * @return KTX_SUCCESS on success, other KTX_* enum values on error. * * Throws the same exceptions as ktxFileStream_getsize() for the reasons given * there plus the following: * * @exception KTX_INVALID_VALUE @p str is @c NULL. * @exception KTX_INVALID_OPERATION @p pos is > the size of the file or an * fseek error occurred. */ static KTX_error_code ktxFileStream_setpos(ktxStream* str, ktx_off_t pos) { … } /** * @~English * @brief Get the size of a ktxFileStream in bytes. * * @param [in] str pointer to the ktxStream whose size is to be queried. * @param [in,out] size pointer to a variable in which size will be written. * * @return KTX_SUCCESS on success, other KTX_* enum values on error. * * @exception KTX_FILE_OVERFLOW size is too large to be returned in a * @c ktx_size_t. * @exception KTX_FILE_ISPIPE file descriptor underlying stream is associated * with a pipe or FIFO so does not have a * file-position indicator. * @exception KTX_FILE_READ_ERROR a system error occurred while getting the * size. * @exception KTX_INVALID_VALUE @p str or @p size is @c NULL. * @exception KTX_INVALID_OPERATION stream is a tty. */ static KTX_error_code ktxFileStream_getsize(ktxStream* str, ktx_size_t* size) { … } /** * @~English * @brief Initialize a ktxFileStream. * * @param [in] str pointer to the ktxStream to initialize. * @param [in] file pointer to the underlying FILE object. * @param [in] closeFileOnDestruct if not false, stdio file pointer will be closed when ktxStream * is destructed. * * @return KTX_SUCCESS on success, KTX_INVALID_VALUE on error. * * @exception KTX_INVALID_VALUE @p stream is @c NULL or @p file is @c NULL. */ KTX_error_code ktxFileStream_construct(ktxStream* str, FILE* file, ktx_bool_t closeFileOnDestruct) { … } /** * @~English * @brief Destruct the stream, potentially closing the underlying FILE. * * This only closes the underyling FILE if the @c closeOnDestruct parameter to * ktxFileStream_construct() was not @c KTX_FALSE. * * @param [in] str pointer to the ktxStream whose FILE is to potentially * be closed. */ void ktxFileStream_destruct(ktxStream* str) { … }