DATRW++ library: seismic data I/O with multiple formats
bytesex.h
Go to the documentation of this file.
1 /*! \file bytesex.h
2  * \brief A copy of bytesex.h from libtfxx (prototypes)
3  *
4  * ----------------------------------------------------------------------------
5  *
6  * \author Thomas Forbriger
7  * \date 29/06/2007
8  *
9  * A copy of bytesex.h from libtfxx (prototypes)
10  *
11  * just to make libdatrw a bit more independent
12  *
13  * ----
14  * This program is free software; you can redistribute it and/or modify
15  * it under the terms of the GNU General Public License as published by
16  * the Free Software Foundation; either version 2 of the License, or
17  * (at your option) any later version.
18  *
19  * This program is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22  * GNU General Public License for more details.
23  *
24  * You should have received a copy of the GNU General Public License
25  * along with this program; if not, write to the Free Software
26  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
27  * ----
28  *
29  * Copyright (c) 2007 by Thomas Forbriger (BFO Schiltach)
30  *
31  * REVISIONS and CHANGES
32  * - 29/06/2007 V1.0 Thomas Forbriger
33  * - 30/04/2010 V1.1 added magic number writing and reading
34  *
35  * ============================================================================
36  */
37 
38 // include guard
39 #ifndef DATRW_BYTESEX_H_VERSION
40 
41 #define DATRW_BYTESEX_H_VERSION \
42  "DATRW_BYTESEX_H V1.1"
43 
44 // we include fstream, because all function are closely related to file I/O
45 // and file_magic definitely requires fstream
46 #include<fstream>
47 
48 namespace datrw {
49 
50  namespace util {
51 
52  /*! \defgroup group_bytesex I/O byte swapping facility.
53  * \brief Provides function to check bytesex and swap input bytes.
54  *
55  * When working in a multi-CPU-model environment, data written on one host
56  * (with Intel CPU e.g.) can not easily be read on a different host (with
57  * Motorola CPU e.g.) when using binary data. In this group we provide
58  * facilities to check bytesex of datafiles and perform byte-swapping if
59  * necessary.
60  *
61  * \ref anchor_fortranio_firsttest "Tests on this module" were performed
62  * within tests of the \ref group_fortranio.
63  *
64  * \sa example_fortraniotest
65  * \sa group_fortranio
66  * \sa bytesex_h
67  *
68  * The components are collected in namespace datrw::util.
69  * @{
70  */
71 
72  //----------------------------------------------------------------------
73  //
74  // we start with a set of useful types and enums
75 
76  /*! A union to support raw I/O.
77  *
78  * \arg \c value the numerical value
79  * \arg \c bytes the raw byte representation
80  */
81  template<typename T>
82  union IOUnion {
83  T value;
84  char bytes[sizeof(T)];
85  };
86 
87  //! Define different CPU type that are recognized
88  enum Ecpu_type {
89  //! Intel CPU
90  cpu_Intel = 1,
91  //! Motorola CPU
93  //! unknown CPU
95  };
96 
97  //! Define bytesex indicator for magic number test
98  enum Emagic_type {
99  //! The bytesex of the file matches this machine
101  //! The bytesex of the file must be swapped to match this machine
103  //! The magic number does match the file
105  };
106 
107  /*!
108  * @} end of group_bytesex
109  */
110 
111  //----------------------------------------------------------------------
112  //
113  // some function templates
114 
115  /*! \brief How to swap any generic type
116  */
117  template<class T>
118  T swap(const T& value)
119  {
120  IOUnion<T> in, out;
121  in.value=value;
122  out=swap(in);
123  return(out.value);
124  }
125 
126  /*! \brief Specialization in case we use use an IOUnion.
127  * i.e. overloading the function
128  */
129  template<class T>
130  IOUnion<T> swap(const IOUnion<T>& value)
131  {
132  IOUnion<T> result;
133  for (unsigned int i=0; i<sizeof(T); i++)
134  { result.bytes[i]=value.bytes[sizeof(T)-i-1]; }
135  return(result);
136  }
137 
138  //----------------------------------------------------------------------
139  //
140  // some binary function
141 
142  /*! \brief Create a magic number from a character string.
143  * \ingroup group_ioswap, bytesex_h
144  *
145  * If \f$x_{i}=(\vec{x})_{i}\f$ represents the input character sequence \c
146  * cmagic and \f$N=4\f$ is the value of \c sizeof(int), then the return
147  * value will be
148  * \f[
149  * \textrm{magic}(\vec{x})
150  * =\sum\limits_{i=0}^{N-1} x_{i}\; 2^{8\; (N-1-i)}
151  * =x_{3}+256\; (x_{2}+256\; (x_{1}+256\; x_{0})).
152  * \f]
153  *
154  * \param cmagic 4-byte character sequence representing magic number (most
155  * restrictive: pass a const pointer to a const char)
156  * is pointer to character array of size sizeof(int)
157  * \return The magic number representing the 4-byte character sequence on
158  * your system
159  */
160  int magic(const char* const cmagic);
161 
162  /*! \brief Check CPU model.
163  * \ingroup group_ioswap, bytesex_h
164  * \return return value indicates the CPU model found
165  */
166  Ecpu_type cpu();
167 
168  /*! \brief Check for magic number in file.
169  *
170  * \ingroup group_ioswap, bytesex_h
171  *
172  * \param is input stream to read from
173  * \param cmagic 4-byte character sequence representing magic number (most
174  * restrictive: pass a const pointer to a const char)
175  * is pointer to character array of size sizeof(int)
176  * \param fortranmode use Fortran binary I/O if true
177  * \return The return value tells whether the file matches
178  *
179  * The function may have the following return values
180  * \arg magic_match The file has the requested magic number and the bytesex of
181  * the data matches that of the system
182  * \arg magic_swap The file has the requested magic number but byte swapping
183  * is required for input data
184  * \arg magic_nomatch The requested magic number was not found in the file
185  */
186  Emagic_type file_magic_test(std::istream& is, const char* const cmagic,
187  const bool& fortranmode=false);
188 
189  /*! \brief Write magic number to file.
190  * \ingroup group_ioswap, bytesex_h
191  *
192  * \param os output stream to write to
193  * \param cmagic 4-byte character sequence representing magic number (most
194  * restrictive: pass a const pointer to a const char)
195  * is pointer to character array of size sizeof(int)
196  * \param fortranmode use Fortran binary I/O if true
197  */
198  void file_magic_write(std::ostream& os, const char* const cmagic,
199  const bool& fortranmode=false);
200 
201  } // namespace util
202 
203 } // namespace datrw
204 
205 #endif // DATRW_BYTESEX_H_VERSION (includeguard)
206 
207 /* ----- END OF bytesex.h ----- */
The bytesex of the file matches this machine.
Definition: bytesex.h:100
Ecpu_type cpu()
check for my CPU model
Definition: bytesex.cc:73
Emagic_type file_magic_test(std::istream &is, const char *const cmagic, const bool &fortranmode)
check magic number in file
Definition: bytesex.cc:105
Ecpu_type
Define different CPU type that are recognized.
Definition: bytesex.h:88
The magic number does match the file.
Definition: bytesex.h:104
T swap(const T &value)
How to swap any generic type.
Definition: bytesex.h:118
unknown CPU
Definition: bytesex.h:94
Root namespace of library.
Definition: aalibdatrwxx.cc:16
Motorola CPU.
Definition: bytesex.h:92
The bytesex of the file must be swapped to match this machine.
Definition: bytesex.h:102
char bytes[sizeof(T)]
Definition: bytesex.h:84
int magic(const char *const cmagic)
function to create the magic number
Definition: bytesex.cc:52
Emagic_type
Define bytesex indicator for magic number test.
Definition: bytesex.h:98
void file_magic_write(std::ostream &os, const char *const cmagic, const bool &fortranmode)
write magic number to file
Definition: bytesex.cc:128
Intel CPU.
Definition: bytesex.h:90