/************************************************************************** * * bitio_m_stdio.h -- Macros for bitio to a file * Copyright (C) 1994 Neil Sharman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * ************************************************************************** * * This file contains macros for doing bitwise input and output on a FILE*. * With these routines you cannot mix reads and writes on the FILE, * or multiple writes, at the same time and guarantee them to work, also you * cannot seek to a point and do a write. The decode routine can detect when * you run off the end of the file and will produce an approate error message. * * **************************************************************************/ #ifndef H_BITIO_M_STDIO #define H_BITIO_M_STDIO typedef struct stdio_bitio_state { FILE *File; unsigned char Buff; unsigned char Btg; } stdio_bitio_state; #ifndef DECODE_ERROR #define DECODE_ERROR (fprintf(stderr,"Unexpected EOF in \"%s\" on line %d\n",\ __FILE__, __LINE__), exit(1)) #endif #define ENCODE_START(f) \ { \ FILE *__outfile = f; \ register unsigned char __buff = 0; \ register unsigned char __btg = sizeof(__buff)*8; #define ENCODE_CONTINUE(b) \ { \ FILE *__outfile = (b).File; \ register unsigned char __buff = (b).Buff; \ register unsigned char __btg = (b).Btg; #define ENCODE_BIT(b) \ do { \ --__btg; \ if (b) __buff |= (1 << __btg); \ if (!__btg) \ { \ putc(__buff, __outfile); \ __buff = 0; \ __btg = sizeof(__buff)*8; \ } \ } while(0) #define ENCODE_PAUSE(b) \ (b).File = __outfile; \ (b).Buff = __buff; \ (b).Btg = __btg; \ } #define ENCODE_DONE \ if (__btg != sizeof(__buff)*8) \ putc(__buff,__outfile); \ } #define DECODE_START(f) \ { \ FILE *__infile = f; \ register unsigned char __buff = 0; \ register unsigned char __btg = 0; #define DECODE_CONTINUE(b) \ { \ FILE *__infile = (b).File; \ register unsigned char __buff = (b).Buff; \ register unsigned char __btg = (b).Btg; #define DECODE_ADD_FF(b) \ do { \ if (!__btg) \ { \ register int val = getc(__infile); \ __buff = val == EOF ? 0xff : val; \ __btg = sizeof(__buff)*8; \ } \ (b) += (b) + ((__buff >> --__btg) & 1); \ } while(0) #define DECODE_ADD_00(b) \ do { \ if (!__btg) \ { \ register int val = getc(__infile); \ __buff = val == EOF ? 0xff : val; \ __btg = sizeof(__buff)*8; \ } \ (b) += (b) + ((__buff >> --__btg) & 1); \ } while(0) #define DECODE_BIT (__btg ? (__buff >> --__btg) & 1 : \ (__buff = getc(__infile), (feof(__infile) ? \ (DECODE_ERROR, 0) : \ (__btg = sizeof(__buff)*8, (__buff >> --__btg) & 1)))) #define DECODE_DONE ; \ } #define DECODE_PAUSE(b) \ (b).File = __infile; \ (b).Buff = __buff; \ (b).Btg = __btg; \ } #define DECODE_SEEK(pos) \ do { \ register long __new_pos = (pos); \ fseek(__infile, __new_pos >> 3, 0); \ __buff = getc(__infile); \ __btg = 8 - (__new_pos&7); \ } \ while(0) #endif