// Header for Bit stream storage class
#ifndef _BITSTREAM_H
#define _BITSTREAM_H
#include <Arduino.h>

#define MAX_BITSTREAM_SIZE 512

class BitStream
{
protected:
  bool processable;             // packet complete, to be processed by caller
  uint8_t *storage;             // Pointer to data holding the bit sequence
  uint16_t storage_size;        // number of allocated bytes in storage
  uint16_t length;              // number of stored bits in sequence
  uint16_t readPtr;             // current reading position
  int increaseStorage(void);    // allocate double storage size and copy data
  uint8_t bitPos;               // Number of bit in current byte
public:
  // Constructor. Optionally takes initial bit stream length
  BitStream(uint16_t initStorage=32);
  // Destructor
  ~BitStream();
  inline void release(void) { processable = false; }
  inline void block(void)   { processable = true; }
  inline bool blocked(void) { return processable; }
  int putBit(bool bit);        // push another bit at the end of the stored sequence
  int getBit(uint16_t pos);    // read bit at pos in sequence
  inline int getBit(void) { return getBit(readPtr); }  // read bit at current readPtr and advance
  inline void unGetBit(void) { if(readPtr) readPtr--; }  // Step back one bit
  int dumpHex(char *buffer, uint16_t buffer_length, uint16_t start_pos=0); // generate hex dump of sequence in buffer
  int dumpBin(char *buffer, uint16_t buffer_length, uint16_t start_pos=0, bool invert=false, bool reverse=false); // generate binary dump
  inline uint16_t getLength(void) { return length; }
  inline uint16_t getPos(void)    { return readPtr; }
  inline void reset(void) { readPtr = 0; }
  inline void init(void) { length = 0; bitPos = 0; readPtr = 0;}
} ;

#endif
