]> git.uio.no Git - u/mrichter/AliRoot.git/blob - HLT/BASE/AliHLTDataDeflater.cxx
forgot to commit change in header file in r52974
[u/mrichter/AliRoot.git] / HLT / BASE / AliHLTDataDeflater.cxx
1 // $Id$
2
3 //**************************************************************************
4 //* This file is property of and copyright by the ALICE HLT Project        * 
5 //* ALICE Experiment at CERN, All rights reserved.                         *
6 //*                                                                        *
7 //* Primary Authors: Matthias Richter <Matthias.Richter@ift.uib.no>        *
8 //*                  for The ALICE HLT Project.                            *
9 //*                                                                        *
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 //**************************************************************************
18
19 /// @file   AliHLTDataDeflater.cxx
20 /// @author Matthias Richter, Timm Steinbeck
21 /// @date   2011-08-10
22 /// @brief  Data deflater class storing only necessary bits
23 /// @note   Code original from AliHLTTPCCompModelDeflater
24
25 #include "AliHLTDataDeflater.h"
26 #include "AliHLTErrorGuard.h"
27 #include <memory>
28 #include <algorithm>
29 #include <iostream>
30
31 /** ROOT macro for the implementation of ROOT specific class methods */
32 ClassImp(AliHLTDataDeflater)
33
34 AliHLTDataDeflater::AliHLTDataDeflater()
35   : AliHLTLogging()
36   , fBitDataCurrentWord(0)
37   , fBitDataCurrentPosInWord(0)
38   , fBitDataCurrentOutput(NULL)
39   , fBitDataCurrentOutputStart(NULL)
40   , fBitDataCurrentOutputEnd(NULL)
41 {
42   // see header file for class documentation
43   // or
44   // refer to README to build package
45   // or
46   // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
47 }
48
49 AliHLTDataDeflater::~AliHLTDataDeflater()
50 {
51   // destructor
52   Clear();
53 }
54
55 int AliHLTDataDeflater::InitBitDataOutput( AliHLTUInt8_t* output, UInt_t outputSize)
56 {
57   // init the target buffer
58   fBitDataCurrentWord = 0;
59   fBitDataCurrentPosInWord = 7;
60   fBitDataCurrentOutput = fBitDataCurrentOutputStart = output;
61   fBitDataCurrentOutputEnd = output+outputSize;
62
63   return 0;
64 }
65
66 void AliHLTDataDeflater::CloseBitDataOutput()
67 {
68   // pad to full byte and clear internal pointer references
69   Pad8Bits();
70   fBitDataCurrentWord=0;
71   fBitDataCurrentPosInWord=0;
72   fBitDataCurrentOutput=NULL;
73   fBitDataCurrentOutputStart=NULL;
74   fBitDataCurrentOutputEnd=NULL;
75 }
76
77 AliHLTUInt8_t AliHLTDataDeflater::GetCurrentOutputByte( Int_t offset ) const
78 {
79   // get the current byte
80   if ( !offset )
81     return fBitDataCurrentWord;
82   else
83     return *(fBitDataCurrentOutput+offset);
84 }
85
86 bool AliHLTDataDeflater::OutputBit( AliHLTUInt32_t const & value )
87 {
88   // write one bit to the current byte and position
89   if ( fBitDataCurrentOutput>=fBitDataCurrentOutputEnd )
90     return false;
91   fBitDataCurrentWord |= (value & 1) << fBitDataCurrentPosInWord;
92   if ( fBitDataCurrentPosInWord )
93     fBitDataCurrentPosInWord--;
94   else {
95     *fBitDataCurrentOutput = fBitDataCurrentWord;
96     fBitDataCurrentPosInWord = 7;
97     fBitDataCurrentOutput++;
98     fBitDataCurrentWord = 0;
99   }
100   return true;
101 }
102
103 bool AliHLTDataDeflater::OutputBits( AliHLTUInt64_t const & value, UInt_t const & bitCount )
104 {
105   // write bit pattern to the current byte and position
106   if ( bitCount>64 ) {
107     HLTFatal( "Internal error: Attempt to write more than 64 bits (%u)", (unsigned)bitCount );
108     return false;
109   }
110   UInt_t bitsToWrite=bitCount;
111   UInt_t curBitCount;
112   while ( bitsToWrite>0 ) {
113     if ( fBitDataCurrentOutput>=fBitDataCurrentOutputEnd )
114       return false;
115 #if 1
116     if ( bitsToWrite >= fBitDataCurrentPosInWord+1 )
117       curBitCount = fBitDataCurrentPosInWord+1;
118     else
119       curBitCount = bitsToWrite;
120     fBitDataCurrentWord |= ( (value >> (bitsToWrite-curBitCount)) & ((1<<curBitCount)-1) ) << (fBitDataCurrentPosInWord+1-curBitCount);
121     if ( fBitDataCurrentPosInWord < curBitCount )
122       {
123         *fBitDataCurrentOutput = fBitDataCurrentWord;
124         fBitDataCurrentPosInWord = 7;
125         fBitDataCurrentOutput++;
126         fBitDataCurrentWord = 0;
127       }
128     else
129       fBitDataCurrentPosInWord -= curBitCount;
130     bitsToWrite -= curBitCount;
131
132 #else
133     AliHLTUInt8_t curValue;
134     if ( bitsToWrite>=8 )
135       {
136         curBitCount=8;
137         curValue = (value >> bitsToWrite-8) & 0xFF;
138         bitsToWrite -= 8;
139       }
140     else
141       {
142         curBitCount=bitsToWrite;
143         curValue = value & ( (1<<bitsToWrite)-1 );
144         bitsToWrite = 0;
145       }
146     if ( fBitDataCurrentPosInWord+1>curBitCount )
147       {
148         fBitDataCurrentWord |= curValue << (fBitDataCurrentPosInWord-curBitCount+1);
149         fBitDataCurrentPosInWord -= curBitCount;
150       }
151     else if ( fBitDataCurrentPosInWord+1==curBitCount )
152       {
153         fBitDataCurrentWord |= curValue;
154         *fBitDataCurrentOutput = fBitDataCurrentWord;
155         fBitDataCurrentPosInWord = 7;
156         fBitDataCurrentOutput++;
157         fBitDataCurrentWord = 0;
158       }
159     else
160       {
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 )
167           return false;
168         fBitDataCurrentWord = curValue & ((1<<second)-1) << (8-second);
169         fBitDataCurrentPosInWord = 7-second;
170       }
171 #endif
172   }
173   return true;
174 }
175
176 bool AliHLTDataDeflater::OutputBits( std::bitset<64> const & value, UInt_t const & bitCount )
177 {
178   // write bit pattern to the current byte and position
179   if ( bitCount>64 ) {
180     HLTFatal( "Internal error: Attempt to write more than 64 bits (%u)", (unsigned)bitCount );
181     return false;
182   }
183   static const std::bitset<64> mask8bit(255ul);
184   UInt_t bitsToWrite=bitCount;
185   UInt_t curBitCount;
186   while ( bitsToWrite>0 ) {
187     if ( fBitDataCurrentOutput>=fBitDataCurrentOutputEnd )
188       return false;
189     if ( bitsToWrite >= fBitDataCurrentPosInWord+1 )
190       curBitCount = fBitDataCurrentPosInWord+1;
191     else
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 )
196       {
197         *fBitDataCurrentOutput = fBitDataCurrentWord;
198         fBitDataCurrentPosInWord = 7;
199         fBitDataCurrentOutput++;
200         fBitDataCurrentWord = 0;
201       }
202     else
203       fBitDataCurrentPosInWord -= curBitCount;
204     bitsToWrite -= curBitCount;
205   }
206   return true;
207 }
208
209 void AliHLTDataDeflater::Pad8Bits()
210 {
211   // finish the current word
212   if ( fBitDataCurrentPosInWord==7 )
213     return;
214   *fBitDataCurrentOutput = fBitDataCurrentWord;
215   fBitDataCurrentPosInWord = 7;
216   fBitDataCurrentOutput++;
217   fBitDataCurrentWord = 0;
218 }
219
220 bool AliHLTDataDeflater::OutputBytes( AliHLTUInt8_t const * data, UInt_t const & byteCount )
221 {
222   // write sequence of bytes
223   Pad8Bits();
224   if ( fBitDataCurrentOutput+byteCount>fBitDataCurrentOutputEnd )
225     return false;
226   memcpy( fBitDataCurrentOutput, data, byteCount );
227   fBitDataCurrentOutput += byteCount;
228   return true;
229 }
230
231 bool AliHLTDataDeflater::OutputParameterBits( int /*(parameterId*/, AliHLTUInt64_t const & /*value*/ )
232 {
233   // write bit pattern of a member to the current byte and position
234   ALIHLTERRORGUARD(1,"method needs to be implemented in child class");
235   return false;
236 }
237
238 void AliHLTDataDeflater::Clear(Option_t * /*option*/)
239 {
240   // internal cleanup
241 }
242
243 void AliHLTDataDeflater::Print(Option_t *option) const
244 {
245   // print info
246   Print(cout, option);
247 }
248
249 void AliHLTDataDeflater::Print(ostream& out, Option_t */*option*/) const
250 {
251   // print to stream
252   out << "AliHLTDataDeflater: " << endl;
253 }
254
255 ostream& operator<<(ostream &out, const AliHLTDataDeflater& me)
256 {
257   me.Print(out);
258   return out;
259 }