ROOT logo
//-*- Mode: C++ -*-
// $Id$
#ifndef ALIHLTDATAINFLATER_H
#define ALIHLTDATAINFLATER_H
//* This file is property of and copyright by the ALICE HLT Project        * 
//* ALICE Experiment at CERN, All rights reserved.                         *
//* See cxx source for full Copyright notice                               *

/// @file   AliHLTDataInflater.h
/// @author Matthias Richter, Timm Steinbeck
/// @date   2011-08-10
/// @brief  Data inflater reading the bitstream from the AliHLTDataDeflater
/// @note   Code original from AliHLTTPCCompModelInflater

#include "AliHLTLogging.h"
#include "AliHLTDataTypes.h"
#include "AliHLTStdIncludes.h"

/**
 * @class AliHLTDataInflater
 * Data inflating interface to a bitstream encoded by AliHLTDataDeflater
 *
 * Setting up the data inflater:
 * <pre>
  AliHLTDataInflater inflater;
  if (inflater.InitBitDataInput(pData, dataSize)<0) {
    // can not initialize
  }
 * </pre>
 *
 * If the layout in the bitstream is known the parts of known bit length
 * can be read by
 * - InputBit(value)
 * - InputBits(value, length)
 *
 * For inflating huffman encoded streams where the symbol length is unknown
 * one has to read a fixed value, retrieve the symbol and rewind the stream.
 * Example how to read a fixed number of bits from the stream and rewind
 * after the length of the symbol has been determined.
 * <pre>
  AliHLTUInt64_t inputWord=0;
  int inputLength=sizeof(inputWord)*8;
  while (outClusterCnt<nofClusters && inflater.InputBits(inputWord, inputLength)) {
    // check how many of the bits belong to the symbol and rewind the
    // input stream
    int symbolLength=...;
    inputWord>>=(inputLength-symbolLength);
    if (!inflater.RewindBitPosition(inputLength-symbolLength)) {
      // some error
      break;
    }

    // do something with data in input word

    // check if there is less remaining data than the full input word bit length
    UInt_t bytes=inflater.GetRemainingBitDataSizeBytes();
    if (bytes>0 && bytes<=sizeof(inputWord)) {
      // reading the last bytes
      // available bits are determined by cuurent position+1 (because
      // position 0 means 1 bit still available) and the bits in the
      // available bytes
      inputLength=inflater.GetCurrentBitInputPosition()+1+(bytes-1)*8;
    }
  }
 * </pre>
 * 
 *
 * @ingroup alihlt_base
 */
class AliHLTDataInflater : public AliHLTLogging
{
public:
  /// standard constructor
  AliHLTDataInflater();
  /// destructor
  ~AliHLTDataInflater();

  /** init inflater for reading
   * @param input  AliHLTUInt8_t* pointer to input data
   * @param inputSize UInt_t input data size
   */
  int InitBitDataInput(const AliHLTUInt8_t* input, UInt_t inputSize );

  /** close inflater for reading */	
  void CloseBitDataInput();
      
  /** function to get current byte input position 
   * @return unsigned long value of current byte input position
   */
  unsigned long GetCurrentByteInputPosition() const
  {
    return (unsigned long)( fBitDataCurrentInput - fBitDataCurrentInputStart );
  }

  /** function to get current bit input position
   * @return unsigned value of current bit input position
   */
  unsigned GetCurrentBitInputPosition() const
  {
    return fBitDataCurrentPosInWord;
  }

  /** function to get current input byte
   * @return AliHLTUInt8_t value of current input byte
   */
  AliHLTUInt8_t GetCurrentInputByte() const
  {
    return fBitDataCurrentWord;
  }

  /** function to determine end of bit input
   * @return boolean if end is reached or not
   */
  bool EndOfBitInput() const
  {
    return (fBitDataCurrentInput>=fBitDataCurrentInputEnd);
  }
      
  /** function to get bit data input size bytes
   * @return UInt_t value of bit data input size bytes
   */
  UInt_t GetBitDataInputSizeBytes() const
  {
    return fBitDataCurrentInput-fBitDataCurrentInputStart;
  }

  /** get number of remaining input bytes
   * the last byte might be already partially read, use
   * GetCurrentBitInputPosition()
   */
  UInt_t GetRemainingBitDataSizeBytes() const
  {
    return fBitDataCurrentInputEnd-fBitDataCurrentInput;
  }

