ATLAS Offline Software
Loading...
Searching...
No Matches
PackedConverter.icc
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
3*/
4/**
5 * @file AthContainers/PackedConverter.icc
6 * @author scott snyder <snyder@bnl.gov>
7 * @date Nov, 2014
8 * @brief Helper for packing/unpacking a @c PackedContainer to/from a stream.
9 */
10
11
12namespace SG {
13
14
15/**
16 * @brief Pack a vector to the stream.
17 * @param nelt Number of elements to pack.
18 * @param vec Vector of elements to pack.
19 * @param stream Destination stream.
20 */
21template <class U, class ALLOC, class STREAM>
22inline
23void PackedConverter::write (size_t nelt,
24 const std::vector<U, ALLOC>& vec,
25 STREAM& stream)
26{
27 // Dispatch on number of bits and on type.
28 switch (m_parms.nbits()) {
29 case 8:
30 if (m_parms.isFloat())
31 writeFloat<CxxUtils::BitPacker8> (nelt, vec, stream);
32 else if (m_parms.isSigned())
33 writeSigned<CxxUtils::BitPacker8> (nelt, vec, stream);
34 else
35 writeUnsigned<CxxUtils::BitPacker8> (nelt, vec, stream);
36 break;
37
38 case 16:
39 if (m_parms.isFloat())
40 writeFloat<CxxUtils::BitPacker16> (nelt, vec, stream);
41 else if (m_parms.isSigned())
42 writeSigned<CxxUtils::BitPacker16> (nelt, vec, stream);
43 else
44 writeUnsigned<CxxUtils::BitPacker16> (nelt, vec, stream);
45 break;
46
47 default:
48 if (m_parms.isFloat())
49 writeFloat<CxxUtils::BitPacker> (nelt, vec, stream);
50 else if (m_parms.isSigned())
51 writeSigned<CxxUtils::BitPacker> (nelt, vec, stream);
52 else
53 writeUnsigned<CxxUtils::BitPacker> (nelt, vec, stream);
54 break;
55 }
56}
57
58
59/**
60 * @brief Pack a nested vector to the stream.
61 * @param nelt Number of elements to pack.
62 * @param vec Vector of elements to pack.
63 * @param stream Destination stream.
64 */
65template <class U, class ALLOC1, class ALLOC2, class STREAM>
66inline
67void PackedConverter::write (size_t nelt,
68 const std::vector<std::vector<U, ALLOC1>, ALLOC2>& vec,
69 STREAM& stream)
70{
71 for (size_t i = 0; i < nelt; i++) {
72 size_t n = vec[i].size();
73 stream << static_cast<uint32_t>(n);
74 this->write (n, vec[i], stream);
75 }
76}
77
78
79/**
80 * @brief Unpack a vector from the stream.
81 * @param nelt Number of elements to unpack.
82 * @param vec Vector to receive the unpacked elements.
83 * @param stream Source stream.
84 */
85template <class U, class ALLOC, class STREAM>
86inline
87void PackedConverter::read (size_t nelt,
88 std::vector<U, ALLOC>& vec,
89 STREAM& stream)
90{
91 vec.clear();
92 vec.reserve (nelt);
93
94 // Dispatch on number of bits and on type.
95 switch (m_parms.nbits()) {
96 case 8:
97 if (m_parms.isFloat())
98 readFloat<CxxUtils::BitUnpacker8> (nelt, vec, stream);
99 else if (m_parms.isSigned())
100 readSigned<CxxUtils::BitUnpacker8> (nelt, vec, stream);
101 else
102 readUnsigned<CxxUtils::BitUnpacker8> (nelt, vec, stream);
103 break;
104
105 case 16:
106 if (m_parms.isFloat())
107 readFloat<CxxUtils::BitUnpacker16> (nelt, vec, stream);
108 else if (m_parms.isSigned())
109 readSigned<CxxUtils::BitUnpacker16> (nelt, vec, stream);
110 else
111 readUnsigned<CxxUtils::BitUnpacker16> (nelt, vec, stream);
112 break;
113
114 default:
115 if (m_parms.isFloat())
116 readFloat<CxxUtils::BitUnpacker> (nelt, vec, stream);
117 else if (m_parms.isSigned())
118 readSigned<CxxUtils::BitUnpacker> (nelt, vec, stream);
119 else
120 readUnsigned<CxxUtils::BitUnpacker> (nelt, vec, stream);
121 break;
122 }
123}
124
125
126/**
127 * @brief Unpack a nested vector from the stream.
128 * @param nelt Number of elements to unpack.
129 * @param vec Vector to receive the unpacked elements.
130 * @param stream Source stream.
131 */
132template <class U, class ALLOC1, class ALLOC2, class STREAM>
133inline
134void PackedConverter::read (size_t nelt,
135 std::vector<std::vector<U, ALLOC1>, ALLOC2>& vec,
136 STREAM& stream)
137{
138 vec.resize (nelt);
139 for (size_t i = 0; i < nelt; i++) {
140 uint32_t n;
141 stream >> n;
142 this->read (n, vec[i], stream);
143 }
144}
145
146
147/**
148 * @brief Pack a vector of unsigned values to the stream.
149 * @param nelt Number of elements to pack.
150 * @param vec Vector of elements to pack.
151 * @param stream Destination stream.
152 */
153template <template<class> class PACKER, class U, class ALLOC, class STREAM>
154inline
155void PackedConverter::writeUnsigned (size_t nelt,
156 const std::vector<U, ALLOC>& vec,
157 STREAM& stream)
158{
159 uint8_t nbits = m_parms.nbits();
160 PACKER<STREAM> packer (nbits, stream);
161 uint32_t mask = CxxUtils::ones<uint32_t> (nbits);
162 for (size_t i = 0; i < nelt; ++i)
163 packer.pack (static_cast<uint32_t>(vec[i]) & mask);
164}
165
166
167/**
168 * @brief Pack a vector of signed values to the stream.
169 * @param nelt Number of elements to pack.
170 * @param vec Vector of elements to pack.
171 * @param stream Destination stream.
172 */
173template <template<class> class PACKER, class U, class ALLOC, class STREAM>
174inline
175void PackedConverter::writeSigned (size_t nelt,
176 const std::vector<U, ALLOC>& vec,
177 STREAM& stream)
178{
179 uint8_t nbits = m_parms.nbits();
180 PACKER<STREAM> packer (nbits, stream);
181 uint32_t mask = CxxUtils::ones<uint32_t> (nbits);
182 uint32_t sgnmask = ~ CxxUtils::ones<uint32_t> (nbits-1);
183 for (size_t i = 0; i < nelt; ++i) {
184 U val = vec[i];
185 uint32_t uval = static_cast<uint32_t> (val);
186 uint32_t m = uval & sgnmask;
187 if (m == 0 || m == sgnmask)
188 packer.pack (uval & mask);
189 else if (val > 0)
190 packer.pack (~sgnmask); // Largest + number
191 else
192 packer.pack (sgnmask & mask); // Largest - number
193 }
194}
195
196
197/**
198 * @brief Pack a vector of float values to the stream.
199 * @param nelt Number of elements to pack.
200 * @param vec Vector of elements to pack.
201 * @param stream Destination stream.
202 */
203template <template<class> class PACKER, class U, class ALLOC, class STREAM>
204inline
205void PackedConverter::writeFloat (size_t nelt,
206 const std::vector<U, ALLOC>& vec,
207 STREAM& stream)
208{
209 uint8_t nbits = m_parms.nbits();
210 PACKER<STREAM> packer (nbits, stream);
211 for (size_t i = 0; i < nelt; ++i)
212 packer.pack (m_packer.pack (vec[i]));
213}
214
215
216
217/**
218 * @brief Unpack a vector of unsigned values from the stream.
219 * @param nelt Number of elements to unpack.
220 * @param vec Vector to receive the unpacked elements.
221 * @param stream Source stream.
222 */
223template <template<class> class UNPACKER, class U, class ALLOC, class STREAM>
224void PackedConverter::readUnsigned (size_t nelt,
225 std::vector<U, ALLOC>& vec,
226 STREAM& stream)
227{
228 uint8_t nbits = m_parms.nbits();
229 UNPACKER<STREAM> unpacker (nbits, stream);
230 for (size_t i = 0; i < nelt; ++i)
231 vec.push_back (static_cast<U> (unpacker.unpack()));
232}
233
234
235/**
236 * @brief Unpack a vector of signed values from the stream.
237 * @param nelt Number of elements to unpack.
238 * @param vec Vector to receive the unpacked elements.
239 * @param stream Source stream.
240 */
241template <template<class> class UNPACKER, class U, class ALLOC, class STREAM>
242void PackedConverter::readSigned (size_t nelt,
243 std::vector<U, ALLOC>& vec,
244 STREAM& stream)
245{
246 uint8_t nbits = m_parms.nbits();
247 uint32_t sgnmask = ~ CxxUtils::ones<uint32_t> (nbits-1);
248 UNPACKER<STREAM> unpacker (nbits, stream);
249 for (size_t i = 0; i < nelt; ++i) {
250 uint32_t val = unpacker.unpack();
251 if (val & sgnmask)
252 val |= sgnmask; // Sign-extend.
253 vec.push_back (static_cast<U> (val));
254 }
255}
256
257
258/**
259 * @brief Unpack a vector of floating-point values from the stream.
260 * @param nelt Number of elements to unpack.
261 * @param vec Vector to receive the unpacked elements.
262 * @param stream Source stream.
263 */
264template <template<class> class UNPACKER, class U, class ALLOC, class STREAM>
265void PackedConverter::readFloat (size_t nelt,
266 std::vector<U, ALLOC>& vec,
267 STREAM& stream)
268{
269 uint8_t nbits = m_parms.nbits();
270 UNPACKER<STREAM> unpacker (nbits, stream);
271 for (size_t i = 0; i < nelt; ++i)
272 vec.push_back (static_cast<U> (m_packer.unpack (unpacker.unpack())));
273}
274
275
276} // namespace SG