ATLAS Offline Software
TPIntegerVector_p2.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 
6 #include <cstring>
7 #include <stdexcept>
8 
9 
10 inline
11 bool TPIntegerVector_p2::lastElement() const {
12  return m_storage->size() == (m_position>>1) + 1;
13 }
14 
15 inline
16 unsigned TPIntegerVector_p2::startPos() const {
17  return m_position? m_storage->m_endPos[m_position-1] : 0;
18 }
19 
20 inline
21 unsigned TPIntegerVector_p2::size() const {
22  return m_storage->m_endPos[m_position] - startPos();
23 }
24 
25 inline
26 unsigned TPIntegerVector_p2::reserved() const {
27  return m_storage->m_endPos[m_position+1] - startPos();
28 }
29 
30 inline
31 void TPIntegerVector_p2::resize( size_t new_size ) {
32  if( new_size > reserved() && !lastElement() )
33  throw std::runtime_error("TPIntegerVector_p2::resize() can only enlarge the last element beyond its reserved size");
34  size_t end = startPos() + new_size;
35  m_storage->m_endPos[m_position] = end;
36  if( lastElement() ) {
37  if( m_storage->m_endPos[m_position+1] < end )
38  m_storage->m_endPos[m_position+1] = end;
39  m_storage->m_data.resize( end );
40  }
41 }
42 
43 inline
44 void TPIntegerVector_p2::grow( const size_t diff ) {
45  resize( size() + diff );
46 }
47 
48 inline
49 void TPIntegerVector_p2::reserve( size_t new_size ) {
50  if( new_size > reserved() && !lastElement() )
51  throw std::runtime_error("TPIntegerVector_p2::reserve() can only enlarge the last element!");
52  if( size() >= new_size || !lastElement() )
53  return;
54  size_t end = startPos() + new_size;
55  m_storage->m_endPos[m_position+1] = end;
56  m_storage->m_data.reserve( end );
57 }
58 
59 
60 
61 inline
62 TPIntegerVector_p2::value_type&
63 TPIntegerVector_p2::operator[]( size_t idx ) {
64  return const_cast<value_type&>(((const TPIntegerVector_p2*)this)->operator[](idx));
65 }
66 
67 inline
68 const TPIntegerVector_p2::value_type&
69 TPIntegerVector_p2::operator[]( size_t idx ) const {
70  return m_storage->m_data[ startPos() + idx ];
71 }
72 
73 
74 
75 inline
76 void TPIntegerVector_p2::push_back( const value_type& val )
77 {
78  resize( size() + 1 );
79  m_storage->m_data[ m_storage->m_endPos[m_position] - 1 ] = val;
80 }
81 
82 
83 inline
84 void TPIntegerVector_p2::push_int( const int& val )
85 {
86  push_back( (value_type)val );
87 }
88 
89 
90 inline
91 void TPIntegerVector_p2::push_float( const float& val )
92 {
93  union {unsigned int i; float f;} m_union;
94  m_union.f = val;
95  push_back( m_union.i );
96 }
97 
98 
99 inline
100 void TPIntegerVector_p2::push_double( const double& val )
101 {
102  union {struct{unsigned int i1;unsigned int i2;} c; double d;} m_union;
103  m_union.d = val;
104  push_back( m_union.c.i1 );
105  push_back( m_union.c.i2 );
106 }
107 
108 inline void
109 TPIntegerVector_p2::push_chars( const char * const s )
110 {
111  _store_bytes( (void*)s, strlen(s)+1 );
112 }
113 
114 
115 inline void
116 TPIntegerVector_p2::push_string( const std::string& str )
117 {
118  push_chars( str.c_str() );
119 }
120 
121 
122 inline void
123 TPIntegerVector_p2::push_bytes( const void * bytes, size_t bytelen )
124 {
125  push_back( bytelen );
126  _store_bytes( bytes, bytelen);
127 }
128 
129 
130 inline void
131 TPIntegerVector_p2::_store_bytes( const void * buff, size_t bytelen )
132 {
133  size_t intlen( size_for_blob(bytelen) - 1 );
134  grow( intlen );
135  // need to grow first and take address later, because of possible memory reallocation
136  value_type& start = m_storage->m_data[ m_storage->m_endPos[m_position] - intlen ];
137  memcpy( (void*)&start, buff, bytelen );
138 }
139 
140 
141 
142 inline
143 void TPIntegerVector_p2::push_TPObjRef( const TPObjRef& val )
144 {
145  union {struct{unsigned short i1;unsigned short i2;} c; unsigned int I;} m_union;
146  m_union.c.i1 = val.topLevelCnvID();
147  m_union.c.i2 = val.typeID() & 0xFFFF;
148  push_back( m_union.I );
149  push_back( val.index());
150 }
151 
152 inline
153 void TPIntegerVector_p2::push_vTPObjRef( const std::vector<TPObjRef>& val )
154 {
155  size_t size = val.size();
156  push_back( size );
157  for( size_t i=0; i<size; i++ )
158  push_TPObjRef( val[i] );
159 }
160 
161 
162 template<typename T>
163 inline size_t
164 TPIntegerVector_p2::size_for( const T& obj )
165 {
166  return ( sizeof(obj) + sizeof(value_type)-1 ) / sizeof(value_type);
167 }
168 
169 
170 inline size_t
171 TPIntegerVector_p2::size_for( const char *s )
172 {
173  return strlen(s) / sizeof(value_type) + 1;
174 }
175 
176 inline size_t
177 TPIntegerVector_p2::size_for_ref( )
178 {
179  return ( sizeof(TPObjRef) + sizeof(value_type)-1 ) / sizeof(value_type);
180 }
181 
182 
183 
184 template<>
185 inline size_t
186 TPIntegerVector_p2::size_for( const std::string& str )
187 {
188  return str.length() / sizeof(value_type) + 1;
189 }
190 
191 inline size_t
192 TPIntegerVector_p2::size_for_blob( size_t blobsize )
193 {
194  return ( blobsize + sizeof(value_type)-1 ) / sizeof(value_type) + 1;
195 }
196 
197 
198 inline size_t
199 TPIntegerVector_p2::next_string_size( const TPIntegerVector_p2::const_iterator& iter ) const
200 {
201  return strlen( (const char *)&*iter );
202 }
203 
204 inline size_t
205 TPIntegerVector_p2::next_blob_size( const TPIntegerVector_p2::const_iterator& iter ) const
206 {
207  return (size_t)*iter;
208 }
209 
210 
211 
212 inline
213 const TPIntegerVector_p2::value_type&
214 TPIntegerVector_p2::next( TPIntegerVector_p2::const_iterator& iter ) const
215 {
216  return *iter++;
217 }
218 
219 
220 inline int
221 TPIntegerVector_p2::next_int( TPIntegerVector_p2::const_iterator& iter ) const
222 {
223  return (int)*iter++;
224 }
225 
226 
227 inline float
228 TPIntegerVector_p2::next_float( TPIntegerVector_p2::const_iterator& iter ) const
229 {
230  union {unsigned int i; float f;} m_union;
231  m_union.i = *iter++;
232  return m_union.f;
233 }
234 
235 inline double
236 TPIntegerVector_p2::next_double( TPIntegerVector_p2::const_iterator& iter ) const
237 {
238  union {struct{unsigned int i1;unsigned int i2;} c; double d;} m_union;
239  m_union.c.i1 = *iter++;
240  m_union.c.i2 = *iter++;
241  return m_union.d;
242 }
243 
244 inline TPObjRef
245 TPIntegerVector_p2::next_TPObjRef( TPIntegerVector_p2::const_iterator& iter ) const
246 {
247  union {struct{unsigned short i1;unsigned short i2;} c; unsigned int I;} m_union;
248  m_union.I = *iter++;
249  return TPObjRef(TPObjRef::typeID_t(m_union.c.i1, m_union.c.i2), (int)*iter++ );
250 }
251 
252 
253 inline void
254 TPIntegerVector_p2::next_chars( TPIntegerVector_p2::const_iterator& iter, char *buff, size_t bufflen ) const
255 {
256  const char *s = (const char *)&*iter;
257  size_t slen = strlen(s);
258  iter += slen/sizeof(value_type) + 1;
259  assert( bufflen > slen );
260  if( bufflen <= slen) slen = bufflen-1;
261  memcpy( (void*)buff, (void*)s, slen+1 );
262 }
263 
264 inline std::string
265 TPIntegerVector_p2::next_string( const_iterator& iter ) const
266 {
267  const char *s = (const char *)&*iter;
268  iter += strlen(s) / sizeof(value_type) + 1;
269  return std::string( s );
270 }
271 
272 
273 inline void
274 TPIntegerVector_p2::next_bytes( TPIntegerVector_p2::const_iterator& iter, void *buff, size_t bufflen ) const
275 {
276  value_type size = *iter++;
277  const void *b = &*iter;
278  iter += size/sizeof(value_type);
279  assert( bufflen >= size );
280  if( bufflen < size) size = bufflen;
281  memcpy( buff, b, size );
282 }
283 
284 
285 inline
286 void TPIntegerVector_p2::next_vTPObjRef( TPIntegerVector_p2::const_iterator& iter, std::vector<TPObjRef>& refs ) const
287 {
288  value_type size = *iter++;
289  refs.clear();
290  refs.reserve( size );
291  for( value_type i=0; i<size; i++ )
292  refs.push_back( next_TPObjRef(iter) );
293 }
294