  /** function to determine input bit
   * @return boolean (if bit is 1 or 0)
   */
  bool InputBit( AliHLTUInt8_t & value );

  /** function to read bits from bitstream
   * @param value
   * @param bitCount
   * @return boolean 
   */
  template<typename T>
  bool InputBits( T & value, UInt_t const & bitCount );

  /**
   * Rewind the current bit position by the given number of bits.
   */
  bool RewindBitPosition(UInt_t const & bitCount);
 
  /** function pad 8 bits */
  void Pad8Bits();

  /** function to determine input bytes
   * @param data       AliHLTUInt8_t* pointer to input data
   * @param byteCount  UInt_t const &
   * @return boolean
   */
  bool InputBytes( AliHLTUInt8_t* data, UInt_t const & byteCount );

  /**
   * Read the next value.
   * Data read function for inflaters for different formats
   */
  virtual bool NextValue(AliHLTUInt64_t& /*value*/, AliHLTUInt32_t& /*length*/) {return false;}
  /// switch to next parameter
  virtual int NextParameter() {return -ENOSYS;}

  /// clear the object and reset pointer references
  virtual void Clear(Option_t * /*option*/ ="");

  /// print info
  virtual void Print(Option_t *option="") const;

  /// print info
  virtual void Print(ostream& out, Option_t *option="") const;

protected:
private:
  /** copy constructor prohibited */
  AliHLTDataInflater(const AliHLTDataInflater&);
  /** assignment operator prohibited */
  AliHLTDataInflater& operator=(const AliHLTDataInflater&);

  /** member variable for bit data current word */
  AliHLTUInt8_t fBitDataCurrentWord; // member variable for bit data current word
  /** member variable for bit data current position in word */
  UInt_t fBitDataCurrentPosInWord;// member variable for bit data current position in word
  /** member variable for bit data current input */
  const AliHLTUInt8_t *fBitDataCurrentInput; // member variable for bit data current input
  /** member variable for bit data current input start */
  const AliHLTUInt8_t *fBitDataCurrentInputStart; // member variable for bit data current input star
  /** member variable for bit data current input end */
  const AliHLTUInt8_t *fBitDataCurrentInputEnd; // member variable for bit data current input end

  ClassDef(AliHLTDataInflater, 0)
};

template<typename T>
bool AliHLTDataInflater::InputBits( T & value, UInt_t const & bitCount )
{
  // read bits from the input stream into variable
  if (bitCount>sizeof(T)*8) {
    HLTFatal( "variable of type size %u too small to read %u bits", sizeof(T)*8, (unsigned)bitCount);
    return false;
  }
  UInt_t bitsToRead=bitCount;
  UInt_t curBitCount;
  value = 0;
  while ( bitsToRead>0 ) {
    if ( fBitDataCurrentInput>=fBitDataCurrentInputEnd )
      return false;
    if ( bitsToRead >= fBitDataCurrentPosInWord+1 )
      curBitCount = fBitDataCurrentPosInWord+1;
    else
      curBitCount = bitsToRead;
    value = (value << curBitCount) | ( (fBitDataCurrentWord >> (fBitDataCurrentPosInWord-curBitCount+1)) & ((1 << curBitCount)-1) );
    if ( fBitDataCurrentPosInWord < curBitCount ) {
      fBitDataCurrentInput++;
      fBitDataCurrentPosInWord = 7;
      if ( fBitDataCurrentInput<fBitDataCurrentInputEnd ) {
	fBitDataCurrentWord = *fBitDataCurrentInput;
      }
    }
    else
      fBitDataCurrentPosInWord -= curBitCount;
    bitsToRead -= curBitCount;
  }
  return true;
}

ostream& operator<<(ostream &out, const AliHLTDataInflater& me);

