SHORE API
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
memops.hpp
Go to the documentation of this file.
1 
2 /*
3  * Copyright 2008,2009,2010,2011,2012 Stephan Ossowski, Korbinian Schneeberger,
4  * Felix Ott, Joerg Hagmann, Alf Scotland, Sebastian Bender
5  *
6  * This file is part of SHORE.
7  *
8  * SHORE is free software: you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation, either version 3 of the License, or
11  * (at your option) any later version.
12  *
13  * SHORE is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with SHORE. If not, see <http://www.gnu.org/licenses/>.
20  */
21 
25 
26 #ifndef SHORE_MISC_MEMOPS_HPP__
27 #define SHORE_MISC_MEMOPS_HPP__
28 
29 #include <iostream>
30 #include <vector>
31 
32 #include <boost/cstdint.hpp>
33 
34 #if defined (__GLIBC__)
35 # include <endian.h>
36 # if (__BYTE_ORDER == __LITTLE_ENDIAN)
37 # define SHORE_MEMOPS_IS_LITTLE_ENDIAN
38 # elif (__BYTE_ORDER == __BIG_ENDIAN)
39 # define SHORE_MEMOPS_IS_BIG_ENDIAN
40 # else
41 # error Unsupported machine endianness.
42 # endif
43 #elif defined(_BIG_ENDIAN) && !defined(_LITTLE_ENDIAN)
44 # define SHORE_MEMOPS_IS_BIG_ENDIAN
45 #elif defined(_LITTLE_ENDIAN) && !defined(_BIG_ENDIAN)
46 # define SHORE_MEMOPS_IS_LITTLE_ENDIAN
47 #elif defined(__sparc) || defined(__sparc__) \
48  || defined(_POWER) || defined(__powerpc__) \
49  || defined(__ppc__) || defined(__hpux) || defined(__hppa) \
50  || defined(_MIPSEB) || defined(_POWER) \
51  || defined(__s390__)
52 # define SHORE_MEMOPS_IS_BIG_ENDIAN
53 #elif defined(__i386__) || defined(__alpha__) \
54  || defined(__ia64) || defined(__ia64__) \
55  || defined(_M_IX86) || defined(_M_IA64) \
56  || defined(_M_ALPHA) || defined(__amd64) \
57  || defined(__amd64__) || defined(_M_AMD64) \
58  || defined(__x86_64) || defined(__x86_64__) \
59  || defined(_M_X64) || defined(__bfin__)
60 # define SHORE_MEMOPS_IS_LITTLE_ENDIAN
61 #else
62 # error Cannot determine endianness endianness.
63 #endif
64 
65 namespace shore {
66 
67 typedef boost::uint8_t uint8_t;
68 typedef boost::uint16_t uint16_t;
69 typedef boost::uint32_t uint32_t;
70 typedef boost::uint64_t uint64_t;
71 
73 template<class T,int SZ>
74 size_t size(T (&)[SZ])
75 {
76  return SZ;
77 }
78 
80 template<class T,int SZ>
81 T* end(T (&array)[SZ])
82 {
83  return array+size(array);
84 }
85 
87 std::ostream &memdump(std::ostream& os,const void* src,size_t n);
88 
90 void* bit_memcpy(
91  void*const dst,const void*const src,const size_t nbits,
92  const size_t dst_bitofs,const size_t src_bitofs=0);
93 
94 #ifndef SHORE_MEMOPS_IS_BIG_ENDIAN
95 
97 inline uint64_t ntoh64(const void*const netw64)
98 {
99  uint64_t ret;
100  reinterpret_cast<char*>(&ret)[0]=static_cast<const char*>(netw64)[7];
101  reinterpret_cast<char*>(&ret)[1]=static_cast<const char*>(netw64)[6];
102  reinterpret_cast<char*>(&ret)[2]=static_cast<const char*>(netw64)[5];
103  reinterpret_cast<char*>(&ret)[3]=static_cast<const char*>(netw64)[4];
104  reinterpret_cast<char*>(&ret)[4]=static_cast<const char*>(netw64)[3];
105  reinterpret_cast<char*>(&ret)[5]=static_cast<const char*>(netw64)[2];
106  reinterpret_cast<char*>(&ret)[6]=static_cast<const char*>(netw64)[1];
107  reinterpret_cast<char*>(&ret)[7]=static_cast<const char*>(netw64)[0];
108  return ret;
109 }
110 
112 inline uint32_t ntoh32(const void*const netw32)
113 {
114  uint32_t ret;
115  reinterpret_cast<char*>(&ret)[0]=static_cast<const char*>(netw32)[3];
116  reinterpret_cast<char*>(&ret)[1]=static_cast<const char*>(netw32)[2];
117  reinterpret_cast<char*>(&ret)[2]=static_cast<const char*>(netw32)[1];
118  reinterpret_cast<char*>(&ret)[3]=static_cast<const char*>(netw32)[0];
119  return ret;
120 }
121 
123 inline uint16_t ntoh16(const void*const netw16)
124 {
125  uint16_t ret;
126  reinterpret_cast<char*>(&ret)[0]=static_cast<const char*>(netw16)[1];
127  reinterpret_cast<char*>(&ret)[1]=static_cast<const char*>(netw16)[0];
128  return ret;
129 }
130 
132 inline uint64_t letoh64(const void*const le64)
133 {
134  uint64_t ret;
135  reinterpret_cast<char*>(&ret)[0]=static_cast<const char*>(le64)[0];
136  reinterpret_cast<char*>(&ret)[1]=static_cast<const char*>(le64)[1];
137  reinterpret_cast<char*>(&ret)[2]=static_cast<const char*>(le64)[2];
138  reinterpret_cast<char*>(&ret)[3]=static_cast<const char*>(le64)[3];
139  reinterpret_cast<char*>(&ret)[4]=static_cast<const char*>(le64)[4];
140  reinterpret_cast<char*>(&ret)[5]=static_cast<const char*>(le64)[5];
141  reinterpret_cast<char*>(&ret)[6]=static_cast<const char*>(le64)[6];
142  reinterpret_cast<char*>(&ret)[7]=static_cast<const char*>(le64)[7];
143  return ret;
144 }
145 
147 inline uint32_t letoh32(const void*const le32)
148 {
149  uint32_t ret;
150  reinterpret_cast<char*>(&ret)[0]=static_cast<const char*>(le32)[0];
151  reinterpret_cast<char*>(&ret)[1]=static_cast<const char*>(le32)[1];
152  reinterpret_cast<char*>(&ret)[2]=static_cast<const char*>(le32)[2];
153  reinterpret_cast<char*>(&ret)[3]=static_cast<const char*>(le32)[3];
154  return ret;
155 }
156 
158 inline uint16_t letoh16(const void*const le16)
159 {
160  uint16_t ret;
161  reinterpret_cast<char*>(&ret)[0]=static_cast<const char*>(le16)[0];
162  reinterpret_cast<char*>(&ret)[1]=static_cast<const char*>(le16)[1];
163  return ret;
164 }
165 
166 #else // SHORE_MEMOPS_IS_BIG_ENDIAN
167 
169 inline uint64_t ntoh64(const void*const netw64)
170 {
171  uint64_t ret;
172  reinterpret_cast<char*>(&ret)[0]=static_cast<const char*>(netw64)[0];
173  reinterpret_cast<char*>(&ret)[1]=static_cast<const char*>(netw64)[1];
174  reinterpret_cast<char*>(&ret)[2]=static_cast<const char*>(netw64)[2];
175  reinterpret_cast<char*>(&ret)[3]=static_cast<const char*>(netw64)[3];
176  reinterpret_cast<char*>(&ret)[4]=static_cast<const char*>(netw64)[4];
177  reinterpret_cast<char*>(&ret)[5]=static_cast<const char*>(netw64)[5];
178  reinterpret_cast<char*>(&ret)[6]=static_cast<const char*>(netw64)[6];
179  reinterpret_cast<char*>(&ret)[7]=static_cast<const char*>(netw64)[7];
180  return ret;
181 }
182 
184 inline uint32_t ntoh32(const void*const netw32)
185 {
186  uint32_t ret;
187  reinterpret_cast<char*>(&ret)[0]=static_cast<const char*>(netw32)[0];
188  reinterpret_cast<char*>(&ret)[1]=static_cast<const char*>(netw32)[1];
189  reinterpret_cast<char*>(&ret)[2]=static_cast<const char*>(netw32)[2];
190  reinterpret_cast<char*>(&ret)[3]=static_cast<const char*>(netw32)[3];
191  return ret;
192 }
193 
195 inline uint16_t ntoh16(const void*const netw16)
196 {
197  uint16_t ret;
198  reinterpret_cast<char*>(&ret)[0]=static_cast<const char*>(netw16)[0];
199  reinterpret_cast<char*>(&ret)[1]=static_cast<const char*>(netw16)[1];
200  return ret;
201 }
202 
204 inline uint64_t letoh64(const void*const netw64)
205 {
206  uint64_t ret;
207  reinterpret_cast<char*>(&ret)[0]=static_cast<const char*>(netw64)[7];
208  reinterpret_cast<char*>(&ret)[1]=static_cast<const char*>(netw64)[6];
209  reinterpret_cast<char*>(&ret)[2]=static_cast<const char*>(netw64)[5];
210  reinterpret_cast<char*>(&ret)[3]=static_cast<const char*>(netw64)[4];
211  reinterpret_cast<char*>(&ret)[4]=static_cast<const char*>(netw64)[3];
212  reinterpret_cast<char*>(&ret)[5]=static_cast<const char*>(netw64)[2];
213  reinterpret_cast<char*>(&ret)[6]=static_cast<const char*>(netw64)[1];
214  reinterpret_cast<char*>(&ret)[7]=static_cast<const char*>(netw64)[0];
215  return ret;
216 }
217 
219 inline uint32_t letoh32(const void*const le32)
220 {
221  uint32_t ret;
222  reinterpret_cast<char*>(&ret)[0]=static_cast<const char*>(le32)[3];
223  reinterpret_cast<char*>(&ret)[1]=static_cast<const char*>(le32)[2];
224  reinterpret_cast<char*>(&ret)[2]=static_cast<const char*>(le32)[1];
225  reinterpret_cast<char*>(&ret)[3]=static_cast<const char*>(le32)[0];
226  return ret;
227 }
228 
230 inline uint16_t letoh16(const void*const le16)
231 {
232  uint16_t ret;
233  reinterpret_cast<char*>(&ret)[0]=static_cast<const char*>(le16)[1];
234  reinterpret_cast<char*>(&ret)[1]=static_cast<const char*>(le16)[0];
235  return ret;
236 }
237 
238 #endif // SHORE_MEMOPS_IS_BIG_ENDIAN
239 
241 inline uint64_t hton64(const void*const host64)
242 {
243  return ntoh64(host64);
244 }
245 
247 inline uint32_t hton32(const void*const host32)
248 {
249  return ntoh32(host32);
250 }
251 
253 inline uint16_t hton16(const void*const host16)
254 {
255  return ntoh16(host16);
256 }
257 
260 {
261  private:
262 
263  struct ptrbase
264  {
265  virtual ~ptrbase() {}
266  };
267 
268  template<class T>
269  struct ptrwrap
270  :public ptrbase
271  {
272  T* data;
273 
274  ptrwrap(T* d): data(d) {}
275  virtual ~ptrwrap()
276  {
277  delete data;
278  }
279  };
280 
281  std::vector<ptrbase*> m_pointers;
282 
283  public:
284 
285  ptrkeeper();
286 
287  template<typename Iterator>
288  ptrkeeper(Iterator b,Iterator e)
289  {
290  while(b!=e)
291  {
292  push_back(*b);
293  ++b;
294  }
295  }
296 
297  ~ptrkeeper();
298 
299  template<typename T>
300  T &push_back(T*const ptr)
301  {
302  m_pointers.push_back(new ptrwrap<T>(ptr));
303  return *ptr;
304  }
305 
306  template<typename T>
307  T &operator()(T*const ptr)
308  {
309  return push_back(ptr);
310  }
311 };
312 
316 class mmapping
317 {
318  private:
319 
320  std::string m_filename;
321  int m_fd;
322 
323  std::streamsize m_filesize;
324 
325  std::streamoff m_offset;
326  std::streamsize m_size;
327 
329  std::streamoff m_pa_offset;
331  std::streamsize m_pa_size;
333  std::streamoff m_pa_diff;
334 
335  void *m_raw_mem;
336  const char *m_begin;
337  const char *m_end;
338 
339 
340  public:
341 
344  mmapping(const std::string &fn=std::string());
345 
350  mmapping(const mmapping &other);
352  ~mmapping();
353 
355  mmapping &operator=(const mmapping &other);
356 
359  void open_file();
361  void open_file(const std::string &fn);
363  void close_file();
364 
365  bool has_file() const;
367  std::streamsize get_filesize() const;
369  const std::string &get_filename() const;
370 
371  bool is_file_open() const;
372 
374  void map(const std::streamoff ofs,const std::streamsize size=0);
375 
377  void map();
378 
380  void unmap();
381 
383  bool is_mapped() const;
384 
389  const char *begin() const;
390 
395  const char *end() const;
396 };
397 
398 struct md5_state;
399 
401 class md5_sum
402 {
403  private:
404 
405  md5_state *m_state;
406  unsigned char *m_sig;
407  std::string m_value;
408 
409  public:
410 
411  md5_sum();
412  ~md5_sum();
413 
415  void process(const char *const data,const size_t n);
417  void finish();
419  const std::string &value() const;
420 
422  static std::string digest(const std::string &str);
423 };
424 
425 } // namespace
426 
427 #endif // SHORE_MISC_MEMOPS_HPP__
428