/**************************************************************************
 *
 * bitio_m_random.h -- Macros for bitio to a file (random access)
 * 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 an array 
 *  of chars. These routines are slower than the ones in "mem" files. but 
 *  with these routines you can mix reads and writes, or multiple writes,  on
 *  the array of chars at the same time and guarantee them to work, also you 
 *  can seek to a point and do a write. The decode and encode macros cannot 
 *  detect when the end off the character is reached and just continue 
 *  processing.
 *
 *
 **************************************************************************/

#ifndef H_BITIO_M_RANDOM
#define H_BITIO_M_RANDOM

#include "longlong.h"
#include "bitio_m_abstract.h"


class random_bitio_buffer : public bitio_buffer { 
public:
  FILE *file;
  unsigned char *buffer;
  mg_u_long  base;
  mg_u_long  used;
  mg_u_long  pos;
  mg_u_long  len;
  mg_u_long  shift;
  void writeRead();

  random_bitio_buffer(FILE *f = 0,
		      mg_u_long length = 8*1024);
  virtual ~random_bitio_buffer();
  
  void attachFile (FILE *f, mg_u_long length);

  random_bitio_buffer &operator= (const random_bitio_buffer &_rbb);
  
  void encodeDone();
  void encodeBit(int b);
  void flush();
  mg_u_long tell();

  void seek(mg_u_long topos);
  void error();
  mg_s_long add00(mg_s_long b);
  mg_s_long addff(mg_s_long b);
  int  bit();
  int  bitOffset();
  void done();

#ifdef USE_LONG_LONG
  // extras for longlong.h
  void seek_LL(mg_ullong pos);
  mg_ullong tell_LL();
#endif
};


/*#define ENCODE_START(f,l)						\
  {									\
    random_bitio_buffer buffer(f, l);

#define ENCODE_CONTINUE(b)						\
  {									\
    random_bitio_buffer buffer;                                               \
    buffer.unpause(b);

#define SEEK fprintf(stderr, "Seek to %d\n",buffer.base)
#define READ fprintf(stderr, "Read of %d\n",buffer.len)
#define WRITE fprintf(stderr, "Write of %d\n",buffer.used)

#define WRITE_READ buffer.writeRead()

#define ENCODE_PAUSE(b)	buffer.pause(&b);}

#define ENCODE_FLUSH buffer.flush();

#define ENCODE_DONE buffer.done();}							

#define DECODE_START(f,l) \
  {									\
    random_bitio_buffer buffer(f, l);

#define DECODE_CONTINUE(b) \
  {									\
    random_bitio_buffer buffer;                                               \
    buffer.unpause(b);

#define DECODE_BIT buffer.bit()

#define DECODE_ADD_FF(b) b = buffer.addff(b)

#define DECODE_ADD_00(b) b = buffer.add00(b)

#define DECODE_DONE buffer.done();}

#define DECODE_PAUSE(b)	buffer.pause(&b);}

#define ENCODE_TELL buffer.tell()

#define DECODE_TELL buffer.tell()
*/



#endif
