LevelS C++ support library  3.82
bstream.h
Go to the documentation of this file.
1 /*
2  * This file is part of libcxxsupport.
3  *
4  * libcxxsupport is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * libcxxsupport is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with libcxxsupport; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17  */
18 
19 /*
20  * libcxxsupport is being developed at the Max-Planck-Institut fuer Astrophysik
21  * and financially supported by the Deutsches Zentrum fuer Luft- und Raumfahrt
22  * (DLR).
23  */
24 
25 /*! \file bstream.h
26  * Classes for binary I/O with streams
27  *
28  * Copyright (C) 2010 Max-Planck-Society
29  * \author Martin Reinecke
30  */
31 
32 #ifndef PLANCK_BSTREAM_H
33 #define PLANCK_BSTREAM_H
34 
35 #include <iostream>
36 #include <fstream>
37 #include <algorithm>
38 #include "datatypes.h"
39 
40 /*! An object of this class can be cast to a \a bool, which indicates whether
41  the computer architecture is big-endian (true) or little-endian (false). */
43  {
44  private:
45  bool big_end;
46 
47  public:
48  EndianTest__()
49  {
50  union { uint16 i16; uint8 i8; } tmp;
51  tmp.i16 = 1;
52  big_end = (tmp.i8==0);
53  }
54  operator bool() const { return big_end; }
55  };
56 
57 const EndianTest__ big_endian;
58 
59 template<size_t size> inline void byteswap_helper__ (char *);
60 template<> inline void byteswap_helper__<1> (char *)
61  {}
62 template<> inline void byteswap_helper__<2> (char *val)
63  {
64  using namespace std;
65  swap (val[0],val[1]);
66  }
67 template<> inline void byteswap_helper__<4> (char *val)
68  {
69  using namespace std;
70  swap (val[0],val[3]); swap (val[1],val[2]);
71  }
72 template<> inline void byteswap_helper__<8> (char *val)
73  {
74  using namespace std;
75  swap (val[0],val[7]); swap (val[1],val[6]);
76  swap (val[2],val[5]); swap (val[3],val[4]);
77  }
78 
79 /*! Performs an endianness conversion on \a val.
80  \note \a T must be a primitive data type! */
81 template<typename T> inline void byteswap (T &val)
82  { byteswap_helper__<sizeof(T)> (reinterpret_cast<char *> (&val)); }
83 
84 const bool file_is_lsb=big_endian, file_is_msb=!big_endian,
85  file_is_natural=false;
86 
87 /*! Class for writing binary data to a stream. */
88 class bostream
89  {
90  private:
91  std::ostream &s;
92  bool doswap;
93 
94  public:
95  /*! Creates a new object which is attached to \a s_ and performs
96  endianness conversion if \a doswap_==true. */
97  bostream (std::ostream &s_, bool doswap_=false)
98  : s(s_), doswap(doswap_) {}
99 
100  /*! Writes a binary representation of \a num objects of type \a T
101  (stored in \a data) to the attached stream. Endianness conversion
102  is performed if requested in the constructor.
103  \note \a T must be a primitive data type! */
104  template<typename T> bostream &put (const T *data, size_t num)
105  {
106  if ((sizeof(T)>1) && doswap)
107  for (size_t m=0; m<num; ++m)
108  {
109  T tmp=data[m];
110  byteswap (tmp);
111  s.write (reinterpret_cast<const char *> (&tmp), sizeof(T));
112  }
113  else
114  s.write (reinterpret_cast<const char *> (data), num*sizeof(T));
115  return *this;
116  }
117  /*! Writes a binary representation of \a data to the attached stream.
118  Endianness conversion is performed if requested in the constructor.
119  \note \a T must be a primitive data type! */
120  template<typename T> bostream &operator<< (const T &data)
121  {
122  put(&data,1);
123  return *this;
124  }
125 
126  bool getSwap() const
127  { return doswap; }
128  void setSwap(bool newswap)
129  { doswap=newswap; }
130  void flipSwap()
131  { doswap=!doswap; }
132  };
133 
134 /*! Class for reading binary data from a stream. */
135 class bistream
136  {
137  private:
138  std::istream &s;
139  bool doswap;
140 
141  public:
142  /*! Creates a new object which is attached to \a s_ and performs
143  endianness conversion if \a doswap_==true. */
144  bistream (std::istream &s_, bool doswap_=false)
145  : s(s_), doswap(doswap_) {}
146 
147  /*! Reads a binary representation of \a num objects of type \a T
148  from the attached stream and stores them in \a data. Endianness
149  conversion is performed if requested in the constructor.
150  \note \a T must be a primitive data type! */
151  template<typename T> bistream &get (T *data, size_t num)
152  {
153  s.read (reinterpret_cast<char *> (data), num*sizeof(T));
154  if ((sizeof(T)>1) && doswap)
155  for (size_t m=0; m<num; ++m)
156  byteswap (data[m]);
157  return *this;
158  }
159  /*! Reads a binary representation of \a data from the attached stream.
160  Endianness conversion is performed if requested in the constructor.
161  \note \a T must be a primitive data type! */
162  template<typename T> bistream &operator>> (T &data)
163  {
164  get (&data,1);
165  return *this;
166  }
167 
168  bool getSwap() const
169  { return doswap; }
170  void setSwap(bool newswap)
171  { doswap=newswap; }
172  void flipSwap()
173  { doswap=!doswap; }
174  };
175 
176 class bofstream: public std::ofstream
177  {
178  private:
179  bool doswap;
180 
181  public:
182  /*! */
183  bofstream (const char *fname, bool doswap_)
184  : std::ofstream(fname,std::ios::binary), doswap(doswap_) {}
185 
186  template<typename T> bofstream &operator<< (const T &data)
187  {
188  if (doswap)
189  {
190  T tmp = data;
191  byteswap (tmp);
192  write (reinterpret_cast<const char *> (&tmp), sizeof(T));
193  }
194  else
195  write (reinterpret_cast<const char *> (&data), sizeof(T));
196  return *this;
197  }
198  template<typename T> bofstream &put (const T *data, size_t num)
199  {
200  if (doswap)
201  for (size_t m=0; m<num; ++m)
202  {
203  T tmp=data[m];
204  byteswap (tmp);
205  write (reinterpret_cast<const char *> (&tmp), sizeof(T));
206  }
207  else
208  write (reinterpret_cast<const char *> (data), num*sizeof(T));
209  return *this;
210  }
211 
212  bool getSwap() const
213  { return doswap; }
214  void setSwap(bool newswap)
215  { doswap=newswap; }
216  void flipSwap()
217  { doswap=!doswap; }
218  };
219 
220 class bifstream: public std::ifstream
221  {
222  private:
223  bool doswap;
224 
225  public:
226  /*! */
227  bifstream ()
228  : doswap(false) {}
229  bifstream (const char *fname, bool doswap_)
230  : std::ifstream(fname,std::ios::binary), doswap(doswap_) {}
231 
232  void open (const char *fname, bool doswap_)
233  {
234  doswap=doswap_;
235  std::ifstream::open(fname,std::ios::binary);
236  }
237 
238  template<typename T> bifstream &operator>> (T &data)
239  {
240  read (reinterpret_cast<char *> (&data), sizeof(T));
241  if (doswap) byteswap (data);
242  return *this;
243  }
244  template<typename T> bifstream &get (T *data, size_t num)
245  {
246  read (reinterpret_cast<char *> (data), num*sizeof(T));
247  if (doswap)
248  for (size_t m=0; m<num; ++m)
249  byteswap (data[m]);
250  return *this;
251  }
252 
253  void rewind()
254  { seekg(0,std::ios::beg); }
255  void skip(std::streamoff nbytes)
256  { seekg(nbytes,std::ios::cur); }
257 
258  bool getSwap() const
259  { return doswap; }
260  void setSwap(bool newswap)
261  { doswap=newswap; }
262  void flipSwap()
263  { doswap=!doswap; }
264  };
265 
266 #endif
bistream(std::istream &s_, bool doswap_=false)
Definition: bstream.h:144
bostream(std::ostream &s_, bool doswap_=false)
Definition: bstream.h:97
void byteswap(T &val)
Definition: bstream.h:81
bostream & operator<<(const T &data)
Definition: bstream.h:120
bistream & operator>>(T &data)
Definition: bstream.h:162
bostream & put(const T *data, size_t num)
Definition: bstream.h:104

Generated on Thu Jul 28 2022 17:32:05 for LevelS C++ support library