📄 bitfile.c
字号:
/**************************************************************************** Bit Stream File Implementation** File : bitfile.c* Purpose : This file implements a simple library of I/O functions for* files that contain data in sizes that aren't integral bytes.* An attempt was made to make the functions in this library* analogous to functions provided to manipulate byte streams.* The functions contained in this library were created with* compression algorithms in mind, but may be suited to other* applications.* Author : Michael Dipperstein* Date : January 9, 2004****************************************************************************** UPDATES** $Id: bitfile.c,v 1.6 2005/12/08 06:56:55 michael Exp $* $Log: bitfile.c,v $* Revision 1.6 2005/12/08 06:56:55 michael* Minor text corrections.** Revision 1.5 2005/12/06 15:06:37 michael* Added BitFileGetBitsInt and BitFilePutBitsInt for integer types.** Revision 1.4 2005/06/23 04:34:18 michael* Prevent BitfileGetBits/PutBits from accessing an extra byte when given* an integral number of bytes.** Revision 1.3 2004/11/09 14:16:58 michael* Added functions to convert open bit_file_t to FILE and to* align open bit_file_t to the next byte.** Revision 1.2 2004/06/15 13:15:58 michael* Use incomplete type to hide definition of bitfile structure** Revision 1.1.1.1 2004/02/09 05:31:42 michael* Initial release******************************************************************************** Bitfile: Bit stream File I/O Routines* Copyright (C) 2004-2005 by Michael Dipperstein (mdipper@.ucsb.edu)** This library is free software; you can redistribute it and/or* modify it under the terms of the GNU Lesser General Public* License as published by the Free Software Foundation; either* version 2.1 of the License, or (at your option) any later version.** This library is distributed in the hope that it will be useful,* but WITHOUT ANY WARRANTY; without even the implied warranty of* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU* Lesser General Public License for more details.** You should have received a copy of the GNU Lesser General Public* License along with this library; if not, write to the Free Software* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA****************************************************************************//**************************************************************************** INCLUDED FILES***************************************************************************/#include <stdlib.h>#include <errno.h>#include "bitfile.h"/**************************************************************************** TYPE DEFINITIONS***************************************************************************/typedef enum{ BF_UNKNOWN_ENDIAN, BF_LITTLE_ENDIAN, BF_BIG_ENDIAN,} endian_t;struct bit_file_t{ FILE *fp; /* file pointer used by stdio functions */ endian_t endian; /* endianess of architecture */ unsigned char bitBuffer; /* bits waiting to be read/written */ unsigned char bitCount; /* number of bits in bitBuffer */ BF_MODES mode; /* open for read, write, or append */};/* union used to test for endianess */typedef union{ unsigned long word; unsigned char bytes[sizeof(unsigned long)];} endian_test_t;/**************************************************************************** PROTOTYPES***************************************************************************/endian_t DetermineEndianess(void);int BitFilePutBitsLE(bit_file_t *stream, void *bits, const unsigned int count);int BitFilePutBitsBE(bit_file_t *stream, void *bits, const unsigned int count, const size_t size);int BitFileGetBitsLE(bit_file_t *stream, void *bits, const unsigned int count);int BitFileGetBitsBE(bit_file_t *stream, void *bits, const unsigned int count, const size_t size);/**************************************************************************** FUNCTIONS***************************************************************************//**************************************************************************** Function : BitFileOpen* Description: This function opens a bit file for reading, writing,* or appending. If successful, a bit_file_t data* structure will be allocated and a pointer to the* structure will be returned.* Parameters : fileName - NULL terminated string containing the name of* the file to be opened.* mode - The mode of the file to be opened* Effects : The specified file will be opened and file structure will* be allocated.* Returned : Pointer to the bit_file_t structure for the bit file* opened, or NULL on failure. errno will be set for all* failure cases.***************************************************************************/bit_file_t *BitFileOpen(const char *fileName, const BF_MODES mode){ char modes[3][2] = {"rb", "wb", "ab"}; /* binary modes for fopen */ bit_file_t *bf; bf = (bit_file_t *)malloc(sizeof(bit_file_t)); if (bf == NULL) { /* malloc failed */ errno = ENOMEM; } else { bf->fp = fopen(fileName, modes[mode]); if (bf->fp == NULL) { /* fopen failed */ free(bf); bf = NULL; } else { /* fopen succeeded fill in remaining bf data */ bf->bitBuffer = 0; bf->bitCount = 0; bf->mode = mode; /*************************************************************** * TO DO: Consider using the last byte in a file to indicate * the number of bits in the previous byte that actually have * data. If I do that, I'll need special handling of files * opened with a mode of BF_APPEND. ***************************************************************/ } } bf->endian = DetermineEndianess(); return (bf);}/**************************************************************************** Function : MakeBitFile* Description: This function naively wraps a standard file in a* bit_file_t structure. ANSI-C doesn't support file status* functions commonly found in other C variants, so the* caller must be passed as a parameter.* Parameters : stream - pointer to the standard file being wrapped.* mode - The mode of the file being wrapped.* Effects : A bit_file_t structure will be created for the stream* passed as a parameter.* Returned : Pointer to the bit_file_t structure for the bit file* or NULL on failure. errno will be set for all failure* cases.***************************************************************************/bit_file_t *MakeBitFile(FILE *stream, const BF_MODES mode){ bit_file_t *bf; if (stream == NULL) { /* can't wrapper empty steam */ errno = EBADF; bf = NULL; } else { bf = (bit_file_t *)malloc(sizeof(bit_file_t)); if (bf == NULL) { /* malloc failed */ errno = ENOMEM; } else { /* set structure data */ bf->fp = stream; bf->bitBuffer = 0; bf->bitCount = 0; bf->mode = mode; } } bf->endian = DetermineEndianess(); return (bf);}/**************************************************************************** Function : DetermineEndianess* Description: This function determines the endianess of the current* hardware architecture. An unsigned long is set to 1. If* the 1st byte of the unsigned long gets the 1, this is a* little endian machine. If the last byte gets the 1, this* is a big endian machine.* Parameters : None* Effects : None* Returned : endian_t for current machine architecture***************************************************************************/endian_t DetermineEndianess(void){ endian_t endian; endian_test_t endianTest; endianTest.word = 1; if (endianTest.bytes[0] == 1) { /* LSB is 1st byte (little endian)*/ endian = BF_LITTLE_ENDIAN; } else if (endianTest.bytes[sizeof(unsigned long) - 1] == 1) { /* LSB is last byte (big endian)*/ endian = BF_BIG_ENDIAN; } else { endian = BF_UNKNOWN_ENDIAN; } return endian;}/**************************************************************************** Function : BitFileClose* Description: This function closes a bit file and frees all associated* data.* Parameters : stream - pointer to bit file stream being closed* Effects : The specified file will be closed and the file structure* will be freed.* Returned : 0 for success or EOF for failure.***************************************************************************/int BitFileClose(bit_file_t *stream){ int returnValue = 0; if (stream == NULL) { return(EOF); } if ((stream->mode == BF_WRITE) || (stream->mode == BF_APPEND)) { /* write out any unwritten bits */ if (stream->bitCount != 0) { (stream->bitBuffer) <<= 8 - (stream->bitCount); fputc(stream->bitBuffer, stream->fp); /* handle error? */ } } /*********************************************************************** * TO DO: Consider writing an additional byte indicating the number of * valid bits (bitCount) in the previous byte. ***********************************************************************/ /* close file */ returnValue = fclose(stream->fp); /* free memory allocated for bit file */ free(stream); return(returnValue);}/**************************************************************************** Function : BitFileToFILE* Description: This function flushes and frees the bitfile structure,* returning a pointer to a stdio file.* Parameters : stream - pointer to bit file stream being closed* Effects : The specified bitfile will be made useable as a stdio* FILE.* Returned : Pointer to FILE. NULL for failure.***************************************************************************/FILE *BitFileToFILE(bit_file_t *stream){ FILE *fp = NULL; if (stream == NULL) { return(NULL); } if ((stream->mode == BF_WRITE) || (stream->mode == BF_APPEND)) { /* write out any unwritten bits */ if (stream->bitCount != 0) { (stream->bitBuffer) <<= 8 - (stream->bitCount); fputc(stream->bitBuffer, stream->fp); /* handle error? */ } } /*********************************************************************** * TO DO: Consider writing an additional byte indicating the number of * valid bits (bitCount) in the previous byte. ***********************************************************************/ /* close file */ fp = stream->fp; /* free memory allocated for bit file */ free(stream); return(fp);}/**************************************************************************** Function : BitFileByteAlign* Description: This function aligns the bitfile to the nearest byte. For* output files, this means writing out the bit buffer with* extra bits set to 0. For input files, this means flushing* the bit buffer.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -