3 //**************************************************************************
4 //* This file is property of and copyright by the ALICE HLT Project *
5 //* ALICE Experiment at CERN, All rights reserved. *
7 //* Primary Authors: Matthias Richter <Matthias.Richter@ift.uib.no> *
8 //* for The ALICE HLT Project. *
10 //* Permission to use, copy, modify and distribute this software and its *
11 //* documentation strictly for non-commercial purposes is hereby granted *
12 //* without fee, provided that the above copyright notice appears in all *
13 //* copies and that both the copyright notice and this permission notice *
14 //* appear in the supporting documentation. The authors make no claims *
15 //* about the suitability of this software for any purpose. It is *
16 //* provided "as is" without express or implied warranty. *
17 //**************************************************************************
19 /// @file AliHLTDataDeflater.cxx
20 /// @author Matthias Richter, Timm Steinbeck
22 /// @brief Data deflater class storing only necessary bits
23 /// @note Code original from AliHLTTPCCompModelDeflater
25 #include "AliHLTDataDeflater.h"
26 #include "AliHLTErrorGuard.h"
31 /** ROOT macro for the implementation of ROOT specific class methods */
32 ClassImp(AliHLTDataDeflater)
34 AliHLTDataDeflater::AliHLTDataDeflater()
36 , fBitDataCurrentWord(0)
37 , fBitDataCurrentPosInWord(0)
38 , fBitDataCurrentOutput(NULL)
39 , fBitDataCurrentOutputStart(NULL)
40 , fBitDataCurrentOutputEnd(NULL)
42 // see header file for class documentation
44 // refer to README to build package
46 // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
49 AliHLTDataDeflater::~AliHLTDataDeflater()
55 int AliHLTDataDeflater::InitBitDataOutput( AliHLTUInt8_t* output, UInt_t outputSize)
57 // init the target buffer
58 fBitDataCurrentWord = 0;
59 fBitDataCurrentPosInWord = 7;
60 fBitDataCurrentOutput = fBitDataCurrentOutputStart = output;
61 fBitDataCurrentOutputEnd = output+outputSize;
66 void AliHLTDataDeflater::CloseBitDataOutput()
68 // pad to full byte and clear internal pointer references
70 fBitDataCurrentWord=0;
71 fBitDataCurrentPosInWord=0;
72 fBitDataCurrentOutput=NULL;
73 fBitDataCurrentOutputStart=NULL;
74 fBitDataCurrentOutputEnd=NULL;
77 AliHLTUInt8_t AliHLTDataDeflater::GetCurrentOutputByte( Int_t offset ) const
79 // get the current byte
81 return fBitDataCurrentWord;
83 return *(fBitDataCurrentOutput+offset);
86 bool AliHLTDataDeflater::OutputBit( AliHLTUInt32_t const & value )
88 // write one bit to the current byte and position
89 if ( fBitDataCurrentOutput>=fBitDataCurrentOutputEnd )
91 fBitDataCurrentWord |= (value & 1) << fBitDataCurrentPosInWord;
92 if ( fBitDataCurrentPosInWord )
93 fBitDataCurrentPosInWord--;
95 *fBitDataCurrentOutput = fBitDataCurrentWord;
96 fBitDataCurrentPosInWord = 7;
97 fBitDataCurrentOutput++;
98 fBitDataCurrentWord = 0;
103 bool AliHLTDataDeflater::OutputBits( AliHLTUInt64_t const & value, UInt_t const & bitCount )
105 // write bit pattern to the current byte and position
107 HLTFatal( "Internal error: Attempt to write more than 64 bits (%u)", (unsigned)bitCount );
110 UInt_t bitsToWrite=bitCount;
112 while ( bitsToWrite>0 ) {
113 if ( fBitDataCurrentOutput>=fBitDataCurrentOutputEnd )
116 if ( bitsToWrite >= fBitDataCurrentPosInWord+1 )
117 curBitCount = fBitDataCurrentPosInWord+1;
119 curBitCount = bitsToWrite;
120 fBitDataCurrentWord |= ( (value >> (bitsToWrite-curBitCount)) & ((1<<curBitCount)-1) ) << (fBitDataCurrentPosInWord+1-curBitCount);
121 if ( fBitDataCurrentPosInWord < curBitCount )
123 *fBitDataCurrentOutput = fBitDataCurrentWord;
124 fBitDataCurrentPosInWord = 7;
125 fBitDataCurrentOutput++;
126 fBitDataCurrentWord = 0;
129 fBitDataCurrentPosInWord -= curBitCount;
130 bitsToWrite -= curBitCount;
133 AliHLTUInt8_t curValue;
134 if ( bitsToWrite>=8 )
137 curValue = (value >> bitsToWrite-8) & 0xFF;
142 curBitCount=bitsToWrite;
143 curValue = value & ( (1<<bitsToWrite)-1 );
146 if ( fBitDataCurrentPosInWord+1>curBitCount )
148 fBitDataCurrentWord |= curValue << (fBitDataCurrentPosInWord-curBitCount+1);
149 fBitDataCurrentPosInWord -= curBitCount;
151 else if ( fBitDataCurrentPosInWord+1==curBitCount )
153 fBitDataCurrentWord |= curValue;
154 *fBitDataCurrentOutput = fBitDataCurrentWord;
155 fBitDataCurrentPosInWord = 7;
156 fBitDataCurrentOutput++;
157 fBitDataCurrentWord = 0;
161 const UInt_t first = fBitDataCurrentPosInWord+1; // Number of bits for first block
162 const UInt_t second = curBitCount-first; // Number of bits for second block
163 fBitDataCurrentWord |= ( curValue >> second ) & ((1<<first)-1);
164 *fBitDataCurrentOutput = fBitDataCurrentWord;
165 fBitDataCurrentOutput++;
166 if ( fBitDataCurrentOutput>=fBitDataCurrentOutputEnd )
168 fBitDataCurrentWord = curValue & ((1<<second)-1) << (8-second);
169 fBitDataCurrentPosInWord = 7-second;
176 bool AliHLTDataDeflater::OutputBits( std::bitset<64> const & value, UInt_t const & bitCount )
178 // write bit pattern to the current byte and position
180 HLTFatal( "Internal error: Attempt to write more than 64 bits (%u)", (unsigned)bitCount );
183 static const std::bitset<64> mask8bit(255ul);
184 UInt_t bitsToWrite=bitCount;
186 while ( bitsToWrite>0 ) {
187 if ( fBitDataCurrentOutput>=fBitDataCurrentOutputEnd )
189 if ( bitsToWrite >= fBitDataCurrentPosInWord+1 )
190 curBitCount = fBitDataCurrentPosInWord+1;
192 curBitCount = bitsToWrite;
193 std::bitset<64> valwrite=(value >> (bitsToWrite-curBitCount)) & mask8bit;
194 fBitDataCurrentWord |= ( valwrite.to_ulong() & ((1<<curBitCount)-1) ) << (fBitDataCurrentPosInWord+1-curBitCount);
195 if ( fBitDataCurrentPosInWord < curBitCount )
197 *fBitDataCurrentOutput = fBitDataCurrentWord;
198 fBitDataCurrentPosInWord = 7;
199 fBitDataCurrentOutput++;
200 fBitDataCurrentWord = 0;
203 fBitDataCurrentPosInWord -= curBitCount;
204 bitsToWrite -= curBitCount;
209 void AliHLTDataDeflater::Pad8Bits()
211 // finish the current word
212 if ( fBitDataCurrentPosInWord==7 )
214 *fBitDataCurrentOutput = fBitDataCurrentWord;
215 fBitDataCurrentPosInWord = 7;
216 fBitDataCurrentOutput++;
217 fBitDataCurrentWord = 0;
220 bool AliHLTDataDeflater::OutputBytes( AliHLTUInt8_t const * data, UInt_t const & byteCount )
222 // write sequence of bytes
224 if ( fBitDataCurrentOutput+byteCount>fBitDataCurrentOutputEnd )
226 memcpy( fBitDataCurrentOutput, data, byteCount );
227 fBitDataCurrentOutput += byteCount;
231 bool AliHLTDataDeflater::OutputParameterBits( int /*(parameterId*/, AliHLTUInt64_t const & /*value*/ )
233 // write bit pattern of a member to the current byte and position
234 ALIHLTERRORGUARD(1,"method needs to be implemented in child class");
238 void AliHLTDataDeflater::Clear(Option_t * /*option*/)
243 void AliHLTDataDeflater::Print(Option_t *option) const
249 void AliHLTDataDeflater::Print(ostream& out, Option_t */*option*/) const
252 out << "AliHLTDataDeflater: " << endl;
255 ostream& operator<<(ostream &out, const AliHLTDataDeflater& me)