1/*! \brief This class read a Grid raw data format
2 *
3 * A grid row data format is very simple. The first n numbers indicate the
4 * size in every dimension of the grid. The other is the data contained by the grid.
5 * In particular if we are in 3D and we are saving a 45x50x30 grid after the 3 numbers
6 * I am expecting 45x50x30 = 67500 objects of type T. There is no check the dimensionality
7 * is correct, neither the type is correct
8 *
9 * \tparam dim dimensionality of the grid
10 * \tparam T type of the grid
11 *
12 */
13#include <iostream>
14#include <Grid/map_grid.hpp>
15#include <fstream>
16
17#define FORTRAN_STYLE 1
18#define STRUCT_OF_ARRAY 2
19
20/*! \brief This is the scalar case
21 *
22 * \tparam T scalar type
23 *
24 */
25template<unsigned int dim, typename Tg, typename Tr, unsigned int i>
26struct meta_raw_read
27{
28 static inline void read(grid_cpu<dim,Tg> & gr,std::ifstream & raw)
29 {
30 auto it = gr.getIterator();
31
32 while (it.isNext())
33 {
34 auto key = it.get();
35
36 raw.read((char *)&gr.template get<i>(key),sizeof(Tr));
37
38 ++it;
39 }
40 }
41};
42
43/*! \brief This is the vector case
44 *
45 * \tparam T vector type
46 *
47 */
48template<unsigned int dim, typename Tg, typename Tr ,unsigned int i, unsigned int nv>
49struct meta_raw_read<dim,Tg,Tr[nv],i>
50{
51 static inline void read(grid_cpu<dim,Tg> & gr,std::ifstream & raw)
52 {
53 for (size_t k = 0 ; k < nv ; k++)
54 {
55 auto it = gr.getIterator();
56
57 while (it.isNext())
58 {
59 auto key = it.get();
60
61 raw.read((char *)&gr.template get<i>(key)[k],sizeof(Tr));
62
63 ++it;
64 }
65 }
66 }
67};
68
69/*! \brief this class is a functor for "for_each" algorithm
70 *
71 * This class is a functor for "for_each" algorithm. For each
72 * element of the boost::vector the operator() is called.
73 * Is mainly used to read each property
74 *
75 * \tparam ele_g element that store the grid and its attributes
76 * \param St type of space where the grid live
77 *
78 */
79template<unsigned int dim, typename Tg>
80struct raw_read
81{
82 //! Grid out
83 grid_cpu<dim,Tg> & gr;
84
85 //! File stream
86 std::ifstream & fl;
87
88 /*! \brief constructor
89 *
90 * \param gr grid to fill
91 * \param fl file from where to read
92 *
93 */
94 raw_read(grid_cpu<dim,Tg> & gr,std::ifstream & fl)
95 :gr(gr),fl(fl)
96 {};
97
98 //! It read for each property
99 template<typename T>
100 void operator()(T& t) const
101 {
102 typedef typename boost::mpl::at<typename Tg::type,boost::mpl::int_<T::value>>::type Tr;
103
104 meta_raw_read<dim,Tg,Tr,T::value>::read(gr,fl);
105 }
106};
107
108template <unsigned int dim, typename T, typename idx_type>
109class GridRawReader
110{
111public:
112
113 //! Constructor
114 GridRawReader() {};
115
116
117 /*! \brief Read a raw grid
118 *
119 * \param file raw file to read
120 * \param gr grid to fill
121 * \param opt option (FORTRAN_STYLE)
122 * \param skip skip N byte
123 *
124 */
125 bool read(std::string file, grid_cpu<dim,T> & gr, size_t opt = 0, size_t skip = 0)
126 {
127 idx_type tmp;
128 std::ifstream raw;
129 raw.open (file, std::ios::binary );
130
131 if (raw.is_open() == false)
132 {
133 std::cerr << __FILE__ << ":" << __LINE__ << " error in opening the file: " << file << std::endl;
134 return false;
135 }
136
137 // get length of file:
138 raw.seekg (0, std::ios::end);
139 size_t length = raw.tellg();
140 raw.seekg (skip, std::ios::beg);
141
142 if (opt & FORTRAN_STYLE)
143 raw.read((char *)&tmp,sizeof(idx_type));
144
145 size_t sz[dim];
146
147 for (size_t i = 0 ; i < dim ; i++)
148 {
149 sz[i] = 0;
150 raw.read((char *)&sz[i],sizeof(idx_type));
151 }
152
153 if (opt & FORTRAN_STYLE)
154 raw.read((char *)&tmp,sizeof(idx_type));
155
156 if (opt & FORTRAN_STYLE)
157 raw.read((char *)&tmp,sizeof(idx_type));
158
159 grid_sm<dim,void> gs(sz);
160
161 size_t offset = 0;
162 if (opt & FORTRAN_STYLE)
163 offset += 2*sizeof(idx_type)*2;
164
165 // Check the the file size make sense
166 if (length - dim*sizeof(idx_type) - offset - skip != gs.size()*sizeof(T) )
167 {
168 std::cout << __FILE__ << ":" << __LINE__ << " Error the size of the raw file does not match with the calculated one" << std::endl;
169 return false;
170 }
171
172 gr.setMemory();
173
174 // resize the grid
175 gr.resize(sz);
176
177 if (!(opt & STRUCT_OF_ARRAY))
178 {
179 // read the data
180 raw.read((char *)gr.getPointer(),gr.size()*sizeof(T));
181 raw.close();
182 }
183 else
184 {
185 // for each property
186 raw_read<dim,T> rr(gr,raw);
187
188 boost::mpl::for_each< boost::mpl::range_c<int,0, T::max_prop> >(rr);
189 }
190
191 return true;
192 }
193};
194