#endif
 AliHLTDataInflater.h:1
 AliHLTDataInflater.h:2
 AliHLTDataInflater.h:3
 AliHLTDataInflater.h:4
 AliHLTDataInflater.h:5
 AliHLTDataInflater.h:6
 AliHLTDataInflater.h:7
 AliHLTDataInflater.h:8
 AliHLTDataInflater.h:9
 AliHLTDataInflater.h:10
 AliHLTDataInflater.h:11
 AliHLTDataInflater.h:12
 AliHLTDataInflater.h:13
 AliHLTDataInflater.h:14
 AliHLTDataInflater.h:15
 AliHLTDataInflater.h:16
 AliHLTDataInflater.h:17
 AliHLTDataInflater.h:18
 AliHLTDataInflater.h:19
 AliHLTDataInflater.h:20
 AliHLTDataInflater.h:21
 AliHLTDataInflater.h:22
 AliHLTDataInflater.h:23
 AliHLTDataInflater.h:24
 AliHLTDataInflater.h:25
 AliHLTDataInflater.h:26
 AliHLTDataInflater.h:27
 AliHLTDataInflater.h:28
 AliHLTDataInflater.h:29
 AliHLTDataInflater.h:30
 AliHLTDataInflater.h:31
 AliHLTDataInflater.h:32
 AliHLTDataInflater.h:33
 AliHLTDataInflater.h:34
 AliHLTDataInflater.h:35
 AliHLTDataInflater.h:36
 AliHLTDataInflater.h:37
 AliHLTDataInflater.h:38
 AliHLTDataInflater.h:39
 AliHLTDataInflater.h:40
 AliHLTDataInflater.h:41
 AliHLTDataInflater.h:42
 AliHLTDataInflater.h:43
 AliHLTDataInflater.h:44
 AliHLTDataInflater.h:45
 AliHLTDataInflater.h:46
 AliHLTDataInflater.h:47
 AliHLTDataInflater.h:48
 AliHLTDataInflater.h:49
 AliHLTDataInflater.h:50
 AliHLTDataInflater.h:51
 AliHLTDataInflater.h:52
 AliHLTDataInflater.h:53
 AliHLTDataInflater.h:54
 AliHLTDataInflater.h:55
 AliHLTDataInflater.h:56
 AliHLTDataInflater.h:57
 AliHLTDataInflater.h:58
 AliHLTDataInflater.h:59
 AliHLTDataInflater.h:60
 AliHLTDataInflater.h:61
 AliHLTDataInflater.h:62
 AliHLTDataInflater.h:63
 AliHLTDataInflater.h:64
 AliHLTDataInflater.h:65
 AliHLTDataInflater.h:66
 AliHLTDataInflater.h:67
 AliHLTDataInflater.h:68
 AliHLTDataInflater.h:69
 AliHLTDataInflater.h:70
 AliHLTDataInflater.h:71
 AliHLTDataInflater.h:72
 AliHLTDataInflater.h:73
 AliHLTDataInflater.h:74
 AliHLTDataInflater.h:75
 AliHLTDataInflater.h:76
 AliHLTDataInflater.h:77
 AliHLTDataInflater.h:78
 AliHLTDataInflater.h:79
 AliHLTDataInflater.h:80
 AliHLTDataInflater.h:81
 AliHLTDataInflater.h:82
 AliHLTDataInflater.h:83
 AliHLTDataInflater.h:84
 AliHLTDataInflater.h:85
 AliHLTDataInflater.h:86
 AliHLTDataInflater.h:87
 AliHLTDataInflater.h:88
 AliHLTDataInflater.h:89
 AliHLTDataInflater.h:90
 AliHLTDataInflater.h:91
 AliHLTDataInflater.h:92
 AliHLTDataInflater.h:93
 AliHLTDataInflater.h:94
 AliHLTDataInflater.h:95
 AliHLTDataInflater.h:96
 AliHLTDataInflater.h:97
 AliHLTDataInflater.h:98
 AliHLTDataInflater.h:99
 AliHLTDataInflater.h:100
 AliHLTDataInflater.h:101
 AliHLTDataInflater.h:102
 AliHLTDataInflater.h:103
 AliHLTDataInflater.h:104
 AliHLTDataInflater.h:105
 AliHLTDataInflater.h:106
 AliHLTDataInflater.h:107
 AliHLTDataInflater.h:108
 AliHLTDataInflater.h:109
 AliHLTDataInflater.h:110
 AliHLTDataInflater.h:111
 AliHLTDataInflater.h:112
 AliHLTDataInflater.h:113
 AliHLTDataInflater.h:114
 AliHLTDataInflater.h:115
 AliHLTDataInflater.h:116
 AliHLTDataInflater.h:117
 AliHLTDataInflater.h:118
 AliHLTDataInflater.h:119
 AliHLTDataInflater.h:120
 AliHLTDataInflater.h:121
 AliHLTDataInflater.h:122
 AliHLTDataInflater.h:123
 AliHLTDataInflater.h:124
 AliHLTDataInflater.h:125
 AliHLTDataInflater.h:126
 AliHLTDataInflater.h:127
 AliHLTDataInflater.h:128
 AliHLTDataInflater.h:129
 AliHLTDataInflater.h:130
 AliHLTDataInflater.h:131
 AliHLTDataInflater.h:132
 AliHLTDataInflater.h:133
 AliHLTDataInflater.h:134
 AliHLTDataInflater.h:135
 AliHLTDataInflater.h:136
 AliHLTDataInflater.h:137
 AliHLTDataInflater.h:138
 AliHLTDataInflater.h:139
 AliHLTDataInflater.h:140
 AliHLTDataInflater.h:141
 AliHLTDataInflater.h:142
 AliHLTDataInflater.h:143
 AliHLTDataInflater.h:144
 AliHLTDataInflater.h:145
 AliHLTDataInflater.h:146
 AliHLTDataInflater.h:147
 AliHLTDataInflater.h:148
 AliHLTDataInflater.h:149
 AliHLTDataInflater.h:150
 AliHLTDataInflater.h:151
 AliHLTDataInflater.h:152
 AliHLTDataInflater.h:153
 AliHLTDataInflater.h:154
 AliHLTDataInflater.h:155
 AliHLTDataInflater.h:156
 AliHLTDataInflater.h:157
 AliHLTDataInflater.h:158
 AliHLTDataInflater.h:159
 AliHLTDataInflater.h:160
 AliHLTDataInflater.h:161
 AliHLTDataInflater.h:162
 AliHLTDataInflater.h:163
 AliHLTDataInflater.h:164
 AliHLTDataInflater.h:165
 AliHLTDataInflater.h:166
 AliHLTDataInflater.h:167
 AliHLTDataInflater.h:168
 AliHLTDataInflater.h:169
 AliHLTDataInflater.h:170
 AliHLTDataInflater.h:171
 AliHLTDataInflater.h:172
 AliHLTDataInflater.h:173
 AliHLTDataInflater.h:174
 AliHLTDataInflater.h:175
 AliHLTDataInflater.h:176
 AliHLTDataInflater.h:177
 AliHLTDataInflater.h:178
 AliHLTDataInflater.h:179
 AliHLTDataInflater.h:180
 AliHLTDataInflater.h:181
 AliHLTDataInflater.h:182
 AliHLTDataInflater.h:183
 AliHLTDataInflater.h:184
 AliHLTDataInflater.h:185
 AliHLTDataInflater.h:186
 AliHLTDataInflater.h:187
 AliHLTDataInflater.h:188
 AliHLTDataInflater.h:189
 AliHLTDataInflater.h:190
 AliHLTDataInflater.h:191
 AliHLTDataInflater.h:192
 AliHLTDataInflater.h:193
 AliHLTDataInflater.h:194
 AliHLTDataInflater.h:195
 AliHLTDataInflater.h:196
 AliHLTDataInflater.h:197
 AliHLTDataInflater.h:198
 AliHLTDataInflater.h:199
 AliHLTDataInflater.h:200
 AliHLTDataInflater.h:201
 AliHLTDataInflater.h:202
 AliHLTDataInflater.h:203
 AliHLTDataInflater.h:204
 AliHLTDataInflater.h:205
 AliHLTDataInflater.h:206
 AliHLTDataInflater.h:207
 AliHLTDataInflater.h:208
 AliHLTDataInflater.h:209
 AliHLTDataInflater.h:210
 AliHLTDataInflater.h:211
 AliHLTDataInflater.h:212
 AliHLTDataInflater.h:213
 AliHLTDataInflater.h:214
 AliHLTDataInflater.h:215
 AliHLTDataInflater.h:216
 AliHLTDataInflater.h:217
 AliHLTDataInflater.h:218
 AliHLTDataInflater.h:219
 AliHLTDataInflater.h:220
 AliHLTDataInflater.h:221
 AliHLTDataInflater.h:222
 AliHLTDataInflater.h:223
 AliHLTDataInflater.h:224
 AliHLTDataInflater.h:225
 AliHLTDataInflater.h:226
 AliHLTDataInflater.h:227
 AliHLTDataInflater.h:228
 AliHLTDataInflater.h:229
 AliHLTDataInflater.h:230
 AliHLTDataInflater.h:231
 AliHLTDataInflater.h:232
 AliHLTDataInflater.h:233
 AliHLTDataInflater.h:234
 AliHLTDataInflater.h:235
 AliHLTDataInflater.h:236
 AliHLTDataInflater.h:237