ATLAS Offline Software
Loading...
Searching...
No Matches
BitUnpacker.icc
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
3*/
4
5// $Id$
6/**
7 * @file CxxUtils/BitUnpacker.icc
8 * @author scott snyder <snyder@bnl.gov>
9 * @date Nov, 2014
10 * @brief Helper to unpack a set of values bitwise from a stream.
11 */
12
13
14#include "CxxUtils/ones.h"
15
16
17namespace CxxUtils {
18
19
20/**
21 * @brief Constructor.
22 * @param nbits Number of bits per item to use in the packed representation.
23 * @param stream Input stream object.
24 */
25template <class STREAM>
26inline
27BitUnpacker<STREAM>::BitUnpacker (uint8_t nbits, STREAM& stream)
28 : m_buf(0),
29 m_nbuf(0),
30 m_nbits(nbits),
31 m_stream (stream),
32 m_mask (CxxUtils::ones<uint32_t>(nbits))
33{
34 assert (m_nbits > 0 && m_nbits <= 32);
35}
36
37
38/**
39 * @brief Unpack one value from the stream.
40 */
41template <class STREAM>
42inline
43uint32_t BitUnpacker<STREAM>::unpack()
44{
45 const uint8_t totbits = 8*sizeof(m_buf);
46
47 if (m_nbuf == 0) {
48 m_stream >> m_buf;
49 m_nbuf = totbits;
50 }
51
52 uint32_t out = m_buf & m_mask;
53 if (m_nbits > m_nbuf) {
54 uint8_t nleft = m_nbits - m_nbuf;
55 m_stream >> m_buf;
56 out |= (m_buf & CxxUtils::ones<uint32_t>(nleft)) << m_nbuf;
57 m_buf >>= nleft;
58 m_nbuf = totbits - nleft;
59 }
60 else {
61 if (m_nbits >= 32)
62 m_buf = 0;
63 else
64 m_buf >>= m_nbits;
65 m_nbuf -= m_nbits;
66 }
67
68 return out;
69}
70
71
72/**
73 * @brief Constructor.
74 * @param stream Input stream object.
75 */
76template <class STREAM>
77inline
78BitUnpacker8<STREAM>::BitUnpacker8 (STREAM& stream)
79 : m_buf(0),
80 m_nbuf(0),
81 m_stream (stream)
82{
83}
84
85
86/**
87 * @brief Constructor.
88 * @param nbits Must be 8.
89 * @param stream Input stream object.
90 */
91template <class STREAM>
92inline
93BitUnpacker8<STREAM>::BitUnpacker8 (uint8_t /*nbits*/, STREAM& stream)
94 : m_buf(0),
95 m_nbuf(0),
96 m_stream (stream)
97{
98}
99
100
101/**
102 * @brief Unpack one value from the stream.
103 */
104template <class STREAM>
105inline
106uint32_t BitUnpacker8<STREAM>::unpack()
107{
108 if (m_nbuf == 0) {
109 m_stream >> m_buf;
110 m_nbuf = 4;
111 }
112
113 uint8_t ret = m_buf & 0xff;
114 m_buf >>= 8;
115 --m_nbuf;
116 return ret;
117}
118
119
120/**
121 * @brief Constructor.
122 * @param stream Input stream object.
123 */
124template <class STREAM>
125inline
126BitUnpacker16<STREAM>::BitUnpacker16 (STREAM& stream)
127 : m_buf(0),
128 m_nbuf(0),
129 m_stream (stream)
130{
131}
132
133
134/**
135 * @brief Constructor.
136 * @param nbits Must be 16.
137 * @param stream Input stream object.
138 */
139template <class STREAM>
140inline
141BitUnpacker16<STREAM>::BitUnpacker16 (uint8_t /*nbits*/, STREAM& stream)
142 : m_buf(0),
143 m_nbuf(0),
144 m_stream (stream)
145{
146}
147
148
149/**
150 * @brief Unpack one value from the stream.
151 */
152template <class STREAM>
153inline
154uint32_t BitUnpacker16<STREAM>::unpack()
155{
156 if (m_nbuf == 0) {
157 m_stream >> m_buf;
158 m_nbuf = 2;
159 }
160
161 uint16_t ret = m_buf & 0xffff;
162 m_buf >>= 16;
163 --m_nbuf;
164 return ret;
165}
166
167
168} // namespace CxxUtils
169
170