]> git.uio.no Git - u/mrichter/AliRoot.git/blob - HLT/BASE/AliHLTDataInflater.h
bugfix: printout using intermediate stringstream is not working, using cout directly...
[u/mrichter/AliRoot.git] / HLT / BASE / AliHLTDataInflater.h
1 //-*- Mode: C++ -*-
2 // $Id$
3 #ifndef ALIHLTDATAINFLATER_H
4 #define ALIHLTDATAINFLATER_H
5 //* This file is property of and copyright by the ALICE HLT Project        * 
6 //* ALICE Experiment at CERN, All rights reserved.                         *
7 //* See cxx source for full Copyright notice                               *
8
9 /// @file   AliHLTDataInflater.h
10 /// @author Matthias Richter, Timm Steinbeck
11 /// @date   2011-08-10
12 /// @brief  Data inflater reading the bitstream from the AliHLTDataDeflater
13 /// @note   Code original from AliHLTTPCCompModelInflater
14
15 #include "AliHLTLogging.h"
16 #include "AliHLTDataTypes.h"
17 #include "AliHLTStdIncludes.h"
18
19 /**
20  * @class AliHLTDataInflater
21  * Data inflating interface to a bitstream encoded by AliHLTDataDeflater
22  *
23  * Setting up the data inflater:
24  * <pre>
25   AliHLTDataInflater inflater;
26   if (inflater.InitBitDataInput(pData, dataSize)<0) {
27     // can not initialize
28   }
29  * </pre>
30  *
31  * If the layout in the bitstream is known the parts of known bit length
32  * can be read by
33  * - InputBit(value)
34  * - InputBits(value, length)
35  *
36  * For inflating huffman encoded streams where the symbol length is unknown
37  * one has to read a fixed value, retrieve the symbol and rewind the stream.
38  * Example how to read a fixed number of bits from the stream and rewind
39  * after the length of the symbol has been determined.
40  * <pre>
41   AliHLTUInt64_t inputWord=0;
42   int inputLength=sizeof(inputWord)*8;
43   while (outClusterCnt<nofClusters && inflater.InputBits(inputWord, inputLength)) {
44     // check how many of the bits belong to the symbol and rewind the
45     // input stream
46     int symbolLength=...;
47     inputWord>>=(inputLength-symbolLength);
48     if (!inflater.RewindBitPosition(inputLength-symbolLength)) {
49       // some error
50       break;
51     }
52
53     // do something with data in input word
54
55     // check if there is less remaining data than the full input word bit length
56     UInt_t bytes=inflater.GetRemainingBitDataSizeBytes();
57     if (bytes>0 && bytes<=sizeof(inputWord)) {
58       // reading the last bytes
59       // available bits are determined by cuurent position+1 (because
60       // position 0 means 1 bit still available) and the bits in the
61       // available bytes
62       inputLength=inflater.GetCurrentBitInputPosition()+1+(bytes-1)*8;
63     }
64   }
65  * </pre>
66  * 
67  *
68  * @ingroup alihlt_base
69  */
70 class AliHLTDataInflater : public AliHLTLogging
71 {
72 public:
73   /// standard constructor
74   AliHLTDataInflater();
75   /// destructor
76   ~AliHLTDataInflater();
77
78   /** init inflater for reading
79    * @param input  AliHLTUInt8_t* pointer to input data
80    * @param inputSize UInt_t input data size
81    */
82   int InitBitDataInput(const AliHLTUInt8_t* input, UInt_t inputSize );
83
84   /** close inflater for reading */     
85   void CloseBitDataInput();
86       
87   /** function to get current byte input position 
88    * @return unsigned long value of current byte input position
89    */
90   unsigned long GetCurrentByteInputPosition() const
91   {
92     return (unsigned long)( fBitDataCurrentInput - fBitDataCurrentInputStart );
93   }
94
95   /** function to get current bit input position
96    * @return unsigned value of current bit input position
97    */
98   unsigned GetCurrentBitInputPosition() const
99   {
100     return fBitDataCurrentPosInWord;
101   }
102
103   /** function to get current input byte
104    * @return AliHLTUInt8_t value of current input byte
105    */
106   AliHLTUInt8_t GetCurrentInputByte() const
107   {
108     return fBitDataCurrentWord;
109   }
110
111   /** function to determine end of bit input
112    * @return boolean if end is reached or not
113    */
114   bool EndOfBitInput() const
115   {
116     return (fBitDataCurrentInput>=fBitDataCurrentInputEnd);
117   }
118       
119   /** function to get bit data input size bytes
120    * @return UInt_t value of bit data input size bytes
121    */
122   UInt_t GetBitDataInputSizeBytes() const
123   {
124     return fBitDataCurrentInput-fBitDataCurrentInputStart;
125   }
126
127   /** get number of remaining input bytes
128    * the last byte might be already partially read, use
129    * GetCurrentBitInputPosition()
130    */
131   UInt_t GetRemainingBitDataSizeBytes() const
132   {
133     return fBitDataCurrentInputEnd-fBitDataCurrentInput;
134   }
135
136   /** function to determine input bit
137    * @return boolean (if bit is 1 or 0)
138    */
139   bool InputBit( AliHLTUInt8_t & value );
140
141   /** function to read bits from bitstream
142    * @param value
143    * @param bitCount
144    * @return boolean 
145    */
146   template<typename T>
147   bool InputBits( T & value, UInt_t const & bitCount );
148
149   /**
150    * Rewind the current bit position by the given number of bits.
151    */
152   bool RewindBitPosition(UInt_t const & bitCount);
153  
154   /** function pad 8 bits */
155   void Pad8Bits();
156
157   /** function to determine input bytes
158    * @param data       AliHLTUInt8_t* pointer to input data
159    * @param byteCount  UInt_t const &
160    * @return boolean
161    */
162   bool InputBytes( AliHLTUInt8_t* data, UInt_t const & byteCount );
163
164   /// clear the object and reset pointer references
165   virtual void Clear(Option_t * /*option*/ ="");
166
167   /// print info
168   virtual void Print(Option_t *option="") const;
169
170   /// print info
171   virtual void Print(ostream& out, Option_t *option="") const;
172
173 protected:
174 private:
175   /** copy constructor prohibited */
176   AliHLTDataInflater(const AliHLTDataInflater&);
177   /** assignment operator prohibited */
178   AliHLTDataInflater& operator=(const AliHLTDataInflater&);
179
180   /** member variable for bit data current word */
181   AliHLTUInt8_t fBitDataCurrentWord; // member variable for bit data current word
182   /** member variable for bit data current position in word */
183   UInt_t fBitDataCurrentPosInWord;// member variable for bit data current position in word
184   /** member variable for bit data current input */
185   const AliHLTUInt8_t *fBitDataCurrentInput; // member variable for bit data current input
186   /** member variable for bit data current input start */
187   const AliHLTUInt8_t *fBitDataCurrentInputStart; // member variable for bit data current input star
188   /** member variable for bit data current input end */
189   const AliHLTUInt8_t *fBitDataCurrentInputEnd; // member variable for bit data current input end
190
191   ClassDef(AliHLTDataInflater, 0)
192 };
193
194 template<typename T>
195 bool AliHLTDataInflater::InputBits( T & value, UInt_t const & bitCount )
196 {
197   // read bits from the input stream into variable
198   if (bitCount>sizeof(T)*8) {
199     HLTFatal( "variable of type size %u too small to read %u bits", sizeof(T)*8, (unsigned)bitCount);
200     return false;
201   }
202   UInt_t bitsToRead=bitCount;
203   UInt_t curBitCount;
204   value = 0;
205   while ( bitsToRead>0 ) {
206     if ( fBitDataCurrentInput>=fBitDataCurrentInputEnd )
207       return false;
208     if ( bitsToRead >= fBitDataCurrentPosInWord+1 )
209       curBitCount = fBitDataCurrentPosInWord+1;
210     else
211       curBitCount = bitsToRead;
212     value = (value << curBitCount) | ( (fBitDataCurrentWord >> (fBitDataCurrentPosInWord-curBitCount+1)) & ((1 << curBitCount)-1) );
213     if ( fBitDataCurrentPosInWord < curBitCount ) {
214       fBitDataCurrentInput++;
215       fBitDataCurrentPosInWord = 7;
216       if ( fBitDataCurrentInput<fBitDataCurrentInputEnd ) {
217         fBitDataCurrentWord = *fBitDataCurrentInput;
218       }
219     }
220     else
221       fBitDataCurrentPosInWord -= curBitCount;
222     bitsToRead -= curBitCount;
223   }
224   return true;
225 }
226
227 ostream& operator<<(ostream &out, const AliHLTDataInflater& me);
228
229 #